Install with PostgreSQL Docker Compose
Use this install method if you want:
- PostgreSQL from the start
- separate app and database storage directories
- a Docker Compose setup that is still easy to run locally
Before you begin
You need:
- Docker Engine with the
docker composecommand available - a free local port for Tarnished,
5577by default curlor another way to save the compose file locally- a strong PostgreSQL password for the
.envfile
Quick install
Create a directory for Tarnished, download the PostgreSQL compose file as docker-compose.yml, create .env, and start the stack:
mkdir tarnished
cd tarnished
curl -fsSLo docker-compose.yml https://raw.githubusercontent.com/markoonakic/tarnished/main/deploy/compose/docker-compose.postgres.yml
cat > .env <<'EOF'
POSTGRES_PASSWORD=replace-with-a-strong-password
APP_PORT=5577
APP_URL=http://localhost:5577
EOF
docker compose up -d
The compose file used in this guide
Save this as docker-compose.yml:
services:
app:
image: ${TARNISHED_IMAGE:-ghcr.io/markoonakic/tarnished:latest}
ports:
- "${APP_PORT:-5577}:5577"
volumes:
- ./data:/app/data
environment:
- POSTGRES_HOST=db
- POSTGRES_PORT=5432
- POSTGRES_USER=tarnished
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
- POSTGRES_DB=tarnished
- APP_URL=${APP_URL:-http://localhost:5577}
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:16-alpine
volumes:
- ./postgres_data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=tarnished
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:?POSTGRES_PASSWORD is required}
- POSTGRES_DB=tarnished
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
interval: 5s
timeout: 5s
start_period: 10s
retries: 5
restart: unless-stopped
The .env file used in this guide
Save this as .env next to docker-compose.yml:
POSTGRES_PASSWORD=replace-with-a-strong-password
APP_PORT=5577
APP_URL=http://localhost:5577
Verify the install
Check that both services are running:
docker compose ps
Then confirm Tarnished responds:
curl http://localhost:5577/health
Expected response:
{"status":"healthy"}
Open Tarnished
Open Tarnished in your browser:
http://localhost:5577
The first account created in a fresh Tarnished instance becomes the administrator.
Where your data lives
In this install mode:
- Tarnished app data and uploaded files are stored under
./data - PostgreSQL data is stored under
./postgres_data
Back up both directories if you want to preserve the instance.
Common adjustments
Change the exposed port
Update .env and restart the stack:
APP_PORT=8080
APP_URL=http://localhost:8080
Pin a specific Tarnished version
Add this to .env:
TARNISHED_IMAGE=ghcr.io/markoonakic/tarnished:0.1.7
Troubleshooting
If the stack does not come up cleanly:
docker compose logs app
docker compose logs db
docker compose logs -f db
Then continue with Deployment and startup problems.
Next step
Continue with Create your admin account.