Dedicated database install (bring your own PostgreSQL)
This install runs only the Tagaris app container and points it at a PostgreSQL server you already run. Use it when you have a database server you would rather keep everything on, or a managed PostgreSQL service, and do not want another database to support or manage.
Tagaris installs three ways, and this is the dedicated-database one. The alternatives are the standard install, which brings its own PostgreSQL container, and a self-contained install, which puts the database inside the app container.
Requirements
- Docker and the Docker Compose plugin.
- A PostgreSQL server, version 16 recommended, reachable from the app container.
- A database and a role for Tagaris on that server. The role must own the database (or be able to create tables), so migrations can build the schema on first start.
Create them on your server, for example:
CREATE ROLE tagaris WITH LOGIN PASSWORD 'letters_and_digits_only';
CREATE DATABASE tagaris OWNER tagaris;
Use letters and digits only in the password: it is spliced into the connection URL, so
characters like : @ / break it.
Install with Docker Compose
1. Create a directory
mkdir -p /opt/tagaris && cd /opt/tagaris
2. Create docker-compose.yml
Save the following as docker-compose.yml. One service and two volumes for uploaded files;
its settings come from the .env file next to it. There is no database service, because
DATABASE_URL points at your server.
services:
app:
image: goodhallsolutions/tagaris:latest
restart: unless-stopped
environment:
DATABASE_URL: ${DATABASE_URL}
BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET}
BETTER_AUTH_URL: ${BETTER_AUTH_URL}
BETTER_AUTH_TRUSTED_ORIGINS: ${BETTER_AUTH_TRUSTED_ORIGINS:-}
API_ENABLED: ${API_ENABLED:-true}
SSO_ISSUER: ${SSO_ISSUER:-}
SSO_CLIENT_ID: ${SSO_CLIENT_ID:-}
SSO_CLIENT_SECRET: ${SSO_CLIENT_SECRET:-}
SSO_PROVIDER_NAME: ${SSO_PROVIDER_NAME:-}
NODE_ENV: production
UPLOADS_DIR: /app/uploads
PHOTOS_DIR: /app/data/photos
ports:
- "3000:3000"
volumes:
- uploads:/app/uploads
- photos:/app/data/photos
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:3000/api/health || exit 1"]
interval: 15s
timeout: 5s
retries: 5
start_period: 40s
volumes:
uploads:
photos:
This uses the official goodhallsolutions/tagaris image, the same as the standard install.
Only the database differs: there is no PostgreSQL container here.
The examples use the latest tag for simplicity. For anything beyond a trial, pin to a major
version such as goodhallsolutions/tagaris:2 so upgrades stay within version 2. See
Upgrading for tags, update steps and database upgrades.
3. Create .env
Save this as .env in the same directory, then set the connection string, the secret and the
URL.
# Point this at your PostgreSQL server, database and role.
# Letters and digits only in the password (it is spliced into the URL).
DATABASE_URL=postgresql://tagaris:letters_and_digits_only@db.example.internal:5432/tagaris?schema=public
# BETTER_AUTH_URL is the public address people reach the app on, not localhost.
# Generate the secret with: openssl rand -base64 32
BETTER_AUTH_SECRET=change_me_generate_with_openssl_rand_base64_32
BETTER_AUTH_URL=https://assets.example.com
BETTER_AUTH_TRUSTED_ORIGINS=
# Single sign-on is normally configured in the app; leave these blank.
SSO_ISSUER=
SSO_CLIENT_ID=
SSO_CLIENT_SECRET=
SSO_PROVIDER_NAME=
4. Start it
docker compose up -d
The app connects to your database, applies any pending migrations, then listens on port 3000.
5. Sign in
Open http://your-host:3000. The first visit opens the setup wizard, which creates your
organisation and the first administrator account. Give it a strong password and store it
safely: it is the install owner and the break-glass login.
6. Put it behind HTTPS
Serve Tagaris through a reverse proxy that terminates TLS (Cloudflare, nginx or Caddy), and
set BETTER_AUTH_URL to the https:// address. Session cookies and sign-in depend on it.
Install without Compose (plain docker run)
docker volume create tagaris_photos tagaris_uploads
docker run -d --name tagaris -p 3000:3000 \
-e DATABASE_URL="postgresql://tagaris:change_me@db.example.internal:5432/tagaris?schema=public" \
-e BETTER_AUTH_SECRET="a_long_random_secret" \
-e BETTER_AUTH_URL="http://your-host:3000" \
-v tagaris_photos:/app/data/photos -v tagaris_uploads:/app/uploads \
goodhallsolutions/tagaris:latest
Migrations run automatically at start, and the first visit opens the setup wizard.
Configuration
The variables match the standard install, with one difference:
DATABASE_URL points at your own server rather than a postgres container, and there are no
POSTGRES_USER, POSTGRES_PASSWORD or POSTGRES_DB values (those only configure the
database container the other installs run). See the standard install's configuration table
for the full reference.
Persistent storage
The database lives on your server and is yours to back up. The app container keeps uploaded files in two volumes:
photos(mounted at/app/data/photos): asset photos, thumbnails and attachments.uploads(mounted at/app/uploads): other uploaded files, including the backups folder.
Back these up alongside your database. Rebuilding or updating the image never touches the volumes.
The in-app scheduled backups (Application settings) still work here: they run pg_dump
against DATABASE_URL, so they capture your external database too. See Backups and
restore.
Troubleshooting
- Database connection error at start (Prisma error P1013): the password contains characters
that break the connection URL, such as
:@/. Use letters and digits only. - Cannot reach the database: check the app container can route to the server's host and port, and that the server accepts connections from the container's address.
- Migrations fail on first start with a permissions error: the role in
DATABASE_URLneeds rights to create tables. Make it the database owner.