Skip to content

Docker in Workspace ​

Overview ​

Docker logo

The workspace comes pre-packaged with all the requirements to run Docker.

Running Docker within an existing container (workspace) is not natively supported by Docker. However, there are alternative methods to achieve this, each with its trade-offs.

INFO

Since this topic is widely documented online, we will not delve into the various risks and tradeoffs of each method.

You can read more about this topic by running a simple Google search for "run docker in docker".

Throughout this page, we will refer to the diagram below which illustrates the basic Docker architecture. The subsequent sections might present a partial perspective of the complete architecture.

Docker architecture

WARNING

The documentation below is tailored for use on a Linux host. Running Docker on Windows may introduce various discrepancies that could impact the applicability and effectiveness of the provided solutions.

Docker In Docker ​

Docker In Docker (also known as dind) allows developers to run a Docker container within an already running Docker container, in order to create sandboxed container environments.

There are five possible methods to accomplish this:

CAVEAT

Options #3, #4, #5, and #6 utilize different forms of remote connections to the Docker daemon running on the remote host. As such, all paths and ports are relative to the remote host and not the running workspace.

If your intention is solely to utilize Docker for building purposes, feel free to ignore the information provided above.

1. Use sysbox (suggested) ​

Sysbox is the recommended method for securely running Docker in Docker. It enables containers to act as virtual machines by improving isolation without requiring privileged mode.

Once sysbox is installed, run the workspace using the sysbox-runc runtime:

sh
docker run \
  --runtime=sysbox-runc \
  -e WS_CONFIGURE_DOCKER=1 \
  ghcr.io/kloudkit/workspace:latest

2. Run dockerd in the Container ​

This approach allows you to start the Docker daemon (dockerd) directly within the container. However, this requires the container to run in privileged mode:

sh
docker run \
  --privileged \
  -e WS_CONFIGURE_DOCKER=1 \
  ghcr.io/kloudkit/workspace:latest

3. Mounting the Docker Socket From the Host ​

Host mount

sh
docker run \
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
  -e WS_CONFIGURE_DOCKER=1 \
  ghcr.io/kloudkit/workspace:latest

4. Connect to a Remote Host (TCP) ​

TCP

Assuming you have access to a remote host running docker, you can set the value of DOCKER_HOST as follows (replace <remote> with your node's IP):

sh
docker run \
  -e DOCKER_HOST=tcp://<remote>:2375 \
  ghcr.io/kloudkit/workspace:latest

Alternately, you can run the command above securely using port 2376 and pregenerated key-pairs.

5. Connect to a Remote Host (SSH) ​

SSH

Assuming you have SSH access to a remote host running docker, you can set the value of DOCKER_HOST as follows (replace <remote> and <user> with your node's IP and username):

sh
docker run \
  -e DOCKER_HOST=ssh://<user>@<remote> \
  ghcr.io/kloudkit/workspace:latest

This method is optimized by the workspace as we internally configure a persistent ssh-agent behind the scenes for a quicker connection experience. For more information, visit our documentation on ssh

6. Use docker:dind Running on a Remote Host ​

DIND

This process is split into 3 steps:

  1. Create a shared network for both containers (workspace and dind):

    sh
    docker network create dind
  2. Run the dind container without TLS shares. Follow these instructions if you decide to use TLS.

    sh
    docker run \
      --privileged \
      --name dind \
      --net dind \
      -v workspace:/workspace:ro \
      -e DOCKER_TLS_CERTDIR="" \
      docker:dind
  3. Finally, run the workspace container using the same network as above.

    sh
    docker run \
      -e DOCKER_HOST=tcp://dind:2375 \
      -v workspace:/workspace \
      --net dind \
      ghcr.io/kloudkit/workspace:latest

NOTE

Feel free to use the docker context command instead of the DOCKER_HOST environment variable from within a running workspace.

Automatically Configure the Docker Daemon ​

Certain methods mentioned earlier (#1, #2, and #3) may require additional user permissions for interacting with the Docker socket. In certain instances (specifically, #1 and#2), the daemon may not be running upon startup.

To speed up the process, during initialization, assign the WS_CONFIGURE_DOCKER environment variable to effortlessly initiate the daemon (if necessary):

sh
docker run \
  -e WS_CONFIGURE_DOCKER=1 \
  ghcr.io/kloudkit/workspace:latest

Docker Group ​

By default, the group assigned to docker is 999. When working with host mounts, it's essential to ensure that the docker.sock file on the host is accessible within the container.

To make sure the container has the necessary group access to the Docker socket, you can use the --group-add flag. This allows you to match the group from the host system to the group inside the container, ensuring the container has the appropriate permissions, as seen below:

sh
docker run \
  --group-add=8888
  -v /var/run/docker.sock:/var/run/docker.sock:ro \
  -e WS_CONFIGURE_DOCKER=1 \
  ghcr.io/kloudkit/workspace:latest

Make sure to replace 8888 with the appropriate group ID from your host system. You can find the group ID associated with docker.sock by checking the permissions:

sh
ls -l /var/run/docker.sock

The same can be achieved in Kubernetes by using supplementalGroups:

yaml
# ...
securityContext:
  supplementalGroups:
    - 8888
# ...

Released under the MIT License