Skip to main content
Docker Compose is the supported way to self-host PostQueen. One file describes her and the three services she depends on, and one command starts all of them. This page is the reference for that file: what it starts, where settings live, and how to change them. If you want to be walked through an install instead, use Try her locally or Deploy to a server.

What the stack contains

docker compose up -d starts eight containers. You do not install PostgreSQL, Redis or Temporal separately, they come with it. Only postqueen is published to your whole machine. Temporal’s two ports are bound to 127.0.0.1, so they are reachable from the server itself and not from the network.
Clone the repository rather than copying the YAML out of this page. The repository also carries a dynamicconfig folder that Temporal mounts at startup, and the file changes between releases.

Where configuration lives

Everything is configured with environment variables, and they ship inline in docker-compose.yaml. Open the file, find the environment: block on the postqueen service, and edit values in place:
That is the default and it is all most people need. Note the YAML style: KEY: 'value' with a colon, not KEY=value.
Dropping a .env file next to docker-compose.yaml does nothing on its own. Compose reads such a file only to substitute ${VARIABLE} placeholders inside the YAML, and this file contains no placeholders. The variables are never passed to the container. This catches people out regularly, because it is genuinely how Compose behaves elsewhere.

Using a file instead

If you would rather keep secrets out of the YAML, add an env_file: key yourself. Compose then does pass that file’s contents to the container:
Note the syntax difference. Inside docker-compose.yaml it is KEY: 'value'. Inside an env file it is KEY=value with no quotes needed.

Using both

You can, and the precedence matters:
environment: wins over env_file:. If the same variable appears in both, the value in the YAML is the one the container gets. Since the shipped file already pins many variables to literal values, including empty ones, a variable you set only in your env file will be ignored if the YAML also mentions it. Either delete the line from the YAML or set your value there.

What does not work

The Compose file mounts a postqueen-config volume at /config. Nothing in the image reads it. A file placed there is never opened. Use environment: or an env_file: key as above.

Applying a change

docker compose restart is not enough. It reuses the existing container, which still carries the old environment. Changed settings need the container recreated, which is what down followed by up does. Your data lives in volumes and survives this.

The settings you are most likely to change

The full list of around 135 variables is in Configuration Reference. These are the ones that matter for almost every install. Two that people change and should not: BACKEND_INTERNAL_URL stays http://localhost:3000, because it describes a hop inside the container rather than a public address. DATABASE_URL and REDIS_URL already point at the bundled containers by service name and only need editing if you bring your own database.
RUN_CRON and IS_GENERAL cannot be turned off by setting them to false. They are tested for presence, not value, so the string false still counts as on. Leave them as they ship.

Checking your configuration took effect

She inspects her own settings at the end of startup and reports anything questionable, then carries on running anyway. A container that is up is not proof that the configuration is sound, so it is worth looking:
Empty output is good news. Anything listed there names the variable it is unhappy about, commonly a trailing slash or a missing URL.

Pinning a version

The file ships with image: ghcr.io/gkhankinay/postqueen-app:latest. On a real install, change latest to a specific version from the releases page:
This matters more than usual here. She reconciles her database schema on every boot, so an unattended image change is also an unattended schema change. Backups and Upgrades explains what that means and how to switch to migrations instead.

Next Steps