Skip to main content
lager devenv manages a reproducible, Docker-based development environment for a project. It records the image, mount directory, shell, saved commands, bind mounts, and environment variables in the DEVENV section of your project’s .lager config file, so every engineer (and your CI) builds and tests in the same container. The environment is consumed by lager exec (run a command in the container) and lager devenv terminal (open an interactive shell in the container).

Syntax

lager devenv COMMAND [ARGS]...

Subcommands

CommandDescription
createCreate the DEVENV config (image, mount dir, shell)
terminalOpen an interactive shell in the container
showPrint the resolved DEVENV configuration
setSet a scalar config key (or append to ports)
unsetRemove a config key entirely
addSave a named command
deleteRemove a saved command
commandsList saved commands
mount add/remove/listManage persistent bind-mounts / volumes
env set/unset/listManage persistent environment variables

Prerequisites

Docker must be installed and on your PATH. Install it from docker.com. On Linux, add your user to the docker group so you don’t need sudo:
sudo usermod -aG docker $USER   # then log out/in, or run: newgrp docker

create

Create the DEVENV section in your project’s .lager config. Run this once per project before using lager exec or lager devenv terminal.
lager devenv create
OptionDefaultDescription
--image TEXTlagerdata/devenv-cortexmDocker image to use
--mount-dir TEXT/appWhere your source code is mounted inside the container
--shell TEXT/bin/bashShell executable inside the image
The image name is validated against standard Docker naming (name, name:tag, registry/name, registry/name:tag). For lagerdata/* images the shell defaults to /bin/bash; for other images you’ll be prompted. If a DEVENV section already exists you’ll be asked before overwriting it.

terminal

Open an interactive shell inside the development container. Your project directory is bind-mounted at the configured mount_dir, and the container is removed on exit (unless --detach is used).
lager devenv terminal
OptionShortDescription
--mount TEXT-mMount a named Docker volume at mount_dir instead of the source dir
--user TEXT-uUser to run as (overrides the user config key)
--group TEXT-gGroup to run as (overrides the group config key)
--name TEXT-nSet the container name
--detach / --no-detach-dRun the container detached
--port TEXT-pPublish a port (HOST:CONTAINER). Repeatable
--entrypoint TEXTOverride the container entrypoint
--network TEXTDocker network mode
--platform TEXTTarget platform (e.g. linux/amd64)
--attach TEXT-aAttach a shell to an already-running container by name
--shell TEXT-sShell to use when attaching (default: config shell or /bin/bash)
--volume TEXT-vBind-mount a host path (HOST:CONTAINER[:ro]). Repeatable
--env FOO=BAR-eSet an environment variable. Repeatable
--passenv NAMEPass a variable through from your current shell. Repeatable
--infoPrint the resolved docker command and config, then exit without launching
CLI flags take precedence over the matching keys stored in the DEVENV config; config-defined ports, volumes, and environment are applied first, then anything passed on the command line is appended. terminal also wires up SSH for you automatically: it forwards your SSH_AUTH_SOCK agent socket and mounts ~/.ssh/id_ed25519 and ~/.ssh/known_hosts (read-only) when they exist, and it mounts your global .lager config into the container so nested lager calls are authenticated. Use --info to debug what would run without launching anything:
lager devenv terminal --info

Attach to a running container

# Open a second shell in a container started with --detach --name build
lager devenv terminal --attach build --shell /bin/bash

show

Print the resolved DEVENV configuration — scalar keys, list keys (ports, volumes, environment), and saved commands.
lager devenv show

set / unset

Set or remove individual configuration keys without re-running create.
lager devenv set image lagerdata/devenv-cortexm:latest
lager devenv set mount_dir /workspace
lager devenv set port 8080:8080      # appends to the ports list
lager devenv unset platform
Scalar keys (replaced on set): image, mount_dir, shell, user, group, entrypoint, hostname, macaddr, network, platform, repo_root_relative_path. The ports key is a list and is appended to (the singular alias port is accepted). Edit volumes and environment with lager devenv mount and lager devenv env respectively — set will refuse them and point you at the right command.

Saved commands: add / delete / commands

Save shell commands under a name so they can be run with lager exec <name>. Commands are stored as cmd.<name> keys in the DEVENV section.
lager devenv add build "make -j4"
lager devenv add test "pytest tests/ --tb=short"
lager devenv commands          # list saved commands
lager devenv delete build      # remove one
Command names may contain only letters, numbers, dashes, and underscores. If you omit the command string, add prompts for it. By default add warns when overwriting an existing command; pass --no-warn to suppress that.

Persistent bind-mounts: mount

Persist host bind-mounts / named volumes in the config so they’re applied on every lager devenv terminal and lager exec run.
lager devenv mount add /host/cache:/root/.cache       # host bind-mount
lager devenv mount add toolchain:/opt/toolchain       # named volume
lager devenv mount add /etc/ssl/certs:/etc/ssl/certs:ro
lager devenv mount list
lager devenv mount remove /host/cache:/root/.cache
Specs use Docker -v form: HOST:CONTAINER[:ro] for a bind-mount or NAME:CONTAINER for a named volume. For portability across machines, specs may use ~, environment variables, and ${PROJECT_ROOT} (which expands to your project’s .lager directory).

Persistent environment variables: env

Persist environment variables in the config so they’re set on every run.
lager devenv env set CFLAGS=-O2
lager devenv env set DEBUG=0
lager devenv env list
lager devenv env unset DEBUG
env set replaces any existing value for the same variable.

How it relates to lager exec

CommandPurpose
lager devenv ...Configure the local container (image, mounts, env, saved commands)
lager devenv terminalOpen an interactive shell in that container
lager execRun a one-off or saved command in that container
All three read the same DEVENV section, so a command saved with lager devenv add is runnable with lager exec, and a mount added with lager devenv mount add applies to both terminal and exec.

Notes

  • Configuration is stored in the DEVENV section of the nearest .lager config file, discovered by walking up from the current directory.
  • terminal launches the container with --rm by default, so it’s removed on exit unless you pass --detach.
  • Exit codes from the container are propagated to the CLI.