Skip to content

Deploying Repovio

Production deployment, TLS proxy, backup, restore, upgrade, and rollback guidance for Repovio.

Repovio's Compose stack starts PostgreSQL, applies Prisma migrations once, and then starts the API and web applications. It does not terminate TLS. Put the web and API services behind a reverse proxy that owns the public hostname and certificates.

Prerequisites

  • Docker Engine with Docker Compose v2.
  • A DNS record for the public hostname.
  • A reverse proxy that obtains and renews TLS certificates.
  • A private server directory readable only by deployment administrators.

The Compose stack persists PostgreSQL data, including normalized user profile pictures, in its named repovio-postgres volume. Do not delete this volume unless you intentionally want to remove all Repovio data.

First deployment

Step 1: Check out a released Repovio version and create the private environment file:

cp .env.example .env
chmod 600 .env

Step 2: Replace every placeholder in .env, especially POSTGRES_PASSWORD, both database URLs, AUTH_JWT_SECRET, and

TOKEN_ENCRYPTION_KEY. Generate the encryption key with:

openssl rand -base64 32

Step 3: Set the externally visible URLs. For a deployment at https://repovio.example.com, use:

PUBLIC_URL=https://repovio.example.com
OIDC_CALLBACK_URL=https://repovio.example.com/api/v1/auth/oidc/callback
CORS_ORIGIN=https://repovio.example.com
NUXT_PUBLIC_API_BASE_URL=https://repovio.example.com/api/v1
OAUTH_CALLBACK_URL=https://repovio.example.com/api/v1/provider-accounts/oauth/callback

Step 4: Bind the container ports to loopback when the reverse proxy runs on the same host:

REPOVIO_API_PORT=127.0.0.1:3001
REPOVIO_WEB_PORT=127.0.0.1:3000

Otherwise, restrict access to ports 3000 and 3001 with the host firewall. Never expose the PostgreSQL container.

Step 5: Set REPOVIO_VERSION in .env to an exact released image pair, then start the stack:

docker compose pull
docker compose up --detach --wait

Keep that value in .env so every later Compose command uses the same API and web version.

Step 6: Confirm the API health endpoint locally:

curl --fail http://127.0.0.1:3001/api/health

Step 7: Open the public Repovio URL and complete the one-time first-run setup to create the first

system administrator.

Reverse proxy and TLS

Proxy the public web origin to port 3000, and the API and Socket.IO paths to port 3001. For example, a Caddy site block can use:

repovio.example.com {
  reverse_proxy /api/* 127.0.0.1:3001
  reverse_proxy /socket.io/* 127.0.0.1:3001
  reverse_proxy /mcp 127.0.0.1:3001
  reverse_proxy 127.0.0.1:3000
}

The proxy must redirect HTTP to HTTPS, validate upstream connections according to its local policy, and preserve the public hostname. Configure OAuth providers with the same HTTPS callback URL set in OAUTH_CALLBACK_URL.

Upgrading

Migrating an earlier installation

Follow the branding upgrade before starting the renamed stack. Set REPOVIO_POSTGRES_VOLUME to the exact existing volume name. Preserve database credentials and the encryption key; no database copy or reset is required for branding.

Step 1: Create and verify a database backup before changing images.

Step 2: Set REPOVIO_VERSION to the exact release version in .env.

Step 3: Pull and apply the release:

docker compose pull
docker compose up --detach --wait

The migrate service applies pending Prisma migrations before the API starts. Inspect it after every update:

docker compose logs migrate

Step 4: Verify the health endpoint and the proxy-served dashboard before considering the update complete.

Database backup

Run backups from the deployment directory. This writes a PostgreSQL custom-format dump to the host without printing credentials or putting them in the command line:

mkdir -p backups
backup_file="backups/repovio-$(date +%F-%H%M%S).dump"
docker compose exec -T postgres sh -c 'pg_dump -U "$POSTGRES_USER" -Fc "$POSTGRES_DB"' \
  > "$backup_file"
pg_restore --list "$backup_file"

Store encrypted copies off-host and periodically test restores on a separate system.

Database restore

Restoring replaces current database objects. Take a new backup first and schedule downtime.

docker compose stop api web
docker compose exec -T postgres sh -c 'pg_restore -U "$POSTGRES_USER" --clean --if-exists --no-owner -d "$POSTGRES_DB"' \
  < backups/repovio-YYYY-MM-DD-HHMMSS.dump
docker compose up --detach --wait

Afterward, check docker compose logs migrate and the API health endpoint. Restore a dump made by a compatible Repovio version when rolling back across schema changes.

Rollback

Step 1: Keep the backup made immediately before the failed upgrade.

Step 2: Set REPOVIO_VERSION in .env to the last known-good image version.

Step 3: Run docker compose pull and docker compose up --detach --wait.

Step 4: If the newer release migrated the database incompatibly, stop API and web, restore the compatible backup, and then

start the previous image version again.

Never use docker compose down --volumes as an update or rollback command: it removes the named PostgreSQL volume.