Skip to content

Commit 16a5ebb

Browse files
authored
chore: add docs re docker inside envbuilder-built-envs (#191)
1 parent ca425f7 commit 16a5ebb

File tree

13 files changed

+212
-0
lines changed

13 files changed

+212
-0
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ Provide the encoded JSON config to envbuilder:
134134
DOCKER_CONFIG_BASE64=ewoJImF1dGhzIjogewoJCSJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOiB7CgkJCSJhdXRoIjogImJhc2U2NCBlbmNvZGVkIHRva2VuIgoJCX0KCX0KfQo=
135135
```
136136

137+
### Docker-in-Docker
138+
139+
See [here](./docs/docker.md) for instructions on running Docker containers inside
140+
environments built by Envbuilder.
141+
137142
## Git Authentication
138143

139144
Two methods of authentication are supported:

docs/docker.md

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Docker inside Envbuilder
2+
3+
There are a number of approaches you can use to have access to a Docker daemon
4+
from inside Envbuilder:
5+
6+
## Docker Outside of Docker (DooD)
7+
8+
**Security:** None
9+
**Convenience:** High
10+
11+
This approach re-uses the host Docker socket and passes it inside the container.
12+
It is the simplest approach, but offers **no security** -- any process inside the
13+
container that can connect to the Docker socket will have access to the
14+
underlying host.
15+
Only use it if you are the only person using the Docker socket (for example, if
16+
you are experimenting on your own workstation).
17+
18+
Example:
19+
20+
```console
21+
docker run -it --rm \
22+
-v /tmp/envbuilder:/workspaces \
23+
-e ENVBUILDER_GIT_URL=https://github.com/coder/envbuilder \
24+
-e ENVBUILDER_DEVCONTAINER_DIR=/workspaces/envbuilder/examples/docker/01_dood \
25+
-e ENVBUILDER_INIT_SCRIPT=bash \
26+
-v /var/run/docker.socket:/var/run/docker.socket \
27+
ghcr.io/coder/envbuilder:latest
28+
```
29+
30+
31+
## Docker-in-Docker (DinD)
32+
33+
**Security:** Low
34+
**Convenience:** High
35+
36+
This approach entails running a Docker daemon inside the container.
37+
This requires a privileged container to run, and therefore has a wide potential
38+
attack surface.
39+
40+
Example:
41+
42+
> Note that due to a lack of init system, the Docker daemon
43+
> needs to be started separately inside the container. In this example, we
44+
> create a custom entrypoint to start the Docker daemon in the background and
45+
> call this entrypoint via `ENVBUILDER_INIT_SCRIPT`.
46+
47+
```console
48+
docker run -it --rm \
49+
--privileged \
50+
-v /tmp/envbuilder:/workspaces \
51+
-e ENVBUILDER_GIT_URL=https://github.com/coder/envbuilder \
52+
-e ENVBUILDER_DEVCONTAINER_DIR=/workspaces/envbuilder/examples/docker/02_dind \
53+
-e ENVBUILDER_INIT_SCRIPT=/entrypoint.sh \
54+
ghcr.io/coder/envbuilder:latest
55+
```
56+
57+
### DinD via Devcontainer Feature
58+
59+
The above can also be accomplished using the [`docker-in-docker` Devcontainer
60+
feature](https://github.com/devcontainers/features/tree/main/src/docker-in-docker).
61+
62+
> Note: we still need the custom entrypoint to start the docker startup script.
63+
> See https://github.com/devcontainers/features/blob/main/src/docker-in-docker/devcontainer-feature.json#L60
64+
65+
Example:
66+
67+
```console
68+
docker run -it --rm \
69+
--privileged \
70+
-v /tmp/envbuilder:/workspaces \
71+
-e ENVBUILDER_GIT_URL=https://github.com/coder/envbuilder \
72+
-e ENVBUILDER_DEVCONTAINER_DIR=/workspaces/envbuilder/examples/docker/03_dind_feature \
73+
-e ENVBUILDER_INIT_SCRIPT=/entrypoint.sh \
74+
ghcr.io/coder/envbuilder:latest
75+
```
76+
77+
## Rootless DinD
78+
79+
**Security:** Medium
80+
**Convenience:** Medium
81+
82+
This approach runs a Docker daemon in *rootless* mode.
83+
While this still requires a privileged container, this allows you to restrict
84+
usage of the `root` user inside the container, as the Docker daemon will be run
85+
under a "fake" root user (via `rootlesskit`). The user inside the workspace can
86+
then be a 'regular' user without root permissions.
87+
88+
> Note: Once again, we use a custom entrypoint via `ENVBUILDER_INIT_SCRIPT` to
89+
> start the Docker daemon via `rootlesskit`.
90+
91+
Example:
92+
93+
```console
94+
docker run -it --rm \
95+
--privileged \
96+
-v /tmp/envbuilder:/workspaces \
97+
-e ENVBUILDER_GIT_URL=https://github.com/coder/envbuilder \
98+
-e ENVBUILDER_DEVCONTAINER_DIR=/workspaces/envbuilder/examples/docker/04_dind_rootless \
99+
-e ENVBUILDER_INIT_SCRIPT=/entrypoint.sh \
100+
ghcr.io/coder/envbuilder:latest
101+
```
102+
103+
## Docker-in-Docker using Sysbox
104+
105+
**Security:** High
106+
**Convenience:** Low for infra admins, high for users
107+
108+
This approach requires installing the [`sysbox-runc` container
109+
runtime](https://github.com/nestybox/sysbox/blob/master/docs/user-guide/install-package.md).
110+
This is an alternative container runtime that provides additional benefits,
111+
including transparently enabling Docker inside workspaces. Most notably, it
112+
**does not require a privileged container**, so you can allow developers root
113+
access inside their workspaces, if required.
114+
115+
Example:
116+
```console
117+
docker run -it --rm \
118+
-v /tmp/envbuilder:/workspaces \
119+
-e ENVBUILDER_GIT_URL=https://github.com/coder/envbuilder \
120+
-e ENVBUILDER_DEVCONTAINER_DIR=/workspaces/envbuilder/examples/docker/02_dind \
121+
-e ENVBUILDER_INIT_SCRIPT=/entrypoint.sh \
122+
--runtime sysbox-runc \
123+
ghcr.io/coder/envbuilder:latest
124+
```
125+
126+
For further information on Sysbox, please consult the [Sysbox
127+
Documentation](https://github.com/nestybox/sysbox/blob/master/docs/user-guide/README.md).

examples/docker/01_dood/Dockerfile

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
FROM ubuntu:noble
2+
RUN apt-get update && apt-get install -y docker.io
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"build": {
3+
"dockerfile": "Dockerfile"
4+
}
5+
}

examples/docker/02_dind/Dockerfile

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FROM ubuntu:noble
2+
RUN apt-get update && \
3+
apt-get install -y curl apt-transport-https && \
4+
curl -fsSL https://get.docker.com/ | sh -s -
5+
ADD entrypoint.sh /entrypoint.sh
6+
ENTRYPOINT ["/entrypoint.sh"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"build": {
3+
"dockerfile": "Dockerfile"
4+
}
5+
}

examples/docker/02_dind/entrypoint.sh

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
nohup dockerd > /var/log/docker.log 2>&1 &
6+
7+
exec bash --login
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
FROM ubuntu:noble
2+
ADD entrypoint.sh /entrypoint.sh
3+
ENTRYPOINT ["/entrypoint.sh"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"build": {
3+
"dockerfile": "Dockerfile"
4+
},
5+
"features": {
6+
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
7+
}
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
/usr/local/share/docker-init.sh
6+
7+
exec bash --login
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
FROM ubuntu:noble
2+
# Based on UID of ubuntu user in container.
3+
ENV XDG_RUNTIME_DIR /run/user/1000
4+
ENV DOCKER_HOST unix:///${XDG_RUNTIME_DIR}/docker.sock
5+
# Setup as root
6+
RUN apt-get update && \
7+
# Install prerequisites
8+
apt-get install -y apt-transport-https curl iproute2 uidmap && \
9+
# Install Docker
10+
curl -fsSL https://get.docker.com/ | sh -s - && \
11+
# Add ubuntu user to docker group
12+
usermod -aG docker ubuntu && \
13+
# Create the XDG_RUNTIME_DIR for our user and set DOCKER_HOST
14+
mkdir -p ${XDG_RUNTIME_DIR} && \
15+
chown ubuntu:ubuntu ${XDG_RUNTIME_DIR}
16+
17+
# Setup rootless mode as the ubuntu user.
18+
USER ubuntu
19+
RUN dockerd-rootless-setuptool.sh install && \
20+
docker context use rootless && \
21+
mkdir -p /home/ubuntu/.local/share/docker
22+
# Add our custom entrypoint
23+
ADD entrypoint.sh /entrypoint.sh
24+
ENTRYPOINT ["/entrypoint.sh"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"build": {
3+
"dockerfile": "Dockerfile"
4+
}
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
# Start the rootless docker daemon as a non-root user
6+
nohup rootlesskit --net=slirp4netns --mtu=1500 --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run dockerd > "/tmp/dockerd-rootless.log" 2>&1 &
7+
8+
exec bash --login

0 commit comments

Comments
 (0)