devspace icon indicating copy to clipboard operation
devspace copied to clipboard

Image build process support for an image dependent on another

Open markphillips100 opened this issue 2 years ago • 23 comments

Is your feature request related to a problem? I have an aspnet core solution with many projects. Each project is built into its own docker image. I created a solution-wide dockerfile to replace the individual project dockerfiles as they all do the same thing; copy source, restore deps, build, test, and then publish. Args allow me to define what project is to be published for the required image.

What I'd like to do is build a base image for the solution that all the project specific images are based from. The base would do all the restore of dependencies, build code, and run tests. The project dockerfile would just publish and do the entrypoint stuff, and it would be based on the base image using an ARG for the tag to use (likely a "latest" based tag as the base may not have changed I suppose).

This requires a level of build dependency control so that the base can be built first before all other images are built in parallel. So is there a way to inform the image build process to build specific images before others?

Which solution do you suggest? I don't have one.

Which alternative solutions exist? None that I know of.

Additional context

/kind feature

markphillips100 avatar Feb 18 '22 06:02 markphillips100

@markphillips100 thanks for creating this issue! You could have this base image as a dependency of your project which are always built before the actual images, please take a look at https://devspace.sh/cli/docs/configuration/dependencies/basics

FabianKramm avatar Feb 18 '22 13:02 FabianKramm

Thank you @FabianKramm . I will take a look and report back.

markphillips100 avatar Feb 18 '22 13:02 markphillips100

Dependencies would definitely work if we would be able to get the tag from the dependency and, for example, pass it as a build arg to the docker build like:

dependencies:
- name: ubuntu
  source:
    path: ./tools/ubuntu

images:
  app:
    image: app
    build:
      docker:
        options:
          buildArgs:
            BASE: ${runtime.dependencies.ubuntu.images.ubuntu.image}:${runtime.dependencies.ubuntu.images.ubuntu.tag}

Currently the runtime variables don't work for this section, so the base image tag needs to static like latest or be something that's consistent like git sha.

mvgijssel avatar Mar 02 '22 08:03 mvgijssel

@mvgijssel thats true, this will be working in devspace v6 where you can actually define a pipeline and build images dependant on each other. We'll release an alpha version of this very soon!

FabianKramm avatar Mar 04 '22 08:03 FabianKramm

Sorry @FabianKramm I haven't had much chance to follow up yet. The pipeline you speak of sounds like it would do the trick well.

markphillips100 avatar Mar 04 '22 09:03 markphillips100

@markphillips100 no worries, with v6 we introduce pipelines where you can essentially override the default devspace behaviour with:

pipelines:
  dev:
    steps:
      - run: |-
          build_images base_image
          build_images app --set build.docker.options.buildArgs.BASE=${runtime.images.base_image}
          ...

FabianKramm avatar Mar 04 '22 09:03 FabianKramm

oh very cool.

markphillips100 avatar Mar 04 '22 09:03 markphillips100

Yeah that looks very promising!

mvgijssel avatar Mar 05 '22 07:03 mvgijssel

Any idea when v6 will drop @FabianKramm ? No pressure, just curious.

markphillips100 avatar Mar 09 '22 08:03 markphillips100

@markphillips100 I guess we'll release an alpha version early next week

FabianKramm avatar Mar 09 '22 11:03 FabianKramm

@FabianKramm I thought I'd give the current alpha (v6.0.0-alpha.2) a go for the pipeline functionality but hit an issue.

I ran devspace upgrade --version v6.0.0-alpha.2 to upgrade which seemed fine. Didn't notice any change to my current devspace.yaml - not sure if the config version should have changed from v1beta11 to v2beta1?

Anyway, I could devspace list vars no problem but I assume to use the new pipeline feature I'd have to change to v2beta1 as per the release docs so did that but get the following error (with --debug enabled):

12:46:12 fatal error loading config: yaml: unmarshal errors:
  line 3: cannot unmarshal !!seq into map[string]*latest.Variable
github.com/loft-sh/devspace/pkg/devspace/config/versions.Parse
        /Users/runner/work/devspace/devspace/pkg/devspace/config/versions/versions.go:146
github.com/loft-sh/devspace/pkg/devspace/config/versions.ParseVariables
        /Users/runner/work/devspace/devspace/pkg/devspace/config/versions/versions.go:114
github.com/loft-sh/devspace/pkg/devspace/config/loader.reloadVariables
        /Users/runner/work/devspace/devspace/pkg/devspace/config/loader/loader.go:358
github.com/loft-sh/devspace/pkg/devspace/config/loader.ResolveImports
        /Users/runner/work/devspace/devspace/pkg/devspace/config/loader/imports.go:31
github.com/loft-sh/devspace/pkg/devspace/config/loader.(*configLoader).parseConfig
        /Users/runner/work/devspace/devspace/pkg/devspace/config/loader/loader.go:306
github.com/loft-sh/devspace/pkg/devspace/config/loader.(*configLoader).LoadWithParser
        /Users/runner/work/devspace/devspace/pkg/devspace/config/loader/loader.go:170
github.com/loft-sh/devspace/pkg/devspace/config/loader.(*configLoader).LoadWithCache
        /Users/runner/work/devspace/devspace/pkg/devspace/config/loader/loader.go:104
github.com/loft-sh/devspace/pkg/devspace/config/loader.(*configLoader).Load
        /Users/runner/work/devspace/devspace/pkg/devspace/config/loader/loader.go:99
github.com/loft-sh/devspace/cmd/list.(*varsCmd).RunListVars
        /Users/runner/work/devspace/devspace/cmd/list/vars.go:63
github.com/loft-sh/devspace/cmd/list.newVarsCmd.func1
        /Users/runner/work/devspace/devspace/cmd/list/vars.go:39
github.com/spf13/cobra.(*Command).execute
        /Users/runner/work/devspace/devspace/vendor/github.com/spf13/cobra/command.go:856
github.com/spf13/cobra.(*Command).ExecuteC
        /Users/runner/work/devspace/devspace/vendor/github.com/spf13/cobra/command.go:974
github.com/spf13/cobra.(*Command).Execute
        /Users/runner/work/devspace/devspace/vendor/github.com/spf13/cobra/command.go:902
github.com/loft-sh/devspace/cmd.Execute
        /Users/runner/work/devspace/devspace/cmd/root.go:134
main.main
        /Users/runner/work/devspace/devspace/main.go:20
runtime.main
        /Users/runner/hostedtoolcache/go/1.17.8/x64/src/runtime/proc.go:255
runtime.goexit
        /Users/runner/hostedtoolcache/go/1.17.8/x64/src/runtime/asm_amd64.s:1581
parse variables
github.com/loft-sh/devspace/pkg/devspace/config/versions.ParseVariables
        /Users/runner/work/devspace/devspace/pkg/devspace/config/versions/versions.go:116
github.com/loft-sh/devspace/pkg/devspace/config/loader.reloadVariables
        /Users/runner/work/devspace/devspace/pkg/devspace/config/loader/loader.go:358
github.com/loft-sh/devspace/pkg/devspace/config/loader.ResolveImports
        /Users/runner/work/devspace/devspace/pkg/devspace/config/loader/imports.go:31
github.com/loft-sh/devspace/pkg/devspace/config/loader.(*configLoader).parseConfig
        /Users/runner/work/devspace/devspace/pkg/devspace/config/loader/loader.go:306
github.com/loft-sh/devspace/pkg/devspace/config/loader.(*configLoader).LoadWithParser
        /Users/runner/work/devspace/devspace/pkg/devspace/config/loader/loader.go:170
github.com/loft-sh/devspace/pkg/devspace/config/loader.(*configLoader).LoadWithCache
        /Users/runner/work/devspace/devspace/pkg/devspace/config/loader/loader.go:104
github.com/loft-sh/devspace/pkg/devspace/config/loader.(*configLoader).Load
        /Users/runner/work/devspace/devspace/pkg/devspace/config/loader/loader.go:99
github.com/loft-sh/devspace/cmd/list.(*varsCmd).RunListVars
        /Users/runner/work/devspace/devspace/cmd/list/vars.go:63
github.com/loft-sh/devspace/cmd/list.newVarsCmd.func1
        /Users/runner/work/devspace/devspace/cmd/list/vars.go:39
github.com/spf13/cobra.(*Command).execute
        /Users/runner/work/devspace/devspace/vendor/github.com/spf13/cobra/command.go:856
github.com/spf13/cobra.(*Command).ExecuteC
        /Users/runner/work/devspace/devspace/vendor/github.com/spf13/cobra/command.go:974
github.com/spf13/cobra.(*Command).Execute
        /Users/runner/work/devspace/devspace/vendor/github.com/spf13/cobra/command.go:902
github.com/loft-sh/devspace/cmd.Execute
        /Users/runner/work/devspace/devspace/cmd/root.go:134
main.main
        /Users/runner/work/devspace/devspace/main.go:20
runtime.main
        /Users/runner/hostedtoolcache/go/1.17.8/x64/src/runtime/proc.go:255
runtime.goexit
        /Users/runner/hostedtoolcache/go/1.17.8/x64/src/runtime/asm_amd64.s:1581

Looking at the code for the alpha tag I see nothing related to a "v2beta1" so I'm a bit confused. Have I jumped in too early expecting pipelines to be in the alpha?

markphillips100 avatar Mar 29 '22 02:03 markphillips100

@markphillips100 yes you are correct, you'll need the newer config version v2beta1 as this allows you to use the new pipelines and other features. Pipelines and all the other functionality is already included in the alpha, however unfortunately you cannot just exchange the config version and it works as we have changed a lot of configuration options which might not be present anymore, but you have used in an older version.

How to upgrade your config: run devspace print with your v1beta11 config version to view how DevSpace converts your v1beta11 to v2beta1. Then copy the output and paste it into the devspace.yaml replacing your current configuration. Then you can add or modify the pipelines as well as start using other new functionality.

FabianKramm avatar Mar 29 '22 07:03 FabianKramm

@FabianKramm thanks. I'll give that a go soon.

markphillips100 avatar Mar 29 '22 07:03 markphillips100

@FabianKramm I'm still getting the same issue. I've also gone back to a real basic yaml to isolate as much as I can.

I tried listing vars using just this yaml and the same error occurs as before. I'm on Windows 11 running in a powershell terminal.

version: v2beta1

vars:
- name: MYVAR
  value: "hello"

When I did the devspace print the output shows my vars separate from the yaml, and only includes a vars env reference in the yaml. So it's not clear to me if there's a syntactic change or not in how I should be including vars in my yaml. Should this simple test file work okay?

Here's the error again when I devspace list vars, for clarity:

fatal parse variables: error loading config: yaml: unmarshal errors:
  line 3: cannot unmarshal !!seq into map[string]*latest.Variable

markphillips100 avatar Mar 29 '22 11:03 markphillips100

Just tried v6.0.0-alpha.4 with the following test yaml files. Test A yaml fails as before, Test B yaml works fine. The "unmarshal" error earlier made me think perhaps the var syntax is no longer accepting an array but a dictionary/map instead? Happy to change my vars if that's the case but just wanted to clarify.

Test A yaml. Unable to parse yaml (unmarshal error):

version: v2beta1

vars:
- name: MY_VAR
  value: hello

Output:

fatal parse variables: error loading config: yaml: unmarshal errors:
  line 3: cannot unmarshal an array into map[string]*latest.Variable (line 3: - name: MY_VAR)

Test B yaml. Working:

version: v2beta1

vars:
  MY_VAR:
    value: hello

Output:

 Variable              Value  
 MY_VAR                hello

markphillips100 avatar Mar 31 '22 01:03 markphillips100

So got all my config converted without errors now (using yaml map rather than arrays). Only it appears my commands that use variables in arguments are not populated if I use the args array property.

For example I tested the following two commands.

version: v2beta1

vars:
  MY_VAR:
    value: hello

commands:
  echo-var1:
    name: echo-var1
    command: echo ${MY_VAR}
  echo-var2:
    name: echo-var2
    command: bash
    args: ["echo", "${MY_VAR}"]

Command echo-var1 outputs "hello". The other command (errors but proves the issue regardless) outputs "${MY_VAR}" as a literal rather than the vars value.

@FabianKramm are you okay with me appending these issues I'm finding as I go to this issue? I appreciate it's an alpha so just want to be sure is all.

markphillips100 avatar Mar 31 '22 02:03 markphillips100

@markphillips100 thanks for the updates! Regarding the commands and args, we generally recommend to only use it like this:

version: v2beta1

vars:
  MY_VAR:
    value: hello

commands:
  echo-var1: |-
    echo ${MY_VAR}

Why do you need to use args instead of typing out the command directly?

FabianKramm avatar Mar 31 '22 11:03 FabianKramm

Why do you need to use args instead of typing out the command directly?

I raised an issue in regards to a path separator when using the non-args way and it solved the problem when using args. See issue #1878

markphillips100 avatar Mar 31 '22 11:03 markphillips100

@markphillips100 thanks for the explanation! This might be fixed as well with DevSpace v6, I tested your description and it prints the following:

PS C:\Users\Administrator\Documents> powershell -ep Bypass ./test.ps1
Env: C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Amazon\cfn-bootstrap\;C:\Program Files\Go\bin;C:\Program Files\Git\cmd;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Amazon\cfn-bootstrap\;C:\Program Files\Go\bin;C:\Program Files\Git\cmd;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\go\bin;C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\bin;C:\bin;C:\Program Files\Go\bin;;C:\Users\Administrator\AppData\Roaming\loft
PS C:\Users\Administrator\Documents> devspace run print-path
Env: C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Amazon\cfn-bootstrap\;C:\Program Files\Go\bin;C:\Program Files\Git\cmd;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Amazon\cfn-bootstrap\;C:\Program Files\Go\bin;C:\Program Files\Git\cmd;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\go\bin;C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\bin;C:\bin;C:\Program Files\Go\bin;;C:\Users\Administrator\AppData\Roaming\loft
PS C:\Users\Administrator\Documents>

with devspace.yaml:

version: v2beta1
name: test


commands:
  print-path: |-
    powershell -ep Bypass ./test.ps1

and test.ps1:

Write-Host "Env: $Env:Path"

FabianKramm avatar Apr 01 '22 13:04 FabianKramm

@FabianKramm you beat me to it! I got side-tracked on other work. That's great to see though so thanks for testing it.

I mostly use the cross platform powershell core (pwsh) so could you possibly confirm it also works with pwsh too? I'm sure it would but just to be sure.

markphillips100 avatar Apr 01 '22 13:04 markphillips100

@markphillips100 also works the same with the new pwsh for me:

PS C:\Users\Administrator\Documents> pwsh ./test.ps1
Env: C:\Program Files\PowerShell\7;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Amazon\cfn-bootstrap\;C:\Program Files\Go\bin;C:\Program Files\Git\cmd;C:\Program Files\PowerShell\7\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Amazon\cfn-bootstrap\;C:\Program Files\Go\bin;C:\Program Files\Git\cmd;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\go\bin;C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\bin;C:\bin;C:\Program Files\Go\bin;;C:\Users\Administrator\AppData\Roaming\loft
PS C:\Users\Administrator\Documents> devspace run print-path
Env: C:\Program Files\PowerShell\7;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Amazon\cfn-bootstrap\;C:\Program Files\Go\bin;C:\Program Files\Git\cmd;C:\Program Files\PowerShell\7\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\Amazon\cfn-bootstrap\;C:\Program Files\Go\bin;C:\Program Files\Git\cmd;C:\Users\Administrator\AppData\Local\Microsoft\WindowsApps;C:\Users\Administrator\go\bin;C:\Users\Administrator\AppData\Local\Programs\Microsoft VS Code\bin;C:\bin;C:\Program Files\Go\bin;;C:\Users\Administrator\AppData\Roaming\loft

with devspace.yaml:

version: v2beta1
name: test
commands:
  print-path: |-
    pwsh ./test.ps1

and test.ps1:

Write-Host "Env: $Env:Path"

FabianKramm avatar Apr 01 '22 13:04 FabianKramm

Fantastic. Thanks @FabianKramm .

markphillips100 avatar Apr 01 '22 13:04 markphillips100

@FabianKramm I have base image and dependent images building via pipelines working well. Commands working using the preferred syntax too. I'm using alpha 7 fyi.

Thanks for your help. Happy for you to close this issue if you wish. Look forward to a v6 release :-)

markphillips100 avatar Apr 03 '22 03:04 markphillips100