Configuration
All runtime configuration is environment variables. Where they are written
depends on how you deploy: /etc/kinkeep/kinkeep.env with
Quadlet, or the .env file beside your
compose file.
Environment variables
| Variable | Required | Default | What it does |
|---|---|---|---|
SECRET_KEY_BASE | yes | — | Signs cookies and tokens. At least 64 characters. Generate with openssl rand -base64 48. |
DATABASE_URL | yes | — | Ecto connection string, ecto://user:pass@host:5432/db. |
MEDIA_ROOT | yes | — | Directory photographs are written under. Must be a volume that outlives the container, and the application refuses to start without it. |
PHX_HOST | — | localhost | Public hostname. Used to build absolute URLs, and by Caddy as the site address it certifies. |
PORT | — | 4000 | Port the application listens on inside the container. |
POOL_SIZE | — | 10 | Database connections in the pool. Raise it only alongside PostgreSQL's max_connections. |
POSTGRES_USER | — | kinkeep | Read by the PostgreSQL container when it initialises. |
POSTGRES_PASSWORD | — | kinkeep | Same. Must match the password inside DATABASE_URL. |
POSTGRES_DB | — | kinkeep_prod | Same. |
ECTO_IPV6 | — | unset | Set to true to connect to the database over IPv6. |
:::warning Do not quote values
When the file is read by Podman as an --env-file, quotes become part of the
value: POSTGRES_PASSWORD="secret" sets the password to "secret", quotes
included, and authentication then fails in a way that is tedious to diagnose.
:::
:::tip Keep the password URL-safe
DATABASE_URL is a URL, so a password containing @, /, : or # breaks
it unless percent-encoded. Generating one with openssl rand -hex 24 sidesteps
the problem entirely.
:::
Persistent data
Two volumes, and both matter:
| Quadlet | Compose | Contents |
|---|---|---|
kinkeep-pgdata | db_data | The PostgreSQL data directory. |
kinkeep-uploads | uploads | Photos and logos uploaded by users. |
Kinkeep stores uploaded media on disk rather than in the database, so backing up the database alone leaves you with records pointing at missing images. See Operations.
:::danger Mount it where MEDIA_ROOT points
The volume and the variable have to name the same directory. If they do not,
the application writes inside its own container, everything looks right, and
every photograph disappears the next time the image is updated. This is
why MEDIA_ROOT has no default: an instance that would lose photographs
refuses to start instead.
:::
Behind a reverse proxy
The Quadlet units already include Caddy, so this only applies if you run your own proxy.
- Point
PHX_HOSTat the public domain. - Forward to port
4000on the container. - Pass
X-Forwarded-ForandX-Forwarded-Proto. Without the latter the application, which redirects to HTTPS in production, will redirect endlessly, because every request looks like plain HTTP to it.