Replace privileged: true with cap_drop ALL plus DAC_OVERRIDE, no-new-privileges, a read-only rootfs and memory/pid limits. DAC_OVERRIDE is what lets the uid-0 entrypoint create its storage directory and read the journal and /rootfs; every other capability stays dropped. Route prometheus.exporter.cadvisor, discovery.docker and loki.source.docker through a docker-socket-proxy sidecar on 127.0.0.1:2375 instead of bind-mounting the socket. POST is refused there, so container create and exec are no longer reachable. NETWORKS is granted because Docker SD resolves network names per container and returns no targets without it. Add an alloy validate step to CI and boot the test container with the shipped capability set, read-only rootfs and proxy rather than --privileged.
composes
My docker compose collection — one directory per service, each self-contained. Tuned to my own setup rather than written as general-purpose templates.
Services are deployed through Coolify and Dokploy, which own what a standalone compose file would otherwise declare:
- No published ports. The platform attaches the container to its proxy network and maps a domain to the internal port. Publishing one would also expose it on the host.
- No
restart:policy. The platform manages the container lifecycle. - No
container_name:. Compose derives it from the directory.
Services that do publish ports or set restart: say so in their own README.
Layout
<service>/
compose.yml # the service definition
README.md # what it is, its variables, how it's wired
.env.example # required variables, committed
.env # real values, gitignored
Compose names the project after its directory, so code-server/ comes up as
the code-server project with its own network and volumes.
Usage
In Coolify or Dokploy, point a Docker Compose resource at the service directory
and set the environment variables from its .env.example.
Locally:
cd <service>
cp .env.example .env # then fill it in
docker compose up -d
docker compose logs -f
docker compose down
.env is picked up automatically because it sits next to compose.yml. Never
commit it — the root .gitignore covers .env/*.env and re-includes
.env.example.
Services
Each links to its own README for variables, ports, and storage.
| Service | What it is |
|---|---|
| alloy | Grafana Alloy shipping host and Docker telemetry to Grafana Cloud |
| code-server | VS Code in the browser, as a remote dev box |
| code-server-base | VS Code in the browser, stock image with no mods |
| couchbase | Couchbase Server |
| gitea-mirror-local | Gitea + PostgreSQL + gitea-mirror, mirroring GitHub repos |
| netdata | Netdata monitoring agent |
| ollama | Ollama LLM server |
| opencode-web | opencode coding agent, served as a browser UI |
| openhands | OpenHands coding agent, running each session in a container it spawns |
| paseo | Paseo coding-agent daemon and web UI |
| traffmonetizer | TraffMonetizer bandwidth-sharing client |
Licensed under Apache 2.0 — see LICENSE.