Skip to content

Commit 6fe3432

Browse files
committed
docs: clarify Docker-in-LXC security boundary
1 parent f095191 commit 6fe3432

5 files changed

Lines changed: 39 additions & 0 deletions

File tree

docs/architecture.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ Baseline `default` and `terrarium` profile behavior:
188188
- root disk on the Terrarium pool
189189
- NIC attached to `terrarium-ovn`
190190

191+
Terrarium does not make ordinary workload containers privileged. The isolated
192+
ID map means container root, including root inside a Docker daemon nested in the
193+
container, is still separated from host root by LXC's user-namespace boundary.
194+
That gives Docker-heavy deployments a host protection layer they would not get
195+
from running all Docker workloads directly on the VPS.
196+
191197
This is an intentional product choice: Terrarium optimizes for isolated environments that can still run realistic developer and agent workloads, including Docker Compose stacks, instead of optimizing for the narrowest possible LXC feature surface.
192198

193199
The `strict` profile keeps the Terrarium root disk and OVN NIC but omits

docs/guides/compose.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This is especially useful for complex projects that want their own dependencies,
88

99
Terrarium's LXD `default` profile enables the settings that Docker-in-LXC usually needs:
1010

11+
- `security.idmap.isolated=true`
1112
- `security.nesting=true`
1213
- `security.syscalls.intercept.mknod=true`
1314
- `security.syscalls.intercept.setxattr=true`
@@ -38,6 +39,16 @@ Terrarium gives each Compose deployment its own boundary:
3839

3940
The stack lives in an LXC container instead of directly on the host. If the workload is compromised or misconfigured, the host is still a separate layer with a smaller blast radius.
4041

42+
Terrarium's normal workload containers are unprivileged and use isolated ID
43+
maps. That means root inside the LXC, and root inside Docker containers created
44+
by the nested Docker daemon, does not become host root. This is especially
45+
useful for Compose stacks copied from the internet or built by app installers
46+
that assume broad Docker access.
47+
48+
This is still a boundary, not a permission to be careless. Avoid `privileged:
49+
true`, broad host bind mounts, host networking, and public admin panels unless
50+
the app genuinely needs them and you understand the risk.
51+
4152
### Isolation
4253

4354
Each Compose stack gets its own filesystem, packages, images, volumes, and daemon state. That makes it much easier to keep multiple projects on one VPS without constant interference.

docs/guides/coolify.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ That gives Coolify the SSH-managed server model it expects, while Terrarium
1515
keeps Docker off the host and gives you LXD isolation, OVN networking, and ZFS
1616
snapshots around each Docker host.
1717

18+
The Coolify servers are unprivileged LXC containers by default. Root inside
19+
those containers, including root inside Docker workloads launched by Coolify, is
20+
not host root, so Docker misconfiguration has one more containment layer before
21+
it reaches the Terrarium host.
22+
1823
## When to use this instead of plain Compose
1924

2025
Use [Isolated Docker Compose deployments](./compose) when you want one stack in

docs/guides/dokploy.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ On Terrarium, the clean model is:
1111

1212
That means Dokploy gets the server model it expects, while Terrarium still gives you LXD isolation and ZFS snapshots around each Docker host.
1313

14+
Those Docker hosts are unprivileged LXC containers by default. Root inside the
15+
deployment-server container, including root inside Docker workloads launched by
16+
Dokploy, is mapped away from host root, which adds a useful host-side safety
17+
layer for Docker deployments with imperfect defaults.
18+
1419
## When to use this instead of plain Compose
1520

1621
Use [Isolated Docker Compose deployments](./compose) when you want one app stack in one container and you are comfortable managing Compose files yourself.

docs/security.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Terrarium is designed to make the safe path feel natural, especially for people
55
The short version:
66

77
- containers are private by default
8+
- workload containers are unprivileged LXC by default
89
- the host is hardened
910
- public exposure is explicit
1011
- a built-in time machine is part of the default storage model
@@ -85,8 +86,17 @@ lxc launch images:ubuntu/24.04 devbox
8586
The compatibility alias `terrarium` has the same settings, so older commands
8687
that pass `--profile terrarium` still work.
8788

89+
Terrarium workload containers are unprivileged LXC containers by default. The
90+
profiles use isolated ID maps, so root inside the container is not host root.
91+
When you run Docker inside one of these containers, Docker still needs
92+
Docker-friendly LXC features, but the nested Docker daemon and its containers
93+
sit behind the extra LXC user-namespace boundary instead of running directly on
94+
the host. That is a useful additional layer against badly configured Docker
95+
deployments.
96+
8897
The baseline `default` and `terrarium` profiles include:
8998

99+
- `security.idmap.isolated=true`
90100
- `security.nesting=true`
91101
- `security.syscalls.intercept.mknod=true`
92102
- `security.syscalls.intercept.setxattr=true`
@@ -101,6 +111,8 @@ Tradeoff:
101111

102112
- this is more permissive than a minimal non-nested container profile
103113
- it is a convenience and compatibility choice, not the narrowest possible baseline
114+
- it does not make broad Docker privileges, unsafe host bind mounts, or exposed
115+
app admin panels safe
104116

105117
Terrarium also creates a `strict` profile for workloads that should not need
106118
nested container runtimes:

0 commit comments

Comments
 (0)