557 lines
11 KiB
Markdown
557 lines
11 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
ssh user@your-server-ip
|
|
```
|
|
|
|
### 2. Install Docker & Docker Compose
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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)
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# Install Ory CLI globally
|
|
npm install -g @ory/cli
|
|
|
|
# Verify
|
|
ory version
|
|
```
|
|
|
|
## Part 3: Application Setup
|
|
|
|
### 1. Navigate to Project Directory
|
|
|
|
```bash
|
|
cd ~/decor-by-hannahs
|
|
```
|
|
|
|
### 2. Create Environment File
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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)
|
|
|
|
```bash
|
|
# 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 &
|
|
```
|
|
|
|
### Option B: Run with systemd (recommended for production-like setup)
|
|
|
|
#### 1. Create Ory Tunnel Service
|
|
|
|
```bash
|
|
sudo nano /etc/systemd/system/ory-tunnel.service
|
|
```
|
|
|
|
Add this content (replace values):
|
|
|
|
```ini
|
|
[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
|
|
|
|
```bash
|
|
sudo nano /etc/systemd/system/decor-by-hannahs.service
|
|
```
|
|
|
|
Add this content:
|
|
|
|
```ini
|
|
[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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
```
|
|
|
|
### 2. Setup Nginx Reverse Proxy (Optional but Recommended)
|
|
|
|
```bash
|
|
# Install Nginx
|
|
sudo apt install nginx -y
|
|
|
|
# Create site configuration
|
|
sudo nano /etc/nginx/sites-available/decor-by-hannahs
|
|
```
|
|
|
|
Add this configuration:
|
|
|
|
```nginx
|
|
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:
|
|
|
|
```bash
|
|
# 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)
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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
|
|
```
|