release-tracker/docs/DEPLOYMENT.md

379 lines
9.6 KiB
Markdown

# Deployment Guide
This document describes how to deploy the Release Tracker application using two different approaches:
1. **Docker Compose** (Self-Hosted) - Uses SQLite database
2. **Vercel** (Cloud) - Uses Turso (serverless SQLite)
## Quick Comparison
| Feature | Docker Compose | Vercel |
|---------|---------------|--------|
| **Database** | SQLite (local file) | Turso (serverless SQLite) |
| **Hosting** | Your own server | Vercel cloud |
| **Cost** | Free (server cost only) | Free tier available |
| **Setup complexity** | Medium | Low |
| **Data control** | Full | Database hosted by Turso |
| **Best for** | Single-user, internal tools | Multi-user, public access |
---
## Option 1: Docker Compose (Self-Hosted)
### Prerequisites
- Linux server (or macOS/Windows with Docker Desktop)
- Docker and Docker Compose installed
- (Optional) Intel Mac users: Docker Desktop supports linux/amd64 builds
### Deployment Steps
#### 1. Build and Run on Linux Server (Recommended)
```bash
# Clone or copy the project to your Linux server
git clone <your-repo> release-tracker
cd release-tracker
# Build the Docker image
sudo docker compose build
# Run the container
sudo docker compose up -d
```
#### 2. Build on Mac, Deploy to Linux
If you're on an Intel Mac and want to build locally then deploy to Linux:
```bash
# Build for linux/amd64 platform
docker build --platform linux/amd64 -t release-tracker:latest .
# Save the image
docker save release-tracker:latest | gzip > release-tracker.tar.gz
# Copy to Linux server
scp release-tracker.tar.gz user@linux-server:/tmp/
# On Linux server, load and run
ssh user@linux-server "cd /tmp && docker load < release-tracker.tar.gz"
# Create docker-compose.yml on Linux server and run
ssh user@linux-server "cd /opt/release-tracker && docker compose up -d"
```
#### 3. Data Persistence
The SQLite database is stored in `./data/app.db` and mounted as a volume. To backup:
```bash
# Backup
cp data/app.db backups/app.db.$(date +%Y%m%d)
# Restore
cp backups/app.db.20240101 data/app.db
sudo docker compose restart
```
### Environment Variables
Create a `.env` file in the project root:
```bash
# Database (SQLite is the only option for Docker)
DB_TYPE=sqlite
DATABASE_URL=file:./data/app.db
# Next.js
NODE_ENV=production
NEXT_TELEMETRY_DISABLED=1
```
### Updating the Application
```bash
# Pull latest code
git pull
# Rebuild and restart
sudo docker compose down
sudo docker compose build --no-cache
sudo docker compose up -d
```
---
## Option 2: Vercel (Cloud)
### Prerequisites
- Vercel account (sign up at [vercel.com](https://vercel.com))
- Git repository (GitHub, GitLab, or Bitbucket)
- Turso account (sign up at [turso.tech](https://turso.tech))
### Step 1: Set Up Turso Database
1. Install Turso CLI:
```bash
curl -sSfL https://get.tur.so/install.sh | bash
```
2. Login to Turso:
```bash
turso auth login
```
3. Create a database:
```bash
turso db create release-tracker
```
4. Get the database URL:
```bash
turso db show release-tracker
```
Copy the "LibSQL URL" (looks like: `libsql://release-tracker-username.turso.io`)
5. Create an authentication token:
```bash
turso db tokens create release-tracker
```
Save this token securely.
### Step 2: Deploy to Vercel
1. **Connect Repository**:
- Go to [vercel.com](https://vercel.com)
- Click "Add New Project"
- Import your Git repository
2. **Configure Build Settings**:
- Framework Preset: Next.js
- Build Command: `npm run build`
- Output Directory: `.next`
3. **Set Environment Variables**:
In the Vercel dashboard, go to Project Settings → Environment Variables, add:
| Variable | Value | Required |
|----------|-------|----------|
| `DB_TYPE` | `turso` | Yes |
| `TURSO_URL` | Your Turso database URL | Yes |
| `TURSO_TOKEN` | Your Turso auth token | Yes |
| `ENABLE_PASSCODE` | `true` (recommended for public sites) | No (default: false) |
| `PASSCODE` | Your secret passcode | If ENABLE_PASSCODE=true |
> **Note**: The build process will automatically run database migrations using the `prebuild` script. Make sure the environment variables are set before the first build.
>
> **Security**: For public deployments, set `ENABLE_PASSCODE=true` and `PASSCODE` to protect the application with a simple passcode. The cookie lasts 7 days.
4. **Deploy**:
- Click "Deploy"
- Vercel will build and deploy automatically
- The build process will:
1. Run `prebuild` script to create database tables
2. Build the Next.js application
3. Deploy to Vercel's edge network
### Updating on Vercel
Simply push to your Git repository:
```bash
git push origin main
```
Vercel will automatically rebuild and redeploy.
---
## Local Development
### Using SQLite (Default)
```bash
# Copy example env file
cp .env.local.example .env.local
# Install dependencies
npm install
# Run development server
npm run dev
```
### Using Turso (Optional, for testing)
```bash
# Copy example env file and edit
cp .env.local.example .env.local
# Edit .env.local:
DB_TYPE=turso
TURSO_URL=libsql://your-database-url
TURSO_TOKEN=your-token
# Run development server
npm run dev
```
---
## Troubleshooting
### Docker Issues
**Issue**: Container fails to start with permission errors
**Solution**: The container runs as root (uid=0, gid=0) by default. If you have permission issues:
```bash
# Fix data directory permissions
sudo chown -R 0:0 ./data
sudo chmod -R 755 ./data
```
**Issue**: Database file is locked
**Solution**: Stop the container, remove the lock files, and restart:
```bash
sudo docker compose down
rm -f data/*.db-wal data/*.db-shm
sudo docker compose up -d
```
### Vercel Issues
**Issue**: Build fails with "no such table" error
**Solution**: This happens when the database tables don't exist during build. The `prebuild` script should create them automatically. If it fails:
- Ensure `TURSO_URL` and `TURSO_TOKEN` are set in Vercel Environment Variables
- Check that the Turso database exists and is accessible
- Try running `npx drizzle-kit push` locally with the same credentials to verify
**Issue**: Build fails with database errors
**Solution**: Ensure environment variables are set in Vercel dashboard (not just in `.env.local`)
**Issue**: Data doesn't persist between deployments
**Solution**: This is expected with SQLite on Vercel. You must use Turso for persistence.
**Issue**: Passcode not working
**Solution**:
- Ensure both `ENABLE_PASSCODE=true` and `PASSCODE` are set
- The passcode is case-sensitive
- Clear browser cookies and try again
- Check browser console for API errors
### Authentication Issues
**Issue**: Cannot access site even with correct passcode
**Solution**:
- Check that cookies are enabled in your browser
- Try accessing in an incognito/private window
- Verify the `AUTH_COOKIE_NAME` hasn't changed between deployments
- The cookie is set to expire after 7 days; if you cleared cookies, you'll need to re-enter the passcode
### Turso Issues
**Issue**: Connection refused or timeout
**Solution**: Check your `TURSO_URL` and `TURSO_TOKEN` are correct. Turso databases may sleep after inactivity on free tier.
---
## Architecture Notes
### Database Abstraction
The application uses a database factory pattern (`src/lib/db/index.ts`) that automatically selects the appropriate database driver based on the `DB_TYPE` environment variable:
- `DB_TYPE=sqlite`: Uses `better-sqlite3` driver with local file
- `DB_TYPE=turso`: Uses `@libsql/client` driver with Turso
Both use the same Drizzle ORM schema, so no code changes are needed when switching between them.
### Data Migration Between Environments
To migrate data from local SQLite to Turso:
1. Export from SQLite:
```bash
sqlite3 data/app.db .dump > backup.sql
```
2. Import to Turso:
```bash
turso db shell release-tracker < backup.sql
```
Note: Some SQLite-specific syntax may need adjustment for Turso compatibility.
---
## Authentication
The application supports optional passcode-based authentication, controlled by environment variables.
### Configuration
| Variable | Description | Default |
|----------|-------------|---------|
| `ENABLE_PASSCODE` | Enable passcode protection | `false` |
| `PASSCODE` | The secret passcode | - |
| `AUTH_COOKIE_NAME` | Name of the auth cookie | `release_tracker_auth` |
### Use Cases
**Private Docker Deployment** (no auth needed):
```bash
ENABLE_PASSCODE=false
```
**Public Vercel Deployment** (auth required):
```bash
ENABLE_PASSCODE=true
PASSCODE=your-secure-passcode-here
```
### How It Works
1. When `ENABLE_PASSCODE=true`, all routes require authentication
2. Users are redirected to `/login` page
3. After entering the correct passcode, a 7-day cookie is set
4. Cookie is `httpOnly`, `secure` (in production), and `SameSite=strict`
5. No logout functionality (users must clear cookies or wait 7 days)
### Security Considerations
- Passcode is never sent to the client (verified server-side)
- Cookie cannot be accessed by JavaScript (`httpOnly`)
- Cookie is only sent over HTTPS in production (`secure`)
- Cookie expires after 7 days (`maxAge: 604800`)
- Single passcode for all users (simple but not suitable for multi-user scenarios)
---
## Backup Strategy
### Docker/SQLite
```bash
# Automated daily backup via cron
0 2 * * * cp /opt/release-tracker/data/app.db /backups/app.db.$(date +\%Y\%m\%d)
```
### Vercel/Turso
Turso provides automatic backups. You can also export manually:
```bash
turso db dump release-tracker > backup.sql
```
---
## Support
For issues specific to:
- **Docker**: Check Docker logs with `docker compose logs`
- **Vercel**: Check Vercel dashboard deployment logs
- **Turso**: Check Turso dashboard or run `turso db inspect release-tracker`