devbox icon indicating copy to clipboard operation
devbox copied to clipboard

[Feature]: Ability to exclude dev packages from production Docker image

Open apgrucza opened this issue 2 years ago • 1 comments

Is your feature request related to a problem you're trying to solve? Please describe. The Devbox documentation says you can generate a production Docker image with the exact same tools you used for development. But a Devbox environment typically contains tools that you would not want to be present in production, e.g. Git, Make, Terraform. (Especially when using pure mode, which forces more of these types of tools to be specified in the Devbox environment.)

Describe the solution you'd like I would like Devbox to be able to generate a "production" Dockerfile that excludes certain packages. This could be achieved by having a dev_packages attribute in devbox.json, in much the same way as package.json files have dependencies and devDependencies attributes.

  • By default, all packages should be included unless a --production flag is used. This flag would be needed on at least the devbox generate dockerfile and devbox install commands, but could be added to others too (e.g. devbox shell).
  • Ideally, Devbox itself should be excluded from Dockerfiles too. This may require a similar trick to what was done in #1036, where devbox shellenv --init-hook was used to set up the environment in the container so that Devbox does not need to be run.
  • The following could be moved out into a separate issue if necessary: A new dev_init_hooks array may also be required in devbox.json, in case people have init hooks that should not run in production. Alternatively, Devbox could pass a DEVBOX_PRODUCTION environment variable to each hook, so that the hook can decide whether or not to run. The former approach is cleaner, but the latter gives users more control over the order in which the hooks run. Perhaps both approaches should be implemented so that users can choose what's best for them.

Describe alternatives you've considered An alternative solution would be to maintain two separate devbox.json files, one for dev and one for production, but this is not ideal because the versions specified for common packages may become out of sync.

apgrucza avatar Jun 28 '23 06:06 apgrucza

I would actually prefer not to limit the solution to just two environments ("dev" and "production"). My CI pipelines include "build" and "deploy" steps, each of which use a different subset of packages in devbox.json. Downloading all packages takes a long time (even with a cache set up). I'd like only the packages required for each step to be downloaded.

So, I propose an --environment option and/or a DEVBOX_ENVIRONMENT environment variable that determines which packages to use:

  • The packages required for each environment would be specified by a new environments array in the packages map.
  • Not specifying environments means the package applies to all environments.
  • Omitting --environment and DEVBOX_ENVIRONMENT would cause all packages to be downloaded (which is appropriate for a development environment where all packages should be available).
  • The environments array should be supported in both devbox.json and in Devbox plugins.

Example:

{
  "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.12.0/.schema/devbox.schema.json",
  "packages": [
    "bash": "5",
    "python": {
        "version": "3.12",
        "environments": ["ci-build", "prod"]
    }
    "jfrog-cli": {
        "version": "2",
        "environments": ["ci-build"]
    }
    "shellcheck": {
        "version": "0.10",
        "environments": ["ci-build"]
    }
    "jq": {
        "version": "1",
        "environments": ["ci-build", "ci-deploy"]
    }
    "awscli2": {
        "version": "2",
        "environments": ["deploy"]
    }
    "curl": {
        "version": "8",
        "environments": ["deploy"]
    }
    "terraform": {
        "version": "1",
        "environments": ["deploy"]
    }
  ]
}

apgrucza avatar Jul 01 '24 06:07 apgrucza

I would suggest something like this or using some kind of folder management to add "inheritance" of "libraries":

  "$schema": "https://raw.githubusercontent.com/jetify-com/devbox/0.13.6/.schema/devbox.schema.json",
  "default": "full", // This is the default group
  "groups": [
    {
      "dev": { // This is the dev group
        "packages": [
          "[email protected]",
          "yarn@latest"
        ],
        "shell": {
          "scripts": {}
        }
      }
    },
    {
      "ops": { // This is the ops group
        "packages": [
          "[email protected]",
          "[email protected]",
          "[email protected]",
          "[email protected]",
          "[email protected]",
          "[email protected]",
          "[email protected]",
          "[email protected]",
          "[email protected]"
        ],
        "shell": {
          "init_hook": [
            "chmod +x platform",
            "export PATH=$PATH:$PWD",
          ],
          "scripts": {}
        }
      }
    },
    {
      "full": { // This is the full group
        "inherit": [ // inheritance of previous groups
          "dev",
          "ops"
        ],
        "packages": [
          "[email protected]",
          "starship@latest",
          "zoxide@latest",
          "atuin@latest",
          "carapace@latest",
          "k9s",
          "kind@latest" //changing some version of previous packages as well
        ],
        "shell": {
          "init_hook": [
            "chmod +x platform",
            "export PATH=$PATH:$PWD",
            "nu"
          ],
          "scripts": {}
        }
      }
    }
  ]
}```

gif30 avatar Feb 25 '25 00:02 gif30