Skip to main content

Top-level package for dockerdo.

Project description

https://img.shields.io/pypi/v/dockerdo.svg Documentation Status

Use your local dev tools for remote docker development

If you love customizing your editor (nvim, emacs, anything goes) and your shell, then this is for you.

Installation

With uv

uv tool install dockerdo
dockerdo install

With pip

pip install dockerdo
dockerdo install

Features

  1. Local Development Tools with Remote Power:

    • Allows developers to use their customized local development environment (editors, shell, GUI tools) while working with containers on remote machines.

    • This solves the common problem of losing your preferred development setup when working on remote systems.

  2. SSH Integration:

    • Uses standard SSH for remote execution

    • Supports SSH proxy jumps for complex network setups

  3. Transparent Filesystem Access:

    • Uses SSHFS to mount container filesystems locally

    • Makes remote container files feel like they’re on your local disk

    • Allows using local GUI tools to edit remote files: No need for X11 forwarding for GUI tools

  4. Dockerfile Development Aid:

    • Tracks file modifications and installation commands

    • dockerdo history command shows relevant commands for Dockerfile creation

    • Filters out local commands (like man, diff, grep) to keep history clean

  5. Ease of Use:

    • Simple installation process (uv or pip)

    • Bash completion included

    • Supports different base distributions (Ubuntu, Alpine)

    • Can work with both local and remote Docker hosts

  6. Better response to latency:

    • Over a slow connection, working normally over ssh causes user interface lag in the shell and TUI: it takes a moment for the remote host to respond to each keypress.

    • In a dockerdo workflow, feedback for keypresses is instant, as you are using the local shell and tools.

    • You still have to wait for commands to finish, but the user interface doesn’t feel like molasses.

The tool is aimed towards developers who:

  • Have heavily customized development environments

  • Need to work with remote compute resources

  • Want to maintain their workflow while using containers

  • Need to develop and debug Dockerfiles

Concept

The three systems

There are up to three systems (“machines”) involved when using dockerdo.

  • The local host: Your local machine (laptop, workstation) with your development tools installed.

  • The remote host: The machine on which the Docker engine runs.

  • The container: The environment inside the Docker container.

It’s possible for the local and remote host to be the same machine, e.g. when doing local dockerfile development.

Use case: remote development

Let’s say you have ssh access to a compute cluster with much more resources than on your local laptop. The cluster nodes have a basic linux environment, so your favorite dev tools are not installed. Your dotfiles are not there, unless you copy them in to each node. The lack of dotfiles means that your shell and editor dosn’t behave the way you like. It’s best practice to containerize your workloads, instead of installing all your junk directly on the cluster node. And naturally, inside the container there is only what was deemed necessary for the image, which can be even more sparse than the node. Because the commands run in a shell on a remote machine, you can’t use GUI tools (unless you do X11 forwarding, yuck).

Instead of putting all your tools and configuration in the container, dockerdo makes the container transparently visible to your already configured local tools, including GUI tools.

Use case: Dockerfile development

When writing a new Dockerfile, it is common to start a container from a base image and then begin installing software and changing configuration interactively in a shell on the container. You then need to keep track of the final working commands and add them to the Dockerfile you are writing. This can be a tedious workflow.

Dockerdo makes it a bit easier. You can use your customized shell to move around, and your customized editor to write the files. The dockerdo history command will list any files you modified, so that you can copy them to the repo to be used when building the Dockerfile. The dockerdo history command will also list all the installation commands you executed, so you can copypaste into the Dockerfile. Any local commands you run in between (man, diff, grep, …) are not included in the history, making it easy to find the relevant commands.

Commands

dockerdo install

  • Creates the dockerdo user configuration file (~/.config/dockerdo/dockerdo.yaml).

  • Adds the dodo alias to your shell’s rc file (.bashrc).

  • Adds the dockerdo shell completion to .bashrc.

dockerdo init

  • Initializes a new session.

  • Defines the work dir ${WORK_DIR} on the local host.

  • Mounts the remote host build directory using sshfs into ${WORK_DIR}/${REMOTE_HOST}.

  • To activate the session in the current shell, use source $(dockerdo init). Later, you can use source ./local/share/dockerdo/${session_name}/activate to reactivate a persistent session.

dockerdo overlay

  • Creates Dockerfile.dockerdo which overlays a given image, making it dockerdo compatible.

    • Installs sshd.

    • Copies your ssh key into authorized_keys inside the image.

    • Changes the CMD to start sshd and sleep forever.

  • Supports base images using different distributions: --distro [ubuntu|alpine].

  • Often you can skip this step, as dockerdo build will run it automatically. You need to run it manually if:

    • You want to inspect or modify the Dockerfile before building.

    • You want to recreate the Dockerfile with a different configuration.

dockerdo build

  • Runs dockerdo overlay, unless you already have a Dockerfile.dockerdo.

  • Runs docker build with the overlayed Dockerfile.

  • Supports remote build with the --remote flag. Note that it is up to you to ensure that the Dockerfile is buildable on the remote host.

dockerdo push

  • Only needed when the remote host is different from the local host.

  • Pushes the image to the docker registry, if configured.

  • If no registry is configured, the image is saved to a compressed tarball, copied to the remote host, and loaded.

dockerdo run

  • Starts the container on the remote host.

  • Mounts the container filesystem using sshfs into ${WORK_DIR}/container.

  • Accepts the arguments for docker run.

  • Always run this command in the background dockerdo run &. The command will continue running in the background to maintain the master ssh connection.

  • To record filesystem events, use dockerdo run --record &. The command will continue running in the background to record events using inotify.

dockerdo export

  • Add or overwrite an environment variable in the session environment.

  • Never pass secrets this way.

dockerdo exec (alias dodo)

  • Executes a command in the running container.

  • The working directory is deduced from the current working directory on the local host. E.g. if you ran dockerdo init in /home/user/project, and are now in /home/user/container/opt/mysoftware, the working directory on the container is /opt/mysoftware.

  • You can pipe text in and out of the command, and the piping happens on the local host.

  • Note that stdin is only connected if you pipe text in, or you specify the -i/--interactive flag.

dockerdo status

  • Prints the status of the session.

dockerdo stop

  • Unmounts the container filesystem.

  • Stops the container.

dockerdo history

  • Prints the command history of the session.

  • Prints the list of modified files, if recording is enabled.

dockerdo rm

  • Removes the container.

  • Unmounts the remote host build directory.

  • If you specify the --delete flag, the session directory is also deleted.

  • Note: if dockerdo run fails and leaves the session in a bad state, you can use dockerdo rm --force to clean up.

Configuration

User configuration is in the ~/.config/dockerdo/dockerdo.yaml file.

Step-by-step example of ssh connections

Let’s say your local host is called london, and you want to use a remote host called reykjavik. The reykjavik host is listening on the normal ssh port 22. We start a container, with sshd running on port 22 inside the container. When starting the container, we give the -p 2222:22 argument to docker run, so that the container sshd is listening on port 2222 on the host. However, the admins of reykjavik have blocked port 2222 in the firewall, so we can’t connect directly. We connect from london to reykjavik using port 22, and then jump to the container using port 2222 on reykjavik. Therefore, the ssh command looks like this:

ssh -J reykjavik -p 2222 127.0.0.1

You have installed your key in ~/.ssh/authorized_keys on reykjavik, and dockerdo will copy it into the container. Therefore, you can authenticate without a password both to reykjavik and the container.

If you need to configure a second jump host for reykjavik, or any other ssh options, you should add it to the ssh config on london like you normally do.

Caveats

  • There is no persistent shell environment in the container. Instead, you must use the dockerdo export subcommand. Alternatively, you can set the variables for a particular app in a launcher script that you write and place in your image.

    • Export is the best approach when you need different values in different container instances launched from the same image, and when you need the env variables in multiple different programs. For example, setting the parameters of a benchmark.

    • A launcher script is the best approach when you have a single program that requires some env variables, and you always want to use the same values. Also the best approach if you have large amounts of data that you want to pass to the program through env variables.

  • ``dockerdo history`` with recording will only list edits done via the sshfs mount. Inotify runs on your local machine, and can only detect filesystem operations that happen locally. If you e.g. use your local editor to write a file on the sshfs mount, inotify will detect it. However, if a script inside the container writes a file, there is no way for inotify to detect it, because sshfs is not able to relay the events that it listens to from the container to the local host.

  • sshfs mount is not intended to replace docker volumes, you need both.

    • Docker volumes/mounts are still needed for persisting data on the host, after the container is stopped and/or deleted. You only mount a specific directory, it doesn’t make sense to have the entire container filesystem as a volume. Anything outside of the mounted volume is normally not easily accessible from the outside. Volumes often suffer from files owned by the wrong user (often root-owned files), due to mismatch in user ids between host and container.

    • The dockerdo sshfs mount spans the entire container filesystem. Everything is accessible. The files remain within the container unless copied out, making sshfs mounts unsuitable for persistent data storage. Sshfs doesn’t suffer from weird file ownership.

  • git has some quirks with sshfs.

    • You will have to set git config --global --add safe.directory ${GIT_DIR} to avoid git warnings. You don’t need to remember this command, git will remind you of it.

    • Some git commands can be slower than normal.

  • Avoid –network=host in Docker. If you need to use network=host in Docker, you have to run sshd on a different port than 22. The standard Dockerfile overlay will not do this for you.

  • On slow connections, sshfs can sometimes be slower to update the filesystem than you can run ``dodo`` commands. This can result in strange behavior, if you try to read the filesystem before it has been updated (e.g. files look empty or truncated). If this happens, have patience. You can use --remote_delay to help you have patience, by adding a delay to all remote commands: you can type as fast as you want, and the delay will be handled automatically for you.

  • A flag for interactive mode

    • Note that stdin is only connected if you pipe text in, or you specify the -i/--interactive flag.

    • If you don’t specify the flag and the command tries to read from stdin, you’ll get an error, e.g. EOFError: EOF when reading a line.

    • Interactive mode is slightly slower, as it has to work around a bug in ssh preventing the use of the master socket.

Wouldn’t it be nice

Wouldn’t it be nice if Docker integrated into the ssh ecosystem, allowing ssh into containers out-of-the box.

  • ssh to the container would work similarly to docker exec shells.

  • No need to install anything extra (sshd) in the containers, because the Docker daemon provides the ssh server.

  • Keys would be managed in Docker on the host, instead of needing to copy them into the container.

  • Env could be managed using Docker --env-file, which would be cleaner.

Demo image

Click to enlarge

docs/source/demo.png

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dockerdo-0.2.0.tar.gz (882.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dockerdo-0.2.0-py3-none-any.whl (24.5 kB view details)

Uploaded Python 3

File details

Details for the file dockerdo-0.2.0.tar.gz.

File metadata

  • Download URL: dockerdo-0.2.0.tar.gz
  • Upload date:
  • Size: 882.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.2

File hashes

Hashes for dockerdo-0.2.0.tar.gz
Algorithm Hash digest
SHA256 6f1a65e0dd5d52aa0ecbd3bbc2a15d032939402a69df536d5d583c20e3717b27
MD5 7ac8a14165b72e3bdea831ae0fc3593c
BLAKE2b-256 843bfb7ab34317b1e33d46207340f14022bfb5ce2592cc201cc9aa9c79790b22

See more details on using hashes here.

File details

Details for the file dockerdo-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: dockerdo-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 24.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.2

File hashes

Hashes for dockerdo-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 803067b5fe68f31731c72258482e77095a114a547e699e3fc4f771df55e4d206
MD5 71e51d23e6f09b6d9b13f4bf66e77c16
BLAKE2b-256 ed41350b7eef4a1e20b52e90b01308cc7b790dcef376471e9cb6e57bf930ed98

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page