# Deploying Veridian Self-hosted deployment guide using Docker Compose on a VPS. ## Prerequisites - A VPS with Docker and Docker Compose installed - A domain name pointed at your VPS IP address - An external reverse proxy (Caddy, Nginx, etc.) for HTTPS termination ## First Deploy ### 1. Clone the repository ```bash git clone https://gitea.wildcardproject.com/zoeissleeping/veridian.git cd veridian ``` ### 2. Configure environment variables ```bash cp .env.example .env ``` Edit `.env` and set the required values: ```bash # Generate a secure auth secret openssl rand -base64 32 # Set these in .env POSTGRES_PASSWORD= BETTER_AUTH_SECRET= NUXT_PUBLIC_URL=https://your-domain.com ``` ### 3. Build and start ```bash docker compose up --build -d ``` This will: 1. Build the Nuxt application 2. Start PostgreSQL and wait for it to be healthy 3. Run all pending database migrations automatically 4. Start the application server ### 4. Verify ```bash # Check container status docker compose ps # Check app logs (should show migration + server start) docker compose logs app # Check for errors docker compose logs app | grep -i error ``` ### 5. Set up your reverse proxy Point your reverse proxy at `127.0.0.1:3000`. Example Caddy config: ``` your-domain.com { reverse_proxy 127.0.0.1:3000 } ``` ## Updating When you pull new changes: ```bash git pull # Rebuild and restart (migrations run automatically on startup) docker compose up --build -d ``` The app container will: 1. Rebuild with the latest code 2. Run any new migrations that were added 3. Restart the server ## Database Migrations Migrations run automatically every time the app container starts, via [`scripts/start.ts`](scripts/start.ts). This uses Drizzle ORM's programmatic migration API (`drizzle-orm/node-postgres/migrator`). - **First deploy**: All migrations run, creating all tables - **Updates**: Only new/pending migrations run - **No changes**: Migrations are a no-op If a migration fails, the app will not start and the container will exit with an error. Check logs with: ```bash docker compose logs app ``` ### Creating new migrations After modifying [`drizzle/schema.ts`](drizzle/schema.ts): ```bash bunx drizzle-kit generate ``` This creates a new SQL file in `drizzle/migrations/`. Commit it to git. It will be applied automatically on next deploy. ## Database Backups ### Manual backup ```bash docker compose exec db pg_dump -U postgres veridian > backup_$(date +%Y%m%d).sql ``` ### Restore from backup ```bash cat backup_20250101.sql | docker compose exec -T db psql -U postgres veridian ``` ### Automated backups (optional) Add a cron job on the host: ```bash # Daily backup at 3 AM 0 3 * * * cd /path/to/veridian && docker compose exec -T db pg_dump -U postgres veridian | gzip > /var/backups/veridian/veridian_$(date +\%Y\%m\%d).sql.gz ``` ## Troubleshooting ### App won't start ```bash # Check logs docker compose logs app # Common issues: # - Missing .env file or required variables not set # - Database not reachable (check db container is healthy) # - Migration errors (schema conflicts) ``` ### Database connection refused ```bash # Check DB is healthy docker compose ps db # Check DB logs docker compose logs db # Test connection docker compose exec db psql -U postgres veridian -c "SELECT 1" ``` ### Reset database (destructive) ```bash docker compose down -v # Removes volumes! docker compose up --build -d ``` ## Environment Variables Reference | Variable | Required | Description | |----------|----------|-------------| | `POSTGRES_DB` | No | Database name (default: `veridian`) | | `POSTGRES_USER` | No | Database user (default: `postgres`) | | `POSTGRES_PASSWORD` | **Yes** | Database password | | `DATABASE_URL` | Auto | Built from the above vars by docker-compose | | `BETTER_AUTH_SECRET` | **Yes** | Auth encryption secret (`openssl rand -base64 32`) | | `NUXT_PUBLIC_URL` | **Yes** | Public URL (e.g., `https://veridian.example.com`) | | `S3_ACCESS_KEY_ID` | No | S3-compatible storage access key | | `S3_SECRET_ACCESS_KEY` | No | S3-compatible storage secret key | | `S3_BUCKET_NAME` | No | S3 bucket name | | `S3_REGION` | No | S3 region | | `S3_ENDPOINT` | No | S3 endpoint URL | | `DISABLE_SIGNUP` | No | Set to `true` to disable new user signups | | `DISABLE_LOCAL_AUTH` | No | Set to `true` to disable email/password auth |