Installation
Kinkeep ships as a single container that bundles the Phoenix application. The only external dependency is a PostgreSQL database. The easiest way to run both is with Podman Compose (or Docker Compose).
Requirements
- Podman ≥ 4.0 with
podman-compose, or Docker with the Compose v2 plugin. - Any Linux host (or macOS / Windows with Podman Desktop).
1. Get the compose file
Download the compose.yml from the repository, or create it manually:
services:
db:
image: docker.io/library/postgres:16-alpine
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/jlopezcur/kinkeep: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}
volumes:
- uploads:/uploads
depends_on:
db:
condition: service_healthy
volumes:
db_data:
uploads:
2. Configure environment variables
Create a .env file next to compose.yml:
SECRET_KEY_BASE=put_a_secret_key_of_at_least_64_characters_here
POSTGRES_PASSWORD=a_secure_password
PHX_HOST=localhost
Generate a secure value for SECRET_KEY_BASE:
openssl rand -base64 48
:::tip Setting PHX_HOST
If you plan to expose Kinkeep on a public domain, set PHX_HOST to that domain (e.g. kinkeep.example.org). This is used to build absolute URLs inside the application.
:::
3. Start the application
# With Podman
podman compose up -d
# With Docker
docker compose up -d
The first run will pull the image, create the database schema, and start all services. This may take a couple of minutes.
4. Create the first user
Open http://localhost:4000 in your browser.
If the database is empty, Kinkeep automatically redirects to /setup where you can create the administrator account and the first organisation.
Common operations
# Stream application logs
podman compose logs -f app
# Open an IEx console inside the running container
podman compose exec app /app/bin/kinkeep remote
# Run pending migrations manually
podman compose exec app /app/bin/kinkeep eval 'Kinkeep.Release.migrate()'
# Stop all services
podman compose down
# Stop and remove all data volumes (⚠ irreversible)
podman compose down -v
Updating
podman compose pull app
podman compose up -d
Kinkeep runs any pending database migrations automatically on every startup, so no manual migration step is required after an update.