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:
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:
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