cachix / devenv

Fast, Declarative, Reproducible, and Composable Developer Environments
https://devenv.sh
Apache License 2.0
4.46k stars 335 forks source link

Run `devenv shell` when creating the container #997

Open domenkozar opened 8 months ago

domenkozar commented 8 months ago

We'd want to support Docker and Podman, the two most popular desktop container engines.

The only compatibility layer that exists is Docker RESTful API, where the workflow would be something like:

  1. Build our container

  2. curl -X POST http://localhost:2375/containers/create \
     -H "Content-Type: application/json" \
     -d '{
           "Image": "spec.json",
           "Cmd": ["devenv", "shell"],
         }'
  3. curl -X POST http://localhost:2375/containers/{id}/start

  4. curl -X POST "http://localhost:2375/commit?container={id}" \
     -H "Content-Type: application/json" \
     -d '{
           "repo": "mynewimage",
           "tag": "latest",
           "comment": "This is my new image",
           "author": "Your Name",
         }'

I'm not sure yet what this would be called, but for now I propose containers.<name>.impureShell = "...";.

cc @mcdonc

mcdonc commented 4 weeks ago

IIUC, it would be cool if it were this easy but the devenv command isn't available anywhere in the PATH within a container. Currently only the devenv-tasks cmd exists within the bindir of the devenv derivation installed in the container and it's not available on the PATH either. We could make it so we could do devenv-tasks run devenv:enterShell easily, that might help.

I'm currently executing this within a Dockerfile to generate a new image with the devenv container as a base:

# syntax=docker/dockerfile:1
# Derived from: https://docs.docker.com/language/python/build-images/

FROM ghcr.io/mcdonc/testpackages/climo:latest

USER user
WORKDIR /env

# creates layer where pip requirements are installed
RUN /bin/entershell

CMD /bin/runproject

Where entershell is:

  entershell = pkgs.writeShellScriptBin "entershell" ''
    # XXX this would be way easier if i could figure out how to get
    # the path to the devenv installed in the container within nix
    devenv=`ls -x /nix/store|grep -P '.{32}\-devenv-\d\.'`
    /nix/store/$devenv/bin/devenv-tasks run devenv:enterShell
  '';

And runproject is

  runproject = pkgs.writeShellScriptBin "runproject" ''
    ${config.procfileScript}
  '';

I add a layer using containers.climo.layers.copyToRoot to put entershell and runproject into the root of the image produced by devenv container, then I then run docker build --tag 'ghcr.io/mcdonc/testpackages/climo:depsinstalled' . to get a derived image that has enterShell run already.