Saltar al contenido principal

On one machine, with Compose

Compose is the quickest way to see Kinkeep running, and a reasonable way to run it on a machine you administer yourself. For a server that should survive a reboot and renew its own certificates, prefer Quadlet.

Before you start

  • Podman 4.0 or newer with podman-compose, or Docker with the Compose v2 plugin.
  • Any Linux host, or macOS and Windows through Podman Desktop.

The compose file

Take compose.yml from the repository, or write it yourself:

compose.yml
services:
db:
image: docker.io/library/postgres:17
restart: unless-stopped
environment:
POSTGRES_USER: kinkeep
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-kinkeep}
POSTGRES_DB: kinkeep_prod
volumes:
- db_data:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U kinkeep -d kinkeep_prod']
interval: 5s
timeout: 5s
retries: 10

app:
image: docker.io/kinkeep/api:latest
restart: unless-stopped
ports:
- '${PORT:-4000}:4000'
environment:
DATABASE_URL: 'ecto://kinkeep:${POSTGRES_PASSWORD:-kinkeep}@db/kinkeep_prod'
SECRET_KEY_BASE: ${SECRET_KEY_BASE}
PHX_HOST: ${PHX_HOST:-localhost}
PORT: 4000
POOL_SIZE: ${POOL_SIZE:-10}
# The same path the volume below is mounted at. Photographs written
# anywhere else go with the container the next time it is replaced.
MEDIA_ROOT: /app/priv/media
volumes:
- uploads:/app/priv/media
depends_on:
db:
condition: service_healthy

volumes:
db_data:
uploads:

Configure and start

Create a .env file next to it:

.env
SECRET_KEY_BASE=at_least_64_characters
POSTGRES_PASSWORD=a_secure_password
PHX_HOST=localhost

Generate the secret with openssl rand -base64 48. See Configuration for every variable.

podman compose up -d

The first run pulls the image, applies the migrations and starts both services. What is listening on port 4000 is the API, which serves JSON and nothing else, so there is no page to open. Create the first administrator as described in Operations.

:::note This stack has no web interface yet The client is its own container, and adding it here is scheduled work rather than something you are missing. Until then this is a usable API and not a usable application. :::

Everyday commands

# Follow the logs
podman compose logs -f app

# An IEx console inside the running container
podman compose exec app /app/bin/kinkeep remote

# Stop everything
podman compose down

# Stop and destroy the data as well (irreversible)
podman compose down -v