Lewati ke konten

Memasang Repovio

Contoh Docker Compose dengan akun lokal atau tumpukan Authentik OIDC lengkap.

Memasang Repovio

Pilih satu contoh untuk instalasi baru. Diperlukan Docker Engine, Compose v2, DNS publik dan reverse proxy TLS. Gunakan nama HTTPS terpisah untuk Repovio dan Authentik. Image privat memerlukan akses GHCR. Instalasi lama mengikuti panduan penerapan dan pembaruan PostgreSQL sesuai versi; jangan gunakan volume PostgreSQL lama pada contoh ini.

Konfigurasi bersama

Simpan YAML sebagai compose.yml dan nilai berikut sebagai .env di direktori privat. Ganti semua penanda dan gunakan tag rilis Repovio yang sama persis untuk kedua image. Buat sandi basis data dan rahasia JWT secara terpisah dengan perintah pertama, kunci enkripsi dengan perintah kedua. Sandi heksadesimal menghindari kesalahan pengodean URL.

openssl rand -hex 32
openssl rand -base64 32
REPOVIO_VERSION=REPLACE_WITH_EXACT_RELEASE_TAG
POSTGRES_PASSWORD=REPLACE_WITH_RANDOM_HEX_PASSWORD
AUTH_JWT_SECRET=REPLACE_WITH_RANDOM_HEX_SECRET
TOKEN_ENCRYPTION_KEY=REPLACE_WITH_BASE64_32_BYTE_KEY

Tanpa OIDC

Tumpukan memakai akun lokal. Selesaikan penyiapan awal untuk membuat administrator pertama. Biarkan OIDC nonaktif; buat akun tambahan di Administrasi → Pengguna.

services:
  postgres:
    image: postgres:18-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: repovio
      POSTGRES_USER: repovio
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD}
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U repovio -d repovio']
      interval: 5s
      timeout: 5s
      retries: 12
    volumes:
      - repovio-postgres:/var/lib/postgresql
  migrate:
    image: ghcr.io/repovio/repovio-api:${REPOVIO_VERSION:?Set an exact release version}
    restart: 'no'
    command: ['node_modules/.bin/prisma', 'migrate', 'deploy', '--config', 'prisma.config.ts']
    environment: &api-environment
      NODE_ENV: production
      PORT: 3001
      DATABASE_URL: postgresql://repovio:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD}@postgres:5432/repovio?schema=public
      SHADOW_DATABASE_URL:
        postgresql://repovio:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD}@postgres:5432/repovio_shadow?schema=public
      AUTH_JWT_SECRET: ${AUTH_JWT_SECRET:?Set AUTH_JWT_SECRET}
      TOKEN_ENCRYPTION_KEY: ${TOKEN_ENCRYPTION_KEY:?Set TOKEN_ENCRYPTION_KEY}
      PUBLIC_URL: https://repovio.example.com
      CORS_ORIGIN: https://repovio.example.com
    depends_on:
      postgres:
        condition: service_healthy
  api:
    image: ghcr.io/repovio/repovio-api:${REPOVIO_VERSION:?Set an exact release version}
    restart: unless-stopped
    environment: *api-environment
    depends_on:
      migrate:
        condition: service_completed_successfully
    ports:
      - '127.0.0.1:3001:3001'
  web:
    image: ghcr.io/repovio/repovio-web:${REPOVIO_VERSION:?Set an exact release version}
    restart: unless-stopped
    environment:
      PORT: 3000
      NUXT_PUBLIC_API_BASE_URL: https://repovio.example.com/api/v1
    depends_on:
      api:
        condition: service_healthy
    ports:
      - '127.0.0.1:3000:3000'
volumes:
  repovio-postgres:

Dengan Authentik

Gunakan alternatif lengkap ini, jangan jalankan kedua contoh bersamaan. Tambahkan nilai berikut ke .env dan buat sandi basis data serta kunci rahasia terpisah. Versi Authentik yang dikunci memakai PostgreSQL sendiri, server dan worker; contoh OIDC ini tidak memerlukan Redis atau soket Docker.

AUTHENTIK_POSTGRES_PASSWORD=REPLACE_WITH_SEPARATE_RANDOM_HEX_PASSWORD
AUTHENTIK_SECRET_KEY=REPLACE_WITH_RANDOM_HEX_SECRET
services:
  postgres:
    image: postgres:18-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: repovio
      POSTGRES_USER: repovio
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD}
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U repovio -d repovio']
      interval: 5s
      timeout: 5s
      retries: 12
    volumes:
      - repovio-postgres:/var/lib/postgresql
  migrate:
    image: ghcr.io/repovio/repovio-api:${REPOVIO_VERSION:?Set an exact release version}
    restart: 'no'
    command: ['node_modules/.bin/prisma', 'migrate', 'deploy', '--config', 'prisma.config.ts']
    environment: &api-environment
      NODE_ENV: production
      PORT: 3001
      DATABASE_URL: postgresql://repovio:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD}@postgres:5432/repovio?schema=public
      SHADOW_DATABASE_URL:
        postgresql://repovio:${POSTGRES_PASSWORD:?Set POSTGRES_PASSWORD}@postgres:5432/repovio_shadow?schema=public
      AUTH_JWT_SECRET: ${AUTH_JWT_SECRET:?Set AUTH_JWT_SECRET}
      TOKEN_ENCRYPTION_KEY: ${TOKEN_ENCRYPTION_KEY:?Set TOKEN_ENCRYPTION_KEY}
      PUBLIC_URL: https://repovio.example.com
      CORS_ORIGIN: https://repovio.example.com
      OIDC_CALLBACK_URL: https://repovio.example.com/api/v1/auth/oidc/callback
    depends_on:
      postgres:
        condition: service_healthy
  api:
    image: ghcr.io/repovio/repovio-api:${REPOVIO_VERSION:?Set an exact release version}
    restart: unless-stopped
    environment: *api-environment
    depends_on:
      migrate:
        condition: service_completed_successfully
    ports:
      - '127.0.0.1:3001:3001'
  web:
    image: ghcr.io/repovio/repovio-web:${REPOVIO_VERSION:?Set an exact release version}
    restart: unless-stopped
    environment:
      PORT: 3000
      NUXT_PUBLIC_API_BASE_URL: https://repovio.example.com/api/v1
    depends_on:
      api:
        condition: service_healthy
    ports:
      - '127.0.0.1:3000:3000'
  authentik-postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: authentik
      POSTGRES_USER: authentik
      POSTGRES_PASSWORD: ${AUTHENTIK_POSTGRES_PASSWORD:?Set AUTHENTIK_POSTGRES_PASSWORD}
    healthcheck:
      test: ['CMD-SHELL', 'pg_isready -U authentik -d authentik']
      interval: 5s
      timeout: 5s
      retries: 12
    volumes:
      - authentik-postgres:/var/lib/postgresql/data
  authentik-server:
    image: ghcr.io/goauthentik/server:2026.8.5
    command: server
    restart: unless-stopped
    shm_size: 512mb
    environment: &authentik-environment
      AUTHENTIK_POSTGRESQL__HOST: authentik-postgres
      AUTHENTIK_POSTGRESQL__NAME: authentik
      AUTHENTIK_POSTGRESQL__USER: authentik
      AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_POSTGRES_PASSWORD:?Set AUTHENTIK_POSTGRES_PASSWORD}
      AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?Set AUTHENTIK_SECRET_KEY}
    depends_on:
      authentik-postgres:
        condition: service_healthy
    ports:
      - '127.0.0.1:9000:9000'
    healthcheck:
      test: ['CMD', 'ak', 'healthcheck']
      interval: 30s
      timeout: 10s
      retries: 10
      start_period: 90s
    volumes:
      - authentik-data:/data
      - authentik-templates:/templates
  authentik-worker:
    image: ghcr.io/goauthentik/server:2026.8.5
    command: worker
    restart: unless-stopped
    shm_size: 512mb
    environment: *authentik-environment
    depends_on:
      authentik-postgres:
        condition: service_healthy
    healthcheck:
      test: ['CMD', 'ak', 'healthcheck']
      interval: 30s
      timeout: 10s
      retries: 10
      start_period: 90s
    volumes:
      - authentik-data:/data
      - authentik-templates:/templates
volumes:
  repovio-postgres:
  authentik-postgres:
  authentik-data:
  authentik-templates:

Proxy dan mulai

Ganti domain contoh dalam YAML, variabel dan proxy. Proxy berjalan di host Docker; kedua nama memerlukan sertifikat TLS valid. Proxy dalam kontainer memakai jaringan Docker bersama, bukan loopback sendiri. Jangan publikasikan port basis data.

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
}
auth.example.com {
  reverse_proxy 127.0.0.1:9000
}

Mengatur OIDC

Buka Authentik dan siapkan akadmin. Buat aplikasi/provider OAuth2/OpenID dengan slug repovio, klien rahasia, alur kode otorisasi, kunci tanda tangan, issuer per provider dan redirect URI ketat berikut. Sertakan openid, profile dan email; profile harus mengembalikan nama grup pada groups.

Issuer: https://auth.example.com/application/o/repovio/
Discovery: https://auth.example.com/application/o/repovio/.well-known/openid-configuration
Redirect URI: https://repovio.example.com/api/v1/auth/oidc/callback

Masuk ke Repovio sebagai administrator lokal. Dalam Pengaturan → Autentikasi masukkan issuer, ID dan rahasia klien, pilih groups dan cakupan openid profile email. Buat repovio-admins, repovio-managers dan repovio-viewers di Authentik lalu petakan peran. Uji, aktifkan OIDC dan periksa akun nonadministrator serta akun tanpa pemetaan. Konfigurasi disimpan di Repovio, bukan variabel OIDC rekaan. Login lokal tetap tersedia untuk pemulihan.

Grup OIDC hanya menentukan peran global. Grup akses lokal dan penetapan langsung memberi akses repositori secara terpisah; pengelola juga memerlukan penetapan Manager. Tidak ada sinkronisasi grup OIDC.

Verifikasi dan pembaruan

Validasi tanpa menampilkan rahasia lalu mulai. Periksa migrasi, kesehatan API dan web; pada contoh kedua periksa juga Authentik dan login OIDC. Lindungi .env dan cadangkan kedua basis data serta volume Authentik. Pertahankan nama volume yang sudah ada. Versi lama mengabaikan izin grup: rollback dapat menghilangkan akses turunan, tetapi penetapan langsung tetap berlaku.

chmod 600 .env
docker compose config --quiet
docker compose pull
docker compose up --detach --wait
docker compose logs migrate
curl --fail http://127.0.0.1:3001/api/health

Panduan lanjutan

Panduan lanjutan · Masuk · Repovio · OIDC

Panduan lanjutan: Authentik Compose · Authentik OIDC

Panduan lanjutan