Skip to main content

Docker install and server users/groups

Ubuntu Server 24.04 — what to install for Docker, and how gqc, apisvc, and the docker group relate.

Users and groups (summary)

Account / groupPurposeGroups to joinDo not
gqcSSH login, git clone/git pull, manual deploys, Docker debuggingapisvc, dockerRun production API as this user
apisvcOwns app files; native mode runs gunicorn via systemd(none required)Login shell, Git, docker group
dockerWho may run docker without sudoAdd gqc onlyAdd apisvc — not needed and expands attack surface
gqc ──member of──► apisvc group  → write /opt/apis for git
gqc ──member of──► docker group → docker build / logs without sudo

apisvc ──owns──► /opt/apis/<api-name>/ (after chown)
apisvc ──reads──► /etc/<api-name>/*.env (group on file, mode 640)

systemd (root) ──runs──► docker compose up (boot / restart)
container ──runs as──► appuser (inside image, not apisvc)

You do not need a separate “docker user”. Docker creates a docker group for the daemon socket (/var/run/docker.sock). Add admin login accounts to that group.


gqc + apisvc group (Git and /opt/apis)

Login users cannot write to /opt/apis unless they are in the apisvc group and /opt/apis is mode 775.

# One-time — run with sudo
DEPLOY_USER=gqc

sudo usermod -aG apisvc "${DEPLOY_USER}"

sudo mkdir -p /opt/apis /opt/venvs
sudo chown root:apisvc /opt/apis /opt/venvs
sudo chmod 775 /opt/apis /opt/venvs

Log out and SSH back in as gqc, then verify:

groups
# must include apisvc

touch /opt/apis/.write-test && rm /opt/apis/.write-test
# should succeed

After every git clone or git pull:

API=dwd-api-fastapi
sudo chown -R apisvc:apisvc /opt/apis/${API}
sudo chmod -R g+rwX /opt/apis/${API}

Do not use sudo git clone — that creates root-owned files and breaks the ownership model.


gqc + docker group (optional but convenient)

When Docker is installed, gqc can be added to the docker group so manual commands work without sudo:

sudo usermod -aG docker gqc

Log out and back in, then:

docker ps
docker compose version

Security note: membership in docker is effectively root-equivalent. Only add trusted admin accounts (gqc), not service accounts.

Production API startup uses systemd running as root, which calls docker compose — that does not require gqc or apisvc to be in the docker group for the service to start on boot.


apisvc — what it does and does not need

Modeapisvc role
Native (venv + gunicorn)systemd User=apisvc; process runs as apisvc
DockerOwns git checkout under /opt/apis/; containers run as appuser inside the image; systemd starts Docker as root

apisvc does not need:

  • docker group membership
  • SSH / deploy keys
  • A login shell

Secrets in /etc/<api-name>/<api-name>.env are root:apisvc mode 640 — readable by group apisvc for native units; Docker compose uses env_file: and the daemon reads them as root when starting the container.


Install Docker on Ubuntu 24.04

Use Ubuntu’s packages (simple, supported, enough for this server):

sudo apt update
sudo apt install -y docker.io docker-compose-v2

sudo systemctl enable docker
sudo systemctl start docker
sudo systemctl status docker --no-pager

Add admin user to docker group:

sudo usermod -aG docker gqc

Log out and SSH back in as gqc, then verify:

docker --version
docker compose version

docker run --rm hello-world

Expected: “Hello from Docker!”

What gets installed

PackageProvides
docker.ioDocker engine, docker CLI, docker.service
docker-compose-v2docker compose (Compose plugin)

You do not need a separate docker-compose v1 binary, Podman, or Docker Desktop on the server.

Optional: Docker CE from Docker Inc.

Only if you need newer engine features than Ubuntu’s package:

# Official convenience script — use only if you intentionally want Docker CE
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker gqc

For this API host, apt install docker.io docker-compose-v2 is the recommended default.


Copy-paste: full one-time server prep

Run on the Ubuntu server (adjust DEPLOY_USER if not gqc):

DEPLOY_USER=gqc

# Service account
sudo useradd --system --home-dir /var/lib/apisvc --create-home \
--shell /usr/sbin/nologin apisvc 2>/dev/null || true

# /opt layout — 775 so apisvc group members can git clone
sudo mkdir -p /opt/apis /opt/venvs
sudo chown root:apisvc /opt/apis /opt/venvs
sudo chmod 775 /opt/apis /opt/venvs

# Deploy user → apisvc group (git)
sudo usermod -aG apisvc "${DEPLOY_USER}"

# Docker
sudo apt update
sudo apt install -y docker.io docker-compose-v2
sudo systemctl enable --now docker
sudo usermod -aG docker "${DEPLOY_USER}"

echo "Log out and SSH back in as ${DEPLOY_USER}, then run: groups"

After re-login, groups should include apisvc and docker.


Checklist

  • gqc in group apisvc; /opt/apis is root:apisvc mode 775
  • Re-logged in after usermod
  • docker.io and docker-compose-v2 installed; docker service enabled
  • gqc in group docker (optional for manual ops; not required for systemd-managed compose)
  • apisvc not in group docker
  • After git operations: chown -R apisvc:apisvc /opt/apis/<api-name>