dosh - run a user shell in a container with cwd bind mounted
dosh(1) is an sh-compatible frontend for docker that runs commands in a new container; using the current user, with cwd bind mounted.
Commands are read either from the standard input or from a file or from command
line using one of the standard shell invocations (i.e. thanks to options -c
,
-i
, -s
or without arguments).
Build the documentation using make(1)
$ make doc
asciidoctor -b manpage -o dosh.1 dosh.1.adoc
gzip -c dosh.1 >dosh.1.gz
rm dosh.1
Run the following command to install dosh(1)
To your home directory
$ make user-install
Or, to your system
$ sudo make install
Traditional variables DESTDIR and PREFIX can be overridden
$ sudo make install PREFIX=/opt/dosh
Or
$ make install DESTDIR=$PWD/pkg PREFIX=/usr
dosh(1) uses /bin/sh
as default interpreter as it is the only reliable Shell
available. The default interpreter can be set by option --shell SHELL
; but it
needs to be set to every call to dosh.
dosh --shell /bin/bash
Instead, the default interpreter can be set using the DOSHELL
environment
variable. When this variable is exported, there is no need to override the Shell
interpreter through the command-line.
Adding these two following lines to the Shell ~/.profile
to tell dosh to
use /bin/bash
as Shell interpreter.
DOSHELL="/bin/bash"
export DOSHELL
dosh(1) relies on the setup of Docker. See its documentation to run Docker as non-root-user.
It is not recommended to run dosh(1) using sudo
in case the user does not
have permission to send the context to the Docker daemon. Instead, consider
using the option --sudo
as it will only run the docker
commands with the
superuser privileges.
On Linux, if you are not a member of the docker
group, please consider to run
dosh
as below:
dosh --sudo
Every docker(1) command performed in dosh(1) can be customized by passing extra arguments thanks its corresponding DOSH_DOCKER_xxx_EXTRA_OPTS environment variable. xxx represents one of the docker commands used in dosh (build, rmi, run, exec, attach, kill and rm).
Note: Only DOSH_DOCKER_RUN_EXTRA_OPTS
is relevant for interactive usage.
As an example, consider mapping extra personal dot-files to feel at home in the container.
Adding these two following lines to the Shell ~/.profile
automatically binds
the ~/.ssh
directory to the container.
DOSH_DOCKER_RUN_EXTRA_OPTS="--volume $HOME/.ssh:$HOME/.ssh"
export DOSH_DOCKER_RUN_EXTRA_OPTS
dosh(1) reads and executes commands from initialization files when it is invoked.
Unlike the standard shells, dosh(1) uses files from personal and local locations instead of files from system and personal locations. The system initialization file is replaced by a local file; and that local file is run after the personal file.
In short, the personal file ~/.dosh_profile
is read first, and the local
file ./doshrc
is read then. The former file is hidden to avoid polutting the
personal directory (as .profile
, .bash_profile
, .bashrc
...) while the
later is not (like Makefile
, Dockerfile
...).
The Shell initialization files (.profile
, .bash_profile
, .bashrc
...) are
read by the host shell. The dosh specific environment-variables are string
variables, and they have to be exported to be part of the environment of the
dosh(1) sub-process.
Both dosh initialization files aim to override the dosh specific variables. The extra options environment-variables are converted to bash(1) arrays before the initialization files are read by dosh(1). They have to remain bash(1) arrays.
Here are some examples of code to copy/paste in the ~/.profile
.
They significantly improve the dosh experience.
This asks dosh to use the same Shell interpreter as the one which is currently in use.
# Not sh?
if [ "$SHELL" != "/bin/sh" ]
then
export DOSHELL="$SHELL"
fi
Important: Be aware that when the Shell interpreter is not installed in the container, dosh ends with the following error:
docker: Error response from daemon: oci runtime error: container_linux.go:265: starting container process caused "exec: \"/bin/zsh\": stat /bin/zsh: no such file or directory".
These following lines export some useful environment variables to the container.
# Export some environment variables
for env in TERM EDITOR
do
[ -n "$env" ] || continue
DOSH_DOCKER_RUN_EXTRA_OPTS+=" --env $env"
done
These following lines map some useful dot-files to the container.
# Map some home dot-files
for vol in $HOME/.config $HOME/.local $HOME/.profile
do
[ -e "$vol" ] || continue
DOSH_DOCKER_RUN_EXTRA_OPTS+=" --volume $vol:$vol"
done
# Map extra home dot-files
for vol in $HOME/.inputrc $HOME/.gnupg $HOME/.screenrc
do
[ -e "$vol" ] || continue
DOSH_DOCKER_RUN_EXTRA_OPTS+=" --volume $vol:$vol"
done
bash(1) invocation files is a must-have to feel like home.
# Map bash dot-files
for vol in $HOME/.bash{_profile,rc,login,logout}
do
[ -e "$vol" ] || continue
DOSH_DOCKER_RUN_EXTRA_OPTS+=" --volume $vol:$vol"
done
zsh(1) too.
# Map zsh dot-files
zdotdir="${ZDOTDIR:-$HOME}"
for vol in $zdotdir/.zshenv $zdotdir/.zprofile $zdotdir/.zshrc $HOME/.zlogin $HOME/.zlogout
do
[ -e "$vol" ] || continue
DOSH_DOCKER_RUN_EXTRA_OPTS+=" --volume $vol:$vol"
done
For a better experience with SSH, these following lines should be considered.
# Map and export ssh things?
if [ -d "$HOME/.ssh" ]
then
DOSH_DOCKER_RUN_EXTRA_OPTS+=" --volume $HOME/.ssh:$HOME/.ssh"
fi
if [ -n "$SSH_AUTH_SOCK" ]
then
DOSH_DOCKER_RUN_EXTRA_OPTS+=" --env SSH_AUTH_SOCK"
DOSH_DOCKER_RUN_EXTRA_OPTS+=" --volume $SSH_AUTH_SOCK:$SSH_AUTH_SOCK"
fi
To enable X in docker, these following lines should be considered.
# Map and export X things?
if [ -n "$DISPLAY" ]
then
for env in DISPLAY XAUTHORITY XSOCK
do
[ -n "$env" ] || continue
DOSH_DOCKER_RUN_EXTRA_OPTS+=" --env $env"
done
dotxauthority="${XAUTHORITY:-$HOME/.Xauthority}"
if [ -e "$dotxauthority" ]
then
DOSH_DOCKER_RUN_EXTRA_OPTS+=" --volume $dotxauthority:$HOME/.Xauthority"
fi
unset dotxauthority
xsock="${XSOCK:-/tmp/.X11-unix}"
if [ -e "$xsock" ]
then
DOSH_DOCKER_RUN_EXTRA_OPTS+=" --volume $xsock:/tmp/.X11-unix:ro"
fi
unset xsock
fi
Note: To enable X through SSH, please have a look to the excellent post of Jean-Tiare Le Bigot on its blog yadutaf.
Colorize the prompt from the container in a different way to distinguish dosh sessions.
# In dosh?
if [ -z "$DOSHLVL" ]
then
return
fi
# Colorize prompt color differently
PS1="${PS1//32/33}"
PROMPT="${PROMPT//blue/green}"
Note: Put these lines to the end of the file.
Lines after the if statement are applied in the container.
podman is a daemonless alternative to docker providing the same command line interface, and it can replace docker without any troubles.
Adding these two following lines to the Shell ~/.profile
to tell dosh to
use /usr/bin/podman
to run docker
commands:
DOSH_DOCKER="/usr/bin/podman"
export DOSH_DOCKER
Also, disable the context using option --no-auto-context
.
Additionally, for Rootless containers, consider adding the two following extra run options to map host UID and GIDs to the container and run it inside a user namespace.
Add either the following line to the Shell ~/.profile
:
DOSH_DOCKER_RUN_EXTRA_OPTS="--userns keep-id --group-add keep-groups"
Or the following line to the dosh ~/.dosh_profile
:
DOSH_DOCKER_RUN_EXTRA_OPTS+=(--userns keep-id --group-add keep-groups`)
Alternatively, use the convenient wrapper script posh to run dosh using podman underneath without touching the Shell and dosh files.
Check for man-pages and its examples.
Also, here is an extra example that builds the documentation
$ echo FROM ubuntu >Dockerfile
$ echo RUN apt-get update && apt-get install -y asciidoctor >>Dockerfile
$ cat Dockerfile
FROM ubuntu
RUN apt-get update && apt-get install -y asciidoctor
$ dosh -c asciidoctor -b manpage -o - dosh.1.adoc | gzip -c - >dosh.1.gz
sha256:ced062433e33
$ man ./dosh.1.gz
Enjoy!
Sumbit patches at https://github.com/gportay/dosh/pulls
Report bugs at https://github.com/gportay/dosh/issues
Written by Gaël PORTAY [email protected]
Copyright 2017-2020,2023-2025 Gaël PORTAY
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 of the License, or (at your option) any later version.