Example: a database

Postgres with a named volume, a password from vars set, and a web UI.


Postgres keeps its data in a named volume, which lasts across deploys. Its password comes from an environment variable, so it stays out of the repository. Adminer, a web UI for databases, is the only service routed to the internet; it reaches Postgres by its service name, db, on the project's default network.

Files #

compose.yaml

 1services:
 2  adminer:
 3    image: adminer
 4    environment:
 5      ADMINER_DEFAULT_SERVER: db
 6    labels:
 7      - traefik.enable=true
 8      - traefik.docker.network=picd-ingress
 9      - traefik.http.routers.adminer.rule=Host(`db-alice.user.cd.pico.sh`)
10    networks: [default, picd-ingress]
11  db:
12    image: postgres:17
13    environment:
14      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set it with vars set}
15    volumes:
16      - data:/var/lib/postgresql/data
17volumes:
18  data:
19networks:
20  picd-ingress:
21    external: true

adminer is on both networks: picd-ingress for Traefik, and default to reach db. traefik.docker.network tells Traefik which of them to use.

Deploy #

Set the password first, which creates the project, then push:

1ssh cd.pico.sh vars set db POSTGRES_PASSWORD="$(openssl rand -hex 16)"
2git init -b main && git add . && git commit -m init
3git push ssh://cd.pico.sh/db.git main

Sign in at https://db-alice.user.cd.pico.sh as postgres, with the password. Adminer is open to anyone who knows it, so take the project down when you're done:

1ssh cd.pico.sh down db

down keeps the volume, so the data is there when you redeploy.

<< PREV
Build an image