for quickly setting up a dev container accessible through ssh
./up --buildor to run in background
./up --build -dauthorized_keyscomes from my dotfiles repository. if you would like to use this container for yourself fork and/or create your own dotfiles repo with your own configuration (or at least your own keys) and update theDockerfileto reflect the new dotfiles repo location.- if no $SSH_SOCK_AUTH is set, will default to Docker Desktop/Colima (
colima start --ssh-agent) default of /run/host-services/ssh-auth.sock, this allows agent forwarding from host -> vm -> container- if you see
failed to convert agent configerror when running./upthen $SSH_SOCK_AUTH is probably not set when it should be. no local ssh-agent and/or no ssh-auth.sock from vm provider.
- if you see
- the dev container will be accessible on port 2222 as "dev" user (e.g. ssh dev@localhost -p 2222 if your user is in
authorized_keys) - the container runs as the unprivileged
devuser (uid 65532). sshd needs root only to setuid into other users, andAllowUsers devmeans it never does, so it runs asdevon port 2222 -- a non-root process cannot bind a port below 1024. use./dsh rootif you need a root shell.
optionally configure your container for commit signing. ssh key signing is preferable to gpg signing since you can re-use the existing ssh-agent socket for signing commits.
git config --global gpg.format ssh # (if not already set from dotfiles)
# publickey is coming from dotfiles, otherwise you need to copy to container
git config --global user.signingkey ~/.ssh/<keyfile>.pub
# gpgsign is used for ssh signing as well
git config --global commit.gpgsign trueall of these commands can either be in the global config or local repo config if some repos require
signing and others don't. if you're stowing ~/.gitconfig from your dotfiles repo it might be preferable
to configure these things in ~/.gitconfig.local and include that from your ~/.gitconfig.
you can shell into the dev container as dev with
./dshor if you want to install more tools you can either update the Dockerfile and recreate the container or shell into container as root and install them
./dsh rootclone your project repo somewhere inside the container and then it will be accessible through remote ssh. your project files should all remain in the container. using a docker volume with a bind mount to the host machine would be extremely slow if indexing, installing node dependencies, etc.
the Dockerfile has two targets that share the same base: docker (default,
socat proxy for the mounted agent socket) and k8s (no socket mount, ssh
agent forwarding enabled instead). both run as dev, which also makes
kubectl exec land as dev -- it has no --user flag.
build the k8s target and push it somewhere your cluster can pull:
docker build --ssh default --target k8s -t <registry>/dev:latest .
docker push <registry>/dev:latestattach a throwaway shell to a running pod. the command overrides the default sshd, so none runs:
kubectl debug -it <pod> --image=<registry>/dev:latest --target=<container> -- zsh -luse --profile=sysadmin if you need ptrace/strace against the target
container.
run the image with no command (default is sshd), either as a standalone pod
or as an ephemeral container without --:
kubectl debug <pod> --image=<registry>/dev:latest --target=<container>then port-forward and connect with agent forwarding. -A replaces the docker
socket mount, so git/gh auth works the same as locally:
kubectl port-forward <pod> 2222:2222
ssh -A dev@localhost -p 2222if the pod sets fsGroup, kubernetes adds it as a supplementary group at
container start. a non-root sshd cannot call initgroups(), so ssh sessions
keep that group -- shared volumes stay writable with no extra setup.
note: with agent forwarding each ssh session gets a new SSH_AUTH_SOCK path. if you keep long-lived tmux sessions, symlink it to a stable path on login, e.g. in zshrc:
[ -S "$SSH_AUTH_SOCK" ] && [ "$SSH_AUTH_SOCK" != "$HOME/.ssh/agent.sock" ] \
&& ln -sf "$SSH_AUTH_SOCK" "$HOME/.ssh/agent.sock"
export SSH_AUTH_SOCK="$HOME/.ssh/agent.sock"