Skip to content

Latest commit

 

History

History
406 lines (299 loc) · 7.83 KB

File metadata and controls

406 lines (299 loc) · 7.83 KB

Deployment Guide

This guide covers different methods for self-hosting the TimelyOne application.

Table of Contents

  1. Docker Compose (Recommended)
  2. Manual Deployment
  3. VPS Deployment
  4. Reverse Proxy Configuration
  5. Production Checklist

Docker Compose (Recommended)

The easiest way to self-host the application is using Docker Compose, which handles both the app and PostgreSQL database.

Prerequisites

  • Docker and Docker Compose installed
  • Domain name (optional, but recommended for HTTPS)

Quick Start

  1. Clone the repository

    git clone <repository-url>
    cd timelyone
  2. Create environment file

    cp .env.example .env
  3. Edit .env and set required variables

    nano .env

    Key variables to set:

    • DB_PASSWORD: Strong password for PostgreSQL
    • NEXTAUTH_SECRET: Generate with openssl rand -base64 32
    • APP_URL: Your domain or IP (e.g., https://calendar.yourdomain.com)
  4. Start the services

    docker-compose up -d
  5. Check logs

    docker-compose logs -f app
  6. Access the application

    • Open http://localhost:3000 (or your configured APP_URL)
    • Complete the setup wizard

Docker Compose Commands

# Start services
docker-compose up -d

# Stop services
docker-compose down

# View logs
docker-compose logs -f

# Restart app only
docker-compose restart app

# Update to latest version
git pull
docker-compose build --no-cache
docker-compose up -d

# Backup database
docker exec calendar-db pg_dump -U calendar_user all_in_one_calendar > backup.sql

# Restore database
cat backup.sql | docker exec -i calendar-db psql -U calendar_user all_in_one_calendar

Manual Deployment

For deploying without Docker on a VPS or local machine.

Prerequisites

  • Node.js 20+
  • PostgreSQL 14+
  • PM2 (optional, for process management)

Steps

  1. Install dependencies

    npm install
  2. Set up PostgreSQL

    # Create database
    createdb all_in_one_calendar
    
    # Create user (optional)
    psql -c "CREATE USER calendar_user WITH PASSWORD 'your_password';"
    psql -c "GRANT ALL PRIVILEGES ON DATABASE all_in_one_calendar TO calendar_user;"
  3. Configure environment

    cp .env.example .env
    nano .env
  4. Run migrations

    npx prisma migrate deploy
    npx prisma generate
  5. Build the application

    npm run build
  6. Start the application

    Option A: Direct start

    npm start

    Option B: With PM2

    npm install -g pm2
    pm2 start npm --name "calendar" -- start
    pm2 save
    pm2 startup

VPS Deployment

Example deployment on a Ubuntu 22.04 VPS (DigitalOcean, Linode, etc.)

1. Initial Server Setup

# Update system
sudo apt update && sudo apt upgrade -y

# Install Node.js 20
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

# Install PostgreSQL
sudo apt install -y postgresql postgresql-contrib

# Install Docker (alternative)
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER

2. Clone and Configure

# Clone repository
cd /opt
sudo git clone <repository-url> calendar
sudo chown -R $USER:$USER calendar
cd calendar

# Set up environment
cp .env.example .env
nano .env

3. Deploy with Docker Compose

docker-compose up -d

4. Set up automatic updates

# Create update script
cat > /opt/calendar/update.sh << 'EOF'
#!/bin/bash
cd /opt/calendar
git pull
docker-compose build --no-cache
docker-compose up -d
EOF

chmod +x /opt/calendar/update.sh

# Add to cron (weekly updates)
(crontab -l 2>/dev/null; echo "0 3 * * 0 /opt/calendar/update.sh") | crontab -

Reverse Proxy Configuration

Nginx

server {
    listen 80;
    server_name calendar.yourdomain.com;

    # Redirect HTTP to HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name calendar.yourdomain.com;

    # SSL configuration (use certbot for Let's Encrypt)
    ssl_certificate /etc/letsencrypt/live/calendar.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/calendar.yourdomain.com/privkey.pem;

    # Proxy settings
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Install SSL with Certbot:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d calendar.yourdomain.com

Caddy (Easier)

Create /etc/caddy/Caddyfile:

calendar.yourdomain.com {
    reverse_proxy localhost:3000
}

Start Caddy:

sudo caddy run --config /etc/caddy/Caddyfile

Traefik (Docker)

Add labels to docker-compose.yml:

services:
  app:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.calendar.rule=Host(`calendar.yourdomain.com`)"
      - "traefik.http.routers.calendar.entrypoints=websecure"
      - "traefik.http.routers.calendar.tls.certresolver=letsencrypt"

Production Checklist

Before going to production, ensure:

Security

  • Change DB_PASSWORD to a strong, unique password
  • Generate a secure NEXTAUTH_SECRET (openssl rand -base64 32)
  • Use HTTPS with a valid SSL certificate
  • Configure firewall (only ports 80, 443, and 22 open)
  • Set up fail2ban to prevent brute force attacks
  • Regular security updates: apt update && apt upgrade

Database

  • Set up automated backups
    # Add to crontab
    0 2 * * * docker exec calendar-db pg_dump -U calendar_user all_in_one_calendar | gzip > /backups/calendar_$(date +\%Y\%m\%d).sql.gz
  • Configure backup retention (keep last 30 days)
  • Test backup restoration

Monitoring

  • Set up uptime monitoring (UptimeRobot, StatusCake, etc.)
  • Configure email alerts for errors
  • Monitor disk space usage
  • Set up log rotation

Performance

  • Enable HTTP/2
  • Configure CDN (optional, for assets)
  • Set up database connection pooling
  • Configure caching headers

Maintenance

  • Document your deployment
  • Set up automatic updates (with testing)
  • Create rollback procedure
  • Test disaster recovery

Troubleshooting

Application won't start

# Check logs
docker-compose logs app

# Common issues:
# 1. Database not ready - wait a few seconds and restart
docker-compose restart app

# 2. Environment variables not set
nano .env

# 3. Port 3000 already in use
sudo lsof -i :3000

Database connection issues

# Check PostgreSQL is running
docker-compose ps postgres

# Check connection from app container
docker-compose exec app npx prisma db pull

Can't access from external IP

# Check firewall
sudo ufw status

# Allow ports
sudo ufw allow 80
sudo ufw allow 443

Out of disk space

# Check disk usage
df -h

# Clean Docker images
docker system prune -a

# Rotate logs
docker-compose down
sudo truncate -s 0 /var/lib/docker/containers/*/*-json.log
docker-compose up -d

Support

For issues or questions:

  • Check GitHub Issues
  • Review documentation
  • Check application logs

Updates

To update to the latest version:

cd /opt/calendar
git pull
docker-compose build --no-cache
docker-compose up -d

Always backup your database before updating!