Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
139aeab
CI: pin actions to commit SHAs, limit token permissions, lint the .gi…
jackspiering Oct 8, 2026
9163c01
CI: validate every service with docker compose config
jackspiering Oct 8, 2026
4f7026f
Paperless, Flatnotes, Technitium, EspoCRM, NextExplorer: require your…
jackspiering Oct 8, 2026
b2eb384
Coder, Mattermost, Sure, XWiki, AFFiNE, Immich, Tandoor: require your…
jackspiering Oct 8, 2026
a43a70f
GitSave, ArtistTrackarr, Seafile: require your own secrets
jackspiering Oct 8, 2026
e73236a
Technitium: warn that the web console on port 5380 uses plain HTTP
jackspiering Oct 8, 2026
816b6e8
Docker socket: say that :ro does not limit Docker API access
jackspiering Oct 8, 2026
898724e
Tandoor: stop Compose when SECRET_KEY is empty
jackspiering Oct 8, 2026
6f4dc40
CI: use the latest rumdl action
jackspiering Oct 8, 2026
74de5a3
CI: cancel superseded runs only on pull requests and fail when the va…
jackspiering Oct 8, 2026
09fd0e8
Upgrading notes: name the old sample value of each database password …
jackspiering Oct 8, 2026
7059021
CI: pin the rumdl version to the pinned action
jackspiering Oct 8, 2026
e100034
Sure, Tandoor, GitSave: require SECRET_KEY_BASE and give one way to g…
jackspiering Oct 8, 2026
e9b74b1
Booklore, FreshRSS, Kaneo, KitchenOwl, Miniflux: stop when a required…
jackspiering Oct 8, 2026
347a32c
AdGuard Home Sync, Formbricks, Frigate, Ghost, Gotify, Nanote: move t…
jackspiering Oct 9, 2026
aaab90a
Merge branch 'main' into t3code/template-baseline-ci-review
jackspiering Oct 9, 2026
98a4878
AFFiNE, Coder, Mattermost, Miniflux: say which characters the databas…
jackspiering Oct 9, 2026
250a9cb
AFFiNE: use password authentication for the database; Paperless, Espo…
jackspiering Oct 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .github/workflows/compose-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Validate Compose files
on:
workflow_dispatch:
push:
branches:
- main
paths:
- 'services/**'
- '.github/workflows/compose-validation.yml'
pull_request:
branches:
- main
paths:
- 'services/**'
- '.github/workflows/compose-validation.yml'

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
validate:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Clone this repo
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

# Some stacks require the user to set their own secrets and stop with
# "required variable X is missing". Supply a dummy value for those and
# retry, so that the rest of the file is still checked.
- name: Run docker compose config
run: |
status=0
for dir in services/*/; do
vars=()
ok=0
for attempt in $(seq 1 30); do
if out=$(cd "$dir" && env "${vars[@]/%/=dummy}" docker compose config --quiet 2>&1); then
ok=1
break
fi
missing=$(grep -oE 'required variable [A-Za-z0-9_]+' <<<"$out" | awk '{print $3}' | sort -u | grep -vxFf <(printf '%s\n' "${vars[@]}") || true)
if [ -z "$missing" ]; then
echo "::error file=${dir}compose.yaml::docker compose config failed in ${dir}"
echo "$out"
status=1
ok=2
break
fi
vars+=($missing)
done
if [ "$ok" = 0 ]; then
echo "::error file=${dir}compose.yaml::too many required variables in ${dir}"
status=1
fi
done
exit $status
17 changes: 12 additions & 5 deletions .github/workflows/linting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ on:
branches:
- main
paths-ignore:
- '.github/**'
# - 'README.md'
- 'LICENSE'
- '.gitignore'
Expand All @@ -15,23 +14,31 @@ on:
branches:
- main
paths-ignore:
- '.github/**'
# - 'README.md'
- 'LICENSE'
- '.gitignore'
- '.gitattributes'
- '.editorconfig'

permissions:
contents: read

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Clone this repo
uses: actions/checkout@v7
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Lint Markdown
uses: rvben/rumdl@v0.2.73
uses: rvben/rumdl@9c4cc2a2ebe176de68e1788106e25af8a9bd3899 # v0.2.78
with:
version: "0.2.78" # Keep in line with the pinned action above
path: "."
config: ".markdownlint.yml"
report-type: annotations
6 changes: 6 additions & 0 deletions services/adguardhome-sync/.env
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,10 @@ TZ=Europe/Amsterdam # See: https://en.wikipedia.org/wiki/List_of_tz_database_tim
# Optional Service variables
# PUID=1000

# AdGuard Home Sync Configuration
# Required: password of the AdGuard Home instance to copy from.
ORIGIN_PASSWORD=
# Required: password of the AdGuard Home instance to copy to.
REPLICA1_PASSWORD=

#EXAMPLE_VAR="Environment variable"
14 changes: 11 additions & 3 deletions services/adguardhome-sync/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,21 @@ This stack runs AdGuard Home Sync with a Tailscale sidecar, as described in [the

Replace the sample values in the `environment` block of `compose.yaml`:

- **`ORIGIN_URL`, `ORIGIN_USERNAME`, `ORIGIN_PASSWORD`.** The AdGuard Home instance to copy from.
- **`REPLICA1_URL`, `REPLICA1_USERNAME`, `REPLICA1_PASSWORD`.** The instance to copy to.
- **`ORIGIN_URL` and `ORIGIN_USERNAME`.** The AdGuard Home instance to copy from.
- **`REPLICA1_URL` and `REPLICA1_USERNAME`.** The instance to copy to.
- **`CRON`.** The schedule. The sample value runs a sync every minute.

Set the passwords in `.env`:

- **`ORIGIN_PASSWORD` and `REPLICA1_PASSWORD`.** The passwords of the two instances. Compose stops with an error if one of them is empty.

To reach an AdGuard Home instance on your Tailnet, see the [DNS section of the standard setup](../../documentation/standard-setup.md#dns).

## Deviations from the standard setup

- **No Tailscale Serve.** The stack has no Serve configuration. The tool only makes outgoing connections to your AdGuard Home instances.
- **Start command.** The stack starts the tool with the `run` command.
- **No data folder.** The tool stores nothing on disk. All settings are in `compose.yaml`.
- **No data folder.** The tool stores nothing on disk. The settings are in `compose.yaml`, and the passwords are in `.env`.

## First run

Expand All @@ -37,6 +41,10 @@ Check the log to see whether the sync works:
docker logs app-adguardhome-sync
```

## Upgrading

Earlier versions of this stack had the sample value `password` for `ORIGIN_PASSWORD` and `REPLICA1_PASSWORD` in `compose.yaml`. The passwords are now in `.env`. They are empty, and Compose stops with an error until you set them. If you already run the stack, move your passwords from `compose.yaml` to `.env`.

## Links

- [AdGuard Home Sync documentation and source code](https://github.com/bakito/adguardhome-sync)
4 changes: 2 additions & 2 deletions services/adguardhome-sync/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@ services:
# Origin AdGuardHome
- ORIGIN_URL=http://192.168.1.1:3000 #Your origin Adguard Home instance -> change as necessary
- ORIGIN_USERNAME=username #change as necessary
- ORIGIN_PASSWORD=password #change as necessary
- ORIGIN_PASSWORD=${ORIGIN_PASSWORD:?Set ORIGIN_PASSWORD in .env}

# First replication target
- REPLICA1_URL=http://192.168.1.2 #Your destination Adguard Home instance change as necessary
- REPLICA1_USERNAME=dbtech #change as necessary
- REPLICA1_PASSWORD=password #change as necessary
- REPLICA1_PASSWORD=${REPLICA1_PASSWORD:?Set REPLICA1_PASSWORD in .env}

# Second replication target (optional)
#- REPLICA2_URL=http://192.168.1.3 #change as necessary
Expand Down
3 changes: 2 additions & 1 deletion services/affine/.env
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ AFFINE_SERVER_EXTERNAL_URL=https://affine.<YOUR_TS_DOMAIN>.ts.net

# database credentials
DB_USERNAME=affine
DB_PASSWORD=affine
# Required: password of the database. Use letters and digits only, because the database address contains it.
DB_PASSWORD=
DB_DATABASE=affine
6 changes: 5 additions & 1 deletion services/affine/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ This stack runs AFFiNE with a Tailscale sidecar, as described in [the standard s
Set these values in `.env`:

- **`AFFINE_SERVER_EXTERNAL_URL`.** The address of the web interface, `https://affine.<tailnet>.ts.net`. AFFiNE does not start with the sample value, because the `affine_migration` container fails.
- **`DB_PASSWORD`.** The password of the database. The default is `affine`.
- **`DB_PASSWORD`.** The password of the database. Use letters and digits only, because the database address contains it. It is empty, and Compose stops with an error until you set it.

## Deviations from the standard setup

Expand All @@ -35,6 +35,10 @@ Set these values in `.env`:

Open the web interface. AFFiNE sends you to its setup page, where you create the administrator account.

## Upgrading

Earlier versions of this stack had a sample value for `DB_PASSWORD` in `.env`. It is now empty, and Compose stops with an error until you set it. If you already run the stack, keep the values that you use now. This is required for the database password, because the database applies it only at the first start. If you kept the sample value, set `DB_PASSWORD=affine` again. The database still uses it.

## Links

- [AFFiNE self-hosting documentation](https://docs.affine.pro/self-host-affine)
Expand Down
9 changes: 3 additions & 6 deletions services/affine/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ services:
environment:
# Variables are declared in .env file.
- REDIS_SERVER_HOST=redis
- DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD}@postgres:5432/${DB_DATABASE:-affine}
- DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD:?Set DB_PASSWORD in .env}@postgres:5432/${DB_DATABASE:-affine}
- AFFINE_INDEXER_ENABLED=false
#- EXAMPLE_VAR=${EXAMPLE_VAR}
healthcheck:
Expand All @@ -95,7 +95,7 @@ services:
environment:
# Variables are declared in .env file.
- REDIS_SERVER_HOST=redis
- DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD}@postgres:5432/${DB_DATABASE:-affine}
- DATABASE_URL=postgresql://${DB_USERNAME}:${DB_PASSWORD:?Set DB_PASSWORD in .env}@postgres:5432/${DB_DATABASE:-affine}
- AFFINE_INDEXER_ENABLED=false
#- EXAMPLE_VAR=${EXAMPLE_VAR}
depends_on:
Expand All @@ -122,12 +122,9 @@ services:
environment:
# Variables are declared in .env file.
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_PASSWORD: ${DB_PASSWORD:?Set DB_PASSWORD in .env}
POSTGRES_DB: ${DB_DATABASE:-affine}
POSTGRES_INITDB_ARGS: '--data-checksums'
# you better set a password for you database
# or you may add 'POSTGRES_HOST_AUTH_METHOD=trust' to ignore postgres security policy
POSTGRES_HOST_AUTH_METHOD: trust
#- EXAMPLE_VAR=${EXAMPLE_VAR}
healthcheck:
test: [ 'CMD', 'pg_isready', '-h', '127.0.0.1', '-U', "${DB_USERNAME}", '-d', "${DB_DATABASE:-affine}" ] # Check if PostgreSQL accepts connections
Expand Down
9 changes: 6 additions & 3 deletions services/artisttrackarr/.env
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ TZ=Europe/Amsterdam # See: https://en.wikipedia.org/wiki/List_of_tz_database_tim
# Any Container environment variables are declared below. See https://docs.docker.com/compose/how-tos/environment-variables/

PUBLIC_URL=http://localhost:8080
SETUP_TOKEN=replace-with-at-least-32-random-characters
APP_ENCRYPTION_KEY=replace-with-at-least-32-random-characters
SESSION_SECRET=replace-with-at-least-32-random-characters
# Required: at least 32 characters. Generate it with: openssl rand -hex 32
SETUP_TOKEN=
# Required: at least 32 characters. Generate it with: openssl rand -hex 32
APP_ENCRYPTION_KEY=
# Required: at least 32 characters. Generate it with: openssl rand -hex 32
SESSION_SECRET=
MUSICBRAINZ_CONTACT=you@example.com
POLL_INTERVAL=6h
TRUST_PROXY=false
Expand Down
6 changes: 5 additions & 1 deletion services/artisttrackarr/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ This stack runs ArtistTrackarr with a Tailscale sidecar, as described in [the st

2. Set these values in `.env`:

- **`SETUP_TOKEN`, `APP_ENCRYPTION_KEY`, and `SESSION_SECRET`.** Three different random values of at least 32 characters each.
- **`SETUP_TOKEN`, `APP_ENCRYPTION_KEY`, and `SESSION_SECRET`.** Three different random values of at least 32 characters each. Generate each with `openssl rand -hex 32`.
- **`MUSICBRAINZ_CONTACT`.** A real email address or project address. ArtistTrackarr sends it to MusicBrainz with each request.
- **`PUBLIC_URL`.** The address of the web interface, `https://artist-trackarr.<tailnet>.ts.net`.

Expand All @@ -45,6 +45,10 @@ Open `https://artist-trackarr.<tailnet>.ts.net/setup`, enter the value of `SETUP
- **Client addresses.** Tailscale Serve is the reverse proxy of this stack. Set `TRUST_PROXY=true` in `.env` only if ArtistTrackarr should trust the client addresses that the proxy forwards.
- **Backups.** Stop the stack before you back up `./artist-trackarr-data`, so that the copy of the database is consistent.

## Upgrading

Earlier versions of this stack had sample values for `SETUP_TOKEN`, `APP_ENCRYPTION_KEY`, and `SESSION_SECRET` in `.env`. They are now empty, and ArtistTrackarr stops with `SETUP_TOKEN must be at least 32 characters` until you set them. If you already run the stack, keep the values that you use now. If you kept the sample value, set `APP_ENCRYPTION_KEY=replace-with-at-least-32-random-characters` again. A new key cannot decrypt the data that ArtistTrackarr stored with the old one.

## Links

- [ArtistTrackarr documentation and source code](https://github.com/crypt0rr/ArtistTrackarr)
Expand Down
2 changes: 1 addition & 1 deletion services/beszel-agent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Without a valid key, the `application` container keeps restarting.
## Deviations from the standard setup

- **No web interface.** The stack has no Tailscale Serve configuration and no `./config` folder. The hub connects to the agent on port `45876` of its Tailscale IP address.
- **Docker socket.** The agent mounts `/var/run/docker.sock` read-only to read the statistics of the containers on the Docker host.
- **Docker socket.** The agent mounts `/var/run/docker.sock` read-only to read the statistics of the containers on the Docker host. The `:ro` flag only makes the socket file read-only. It does not limit what the service can do through the Docker API, so treat access to the socket as root access to the Docker host.
- **No data folder.** The agent stores nothing on disk.

## First run
Expand Down
2 changes: 1 addition & 1 deletion services/beszel-agent/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ services:
PORT: 45876
KEY: "ssh-ed25519 <ADD-YOUR-beszel-agent-KEY-HERE>"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro # Read-only access to the docker.sock
- /var/run/docker.sock:/var/run/docker.sock:ro # The :ro flag does not limit Docker API access: the service can control Docker on the host
depends_on:
tailscale:
condition: service_healthy
Expand Down
2 changes: 1 addition & 1 deletion services/booklore/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This stack runs BookLore with a Tailscale sidecar, as described in [the standard

## Before you start

- **Set the database passwords.** `MYSQL_ROOT_PASSWORD` and `MYSQL_PASSWORD` in `.env` are empty. Give both a random value.
- **Set the database passwords.** `MYSQL_ROOT_PASSWORD` and `MYSQL_PASSWORD` in `.env` are empty. Give both a random value. Compose stops with an error until you set them.
- **Choose your book folder.** To use an existing collection, point the `/books1` volume in `compose.yaml` at your own folder. Otherwise the stack starts with an empty `./books` folder.

## Deviations from the standard setup
Expand Down
6 changes: 3 additions & 3 deletions services/booklore/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ services:
- PGID=1000
- DATABASE_URL=jdbc:mariadb://mariadb:3306/booklore # Only modify this if you're familiar with JDBC and your database setup
- DATABASE_USERNAME=${MYSQL_USER} # Must match MYSQL_USER defined in the mariadb container
- DATABASE_PASSWORD=${MYSQL_PASSWORD} # Use a strong password; must match MYSQL_PASSWORD defined in the mariadb container
- DATABASE_PASSWORD=${MYSQL_PASSWORD:?Set MYSQL_PASSWORD in .env} # Use a strong password; must match MYSQL_PASSWORD defined in the mariadb container
- SWAGGER_ENABLED=false # Swagger UI (API docs).
- TZ=${TZ}
volumes:
Expand All @@ -81,10 +81,10 @@ services:
environment:
- PUID=1000
- PGID=1000
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} # Use a strong password for the database's root user, should be different from MYSQL_PASSWORD
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD:?Set MYSQL_ROOT_PASSWORD in .env} # Use a strong password for the database's root user, should be different from MYSQL_PASSWORD
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_USER=${MYSQL_USER} # Must match DATABASE_USERNAME defined in the booklore container
- MYSQL_PASSWORD=${MYSQL_PASSWORD} # Use a strong password; must match DATABASE_PASSWORD defined in the booklore container
- MYSQL_PASSWORD=${MYSQL_PASSWORD:?Set MYSQL_PASSWORD in .env} # Use a strong password; must match DATABASE_PASSWORD defined in the booklore container
volumes:
- ./mariadb_config:/config
restart: always
Expand Down
3 changes: 2 additions & 1 deletion services/coder/.env
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ TZ=Europe/Amsterdam # See: https://en.wikipedia.org/wiki/List_of_tz_database_tim

CODER_VERSION=latest
POSTGRES_USER=username
POSTGRES_PASSWORD=strongpassword
# Required: password of the database. Use letters and digits only, because the database address contains it.
POSTGRES_PASSWORD=
POSTGRES_DB=coder
CODER_ACCESS_URL=https://coder.<YOUR-TAILSCALE-DOMAIN>.ts.net

Expand Down
8 changes: 6 additions & 2 deletions services/coder/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,22 @@ This stack runs Coder with a Tailscale sidecar, as described in [the standard se
2. Set these values in `.env`:

- **`CODER_ACCESS_URL`.** The address of the web interface, `https://coder.<tailnet>.ts.net`.
- **`POSTGRES_PASSWORD`.** The password of the database.
- **`POSTGRES_PASSWORD`.** The password of the database. Use letters and digits only, because the database address contains it. Compose stops with an error if it is empty.

## Deviations from the standard setup

- **Extra container.** The stack runs a `database` container with PostgreSQL. It uses the network of the `tailscale` container as well, so Coder reaches it at `localhost`. PostgreSQL therefore also listens on port `5432` of the Tailscale IP address of the device.
- **Docker socket.** Coder mounts `/var/run/docker.sock` read-only, so that templates can use Docker on the host.
- **Docker socket.** Coder mounts `/var/run/docker.sock` read-only, so that templates can use Docker on the host. The `:ro` flag only makes the socket file read-only. It does not limit what the service can do through the Docker API, so treat access to the socket as root access to the Docker host.
- **Image version.** `CODER_VERSION` in `.env` selects the version of the Coder image.

## First run

Open the web interface and create the first account, which becomes the administrator.

## Upgrading

Earlier versions of this stack had a sample value for `POSTGRES_PASSWORD` in `.env`. It is now empty, and Compose stops with an error until you set it. If you already run the stack, keep the values that you use now. This is required for the database password, because the database applies it only at the first start. If you kept the sample value, set `POSTGRES_PASSWORD=strongpassword` again. The database still uses it.

## Links

- [Coder documentation](https://coder.com/docs)
Expand Down
4 changes: 2 additions & 2 deletions services/coder/compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ services:
network_mode: service:tailscale # Sidecar configuration to route the service through Tailscale
container_name: app-${SERVICE} # Name for local container management
environment:
CODER_PG_CONNECTION_URL: "postgresql://${POSTGRES_USER:-username}:${POSTGRES_PASSWORD:-password}@localhost/${POSTGRES_DB:-coder}?sslmode=disable"
CODER_PG_CONNECTION_URL: "postgresql://${POSTGRES_USER:-username}:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env}@localhost/${POSTGRES_DB:-coder}?sslmode=disable"
CODER_HTTP_ADDRESS: "0.0.0.0:7080"
CODER_ACCESS_URL: "${CODER_ACCESS_URL}"
TZ: ${TZ}
Expand Down Expand Up @@ -81,7 +81,7 @@ services:
image: "postgres:17"
environment:
POSTGRES_USER: ${POSTGRES_USER:-username} # The PostgreSQL user (useful to connect to the database)
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password} # The PostgreSQL password (useful to connect to the database)
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD in .env} # The PostgreSQL password (useful to connect to the database)
POSTGRES_DB: ${POSTGRES_DB:-coder} # The PostgreSQL default database (automatically created at first launch)
volumes:
- ./${SERVICE}-data/coder-data:/var/lib/postgresql/data # Use "docker volume rm coder_coder_data" to reset Coder
Expand Down
2 changes: 1 addition & 1 deletion services/dozzle/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Nothing beyond the [Quick Start](../../README.md#quick-start).

## Deviations from the standard setup

- **Docker socket.** Dozzle mounts `/var/run/docker.sock` read-only to read the logs of all containers on the Docker host.
- **Docker socket.** Dozzle mounts `/var/run/docker.sock` read-only to read the logs of all containers on the Docker host. The `:ro` flag only makes the socket file read-only. It does not limit what the service can do through the Docker API, so treat access to the socket as root access to the Docker host.

## First run

Expand Down
Loading
Loading