30a425744d
- Add scripts/start.ts to run drizzle migrations before server start - Update Dockerfile to copy migration files and install prod deps - Change entrypoint to use migration-aware startup script - Add deployment documentation
4.3 KiB
4.3 KiB
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
git clone https://gitea.wildcardproject.com/zoeissleeping/veridian.git
cd veridian
2. Configure environment variables
cp .env.example .env
Edit .env and set the required values:
# Generate a secure auth secret
openssl rand -base64 32
# Set these in .env
POSTGRES_PASSWORD=<your-secure-db-password>
BETTER_AUTH_SECRET=<output from openssl>
NUXT_PUBLIC_URL=https://your-domain.com
3. Build and start
docker compose up --build -d
This will:
- Build the Nuxt application
- Start PostgreSQL and wait for it to be healthy
- Run all pending database migrations automatically
- Start the application server
4. Verify
# 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:
git pull
# Rebuild and restart (migrations run automatically on startup)
docker compose up --build -d
The app container will:
- Rebuild with the latest code
- Run any new migrations that were added
- Restart the server
Database Migrations
Migrations run automatically every time the app container starts, via 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:
docker compose logs app
Creating new migrations
After modifying drizzle/schema.ts:
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
docker compose exec db pg_dump -U postgres veridian > backup_$(date +%Y%m%d).sql
Restore from backup
cat backup_20250101.sql | docker compose exec -T db psql -U postgres veridian
Automated backups (optional)
Add a cron job on the host:
# 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
# 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
# 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)
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 |