Files
website/DEPLOYMENT.md
tumillanino d5818bcf13 everything
2025-10-28 14:48:44 +11:00

11 KiB

Deployment Guide - Test Server Setup

This guide walks through deploying Decor by Hannah's to a test server using rclone.

Prerequisites

  • A Linux server (Ubuntu 20.04+ recommended)
  • SSH access to the server
  • rclone installed locally
  • Domain name (optional, but recommended)

Part 1: Local Preparation

1. Configure rclone

# Configure rclone with your server
rclone config

# Follow prompts to add an SFTP remote:
# - Type: sftp
# - Host: your-server-ip
# - User: your-ssh-user
# - Port: 22 (or your SSH port)
# - Key file: path to your SSH key (optional)

# Name it something like "testserver"

2. Prepare Your Local Project

# Make sure everything is committed
git status

# Create a .deployignore file (optional)
cat > .deployignore << 'EOF'
.git/
.env
*.log
tmp/
EOF

# Test your build locally
go build -o server cmd/server/main.go

3. Copy Files to Server

# Sync project to server (excluding .git and .env)
rclone sync . testserver:/home/youruser/decor-by-hannahs \
  --exclude ".git/**" \
  --exclude ".env" \
  --exclude "*.log" \
  --exclude "tmp/**" \
  --progress

# Or use rsync if you prefer:
# rsync -avz --exclude '.git' --exclude '.env' . user@server:/home/youruser/decor-by-hannahs/

Part 2: Server Setup

1. SSH into Your Server

ssh user@your-server-ip

2. Install Docker & Docker Compose

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

# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Add your user to docker group
sudo usermod -aG docker $USER

# Install Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

# Verify installation
docker --version
docker-compose --version

# Log out and back in for group changes to take effect
exit
ssh user@your-server-ip

3. Install Go

# Download Go (check for latest version at https://go.dev/dl/)
wget https://go.dev/dl/go1.21.5.linux-amd64.tar.gz

# Remove old Go installation (if exists)
sudo rm -rf /usr/local/go

# Extract and install
sudo tar -C /usr/local -xzf go1.21.5.linux-amd64.tar.gz

# Add to PATH
echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.bashrc
echo 'export PATH=$PATH:$HOME/go/bin' >> ~/.bashrc
source ~/.bashrc

# Verify installation
go version

4. Install Node.js (for Ory CLI)

# Install Node.js via nvm
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
source ~/.bashrc

# Install latest LTS
nvm install --lts
nvm use --lts

# Verify
node --version
npm --version

5. Install Ory CLI

# Install Ory CLI globally
npm install -g @ory/cli

# Verify
ory version

Part 3: Application Setup

1. Navigate to Project Directory

cd ~/decor-by-hannahs

2. Create Environment File

# Copy example and edit
cp .env.example .env
nano .env

# Fill in your values:
# DATABASE_URL=postgresql://party:your_password@localhost:5432/partydb
# ORY_API_URL=http://localhost:4000
# TUNNEL_PORT=4000
# PORT=3000

3. Start PostgreSQL with Docker

# Start database
docker-compose up -d db

# Wait a few seconds for DB to initialize
sleep 5

# Verify it's running
docker ps

# Test connection
docker exec -it $(docker ps -q -f name=db) psql -U party -d partydb -c "SELECT version();"

4. Run Database Migrations

# Apply all migrations in order
for migration in migrations/*.sql; do
  echo "Applying $migration..."
  docker exec -i $(docker ps -q -f name=db) psql -U party -d partydb < "$migration"
done

# Verify tables exist
docker exec -it $(docker ps -q -f name=db) psql -U party -d partydb -c "\dt"

5. Build the Application

# Install Go dependencies
go mod download

# Build the application
go build -o server cmd/server/main.go

# Verify binary
./server --help || echo "Binary created successfully"

Part 4: Running the Application

Option A: Run Directly (for testing)

# Terminal 1: Start Ory tunnel
./start-tunnel.sh
# Or manually:
# ory tunnel --dev --project <your-ory-project-slug> http://localhost:3000

# Terminal 2: Start the application
./server

# Or run in background:
nohup ./server > app.log 2>&1 &

1. Create Ory Tunnel Service

sudo nano /etc/systemd/system/ory-tunnel.service

Add this content (replace values):

[Unit]
Description=Ory Tunnel for Decor by Hannah's
After=network.target

[Service]
Type=simple
User=youruser
WorkingDirectory=/home/youruser/decor-by-hannahs
Environment="PATH=/usr/local/bin:/usr/bin:/bin:/home/youruser/.nvm/versions/node/v20.10.0/bin"
ExecStart=/home/youruser/.nvm/versions/node/v20.10.0/bin/npx @ory/cli tunnel --dev --project your-ory-project-slug http://localhost:3000
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

2. Create Application Service

sudo nano /etc/systemd/system/decor-by-hannahs.service

Add this content:

[Unit]
Description=Decor by Hannah's Application
After=network.target docker.service ory-tunnel.service
Requires=docker.service

[Service]
Type=simple
User=youruser
WorkingDirectory=/home/youruser/decor-by-hannahs
Environment="PATH=/usr/local/go/bin:/usr/local/bin:/usr/bin:/bin"
EnvironmentFile=/home/youruser/decor-by-hannahs/.env
ExecStart=/home/youruser/decor-by-hannahs/server
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

3. Enable and Start Services

# Reload systemd
sudo systemctl daemon-reload

# Enable services to start on boot
sudo systemctl enable ory-tunnel
sudo systemctl enable decor-by-hannahs

# Start services
sudo systemctl start ory-tunnel
sudo systemctl start decor-by-hannahs

# Check status
sudo systemctl status ory-tunnel
sudo systemctl status decor-by-hannahs

# View logs
sudo journalctl -u ory-tunnel -f
sudo journalctl -u decor-by-hannahs -f

Part 5: Firewall & Networking

1. Configure Firewall

# Install ufw if not present
sudo apt install ufw -y

# Allow SSH (IMPORTANT: do this first!)
sudo ufw allow 22/tcp

# Allow HTTP and HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Allow application port (if accessing directly)
sudo ufw allow 3000/tcp

# Enable firewall
sudo ufw enable

# Check status
sudo ufw status
# Install Nginx
sudo apt install nginx -y

# Create site configuration
sudo nano /etc/nginx/sites-available/decor-by-hannahs

Add this configuration:

server {
    listen 80;
    server_name your-domain.com www.your-domain.com;

    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;
    }
}

Enable the site:

# Create symbolic link
sudo ln -s /etc/nginx/sites-available/decor-by-hannahs /etc/nginx/sites-enabled/

# Test configuration
sudo nginx -t

# Restart Nginx
sudo systemctl restart nginx
sudo systemctl enable nginx

3. Setup SSL with Let's Encrypt (Optional)

# Install Certbot
sudo apt install certbot python3-certbot-nginx -y

# Obtain certificate
sudo certbot --nginx -d your-domain.com -d www.your-domain.com

# Certbot will automatically configure Nginx for HTTPS
# Certificates auto-renew via cron

Part 6: Post-Deployment

1. Create Admin User

# First, register a user through the web interface
# Then grant admin privileges:
docker exec -i $(docker ps -q -f name=db) psql -U party -d partydb -c "UPDATE users SET is_admin = TRUE WHERE email = 'your-email@example.com';"

2. Test the Application

# Check if services are running
sudo systemctl status decor-by-hannahs
sudo systemctl status ory-tunnel

# Test the endpoint
curl http://localhost:3000

# Or visit in browser:
# http://your-server-ip:3000
# or http://your-domain.com (if using Nginx)

3. Monitor Logs

# Application logs
sudo journalctl -u decor-by-hannahs -f

# Ory tunnel logs
sudo journalctl -u ory-tunnel -f

# Nginx logs (if using)
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

# Database logs
docker logs -f $(docker ps -q -f name=db)

Part 7: Maintenance & Updates

Deploying Updates

# On local machine: sync changes
rclone sync . testserver:/home/youruser/decor-by-hannahs \
  --exclude ".git/**" \
  --exclude ".env" \
  --progress

# On server: rebuild and restart
cd ~/decor-by-hannahs
go build -o server cmd/server/main.go
sudo systemctl restart decor-by-hannahs

Database Backups

# Create backup script
cat > ~/backup-db.sh << 'EOF'
#!/bin/bash
BACKUP_DIR=~/backups
mkdir -p $BACKUP_DIR
DATE=$(date +%Y%m%d_%H%M%S)
docker exec $(docker ps -q -f name=db) pg_dump -U party partydb > $BACKUP_DIR/backup_$DATE.sql
# Keep only last 7 days
find $BACKUP_DIR -name "backup_*.sql" -mtime +7 -delete
EOF

chmod +x ~/backup-db.sh

# Add to crontab (daily at 2 AM)
(crontab -l 2>/dev/null; echo "0 2 * * * /home/youruser/backup-db.sh") | crontab -

Restore from Backup

# Restore a backup
docker exec -i $(docker ps -q -f name=db) psql -U party -d partydb < ~/backups/backup_YYYYMMDD_HHMMSS.sql

Troubleshooting

Application won't start

# Check logs
sudo journalctl -u decor-by-hannahs -n 50

# Check if port is in use
sudo lsof -i :3000

# Check environment variables
sudo systemctl show decor-by-hannahs --property=Environment

Database connection issues

# Check if database is running
docker ps | grep db

# Test connection
docker exec -it $(docker ps -q -f name=db) psql -U party -d partydb

# Check database logs
docker logs $(docker ps -q -f name=db)

Ory tunnel issues

# Check tunnel status
sudo journalctl -u ory-tunnel -n 50

# Test Ory connection
curl http://localhost:4000/.ory/health/ready

# Restart tunnel
sudo systemctl restart ory-tunnel

Permission issues

# Fix file ownership
sudo chown -R youruser:youruser ~/decor-by-hannahs

# Fix binary permissions
chmod +x ~/decor-by-hannahs/server

Security Checklist

  • Change default database password in docker-compose.yml and .env
  • Setup firewall (ufw)
  • Use HTTPS (Let's Encrypt)
  • Keep system updated: sudo apt update && sudo apt upgrade
  • Setup automated backups
  • Use strong passwords for admin accounts
  • Restrict SSH access (key-based auth, disable root login)
  • Monitor logs regularly
  • Setup fail2ban for SSH protection

Quick Reference Commands

# Restart application
sudo systemctl restart decor-by-hannahs

# View logs
sudo journalctl -u decor-by-hannahs -f

# Rebuild application
cd ~/decor-by-hannahs && go build -o server cmd/server/main.go

# Database CLI
docker exec -it $(docker ps -q -f name=db) psql -U party -d partydb

# Backup database
docker exec $(docker ps -q -f name=db) pg_dump -U party partydb > backup.sql

# Check service status
sudo systemctl status decor-by-hannahs ory-tunnel nginx