# Alternative: Docker-based Deployment on Scaleway Instance This guide provides an alternative deployment method using a Scaleway instance with Docker and Nginx. ## Advantages of this Method - Full control over the web server - Easy SSL/TLS setup with Let's Encrypt - Better caching control - Custom redirects and URL rewriting - Lower egress costs for high-traffic sites ## Architecture ``` Gitea → Build Hugo → Push to Scaleway Registry → Deploy to Instance via Docker ``` ## Step 1: Create Scaleway Instance ```bash scw instance server create \ name=notebook-server \ type=DEV1-S \ image=ubuntu_jammy \ zone=fr-par-1 ``` Or via console: Create a DEV1-S instance with Ubuntu 22.04 ## Step 2: Install Docker on Instance SSH into your instance and run: ```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 sudo usermod -aG docker $USER # Install Docker Compose sudo apt install docker-compose-plugin -y # Install Nginx and Certbot sudo apt install nginx certbot python3-certbot-nginx -y ``` ## Step 3: Create Docker Deployment Structure On your instance, create: ```bash mkdir -p /opt/notebook cd /opt/notebook ``` Create `docker-compose.yml`: ```yaml version: '3.8' services: nginx: image: nginx:alpine container_name: notebook-nginx ports: - "80:80" - "443:443" volumes: - ./public:/usr/share/nginx/html:ro - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro - ./ssl:/etc/nginx/ssl:ro restart: unless-stopped ``` Create `nginx.conf`: ```nginx server { listen 80; server_name notebook.arnodo.fr; # Redirect to HTTPS return 301 https://$server_name$request_uri; } server { listen 443 ssl http2; server_name notebook.arnodo.fr; ssl_certificate /etc/nginx/ssl/fullchain.pem; ssl_certificate_key /etc/nginx/ssl/privkey.pem; # Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; root /usr/share/nginx/html; index index.html; # Compression gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/x-javascript application/xml+rss application/javascript application/json; # Cache static assets location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; } # Hugo pretty URLs location / { try_files $uri $uri/ $uri.html =404; } # Custom 404 page error_page 404 /404.html; } ``` ## Step 4: Configure DNS Point your domain to the Scaleway instance: ``` notebook.arnodo.fr A ``` ## Step 5: Setup SSL Certificate ```bash sudo certbot certonly --standalone -d notebook.arnodo.fr # Copy certificates to project directory sudo cp /etc/letsencrypt/live/notebook.arnodo.fr/fullchain.pem /opt/notebook/ssl/ sudo cp /etc/letsencrypt/live/notebook.arnodo.fr/privkey.pem /opt/notebook/ssl/ sudo chown -R $USER:$USER /opt/notebook/ssl ``` Set up auto-renewal: ```bash # Add to crontab 0 0 1 * * certbot renew && cp /etc/letsencrypt/live/notebook.arnodo.fr/*.pem /opt/notebook/ssl/ && docker-compose -f /opt/notebook/docker-compose.yml restart nginx ``` ## Step 6: Update Gitea Workflow Create `.gitea/workflows/deploy-docker.yml`: ```yaml name: Deploy to Scaleway Instance on: push: branches: - main jobs: build-and-deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: hugo-version: 'latest' extended: true - name: Build Hugo site run: hugo --minify - name: Install rsync run: sudo apt-get install -y rsync - name: Setup SSH key run: | mkdir -p ~/.ssh echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa ssh-keyscan -H ${{ secrets.SERVER_IP }} >> ~/.ssh/known_hosts - name: Deploy to server run: | rsync -avz --delete \ -e "ssh -i ~/.ssh/id_rsa -o StrictHostKeyChecking=no" \ public/ \ ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }}:/opt/notebook/public/ - name: Restart Nginx run: | ssh -i ~/.ssh/id_rsa ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }} \ "cd /opt/notebook && docker-compose restart nginx" ``` ## Step 7: Configure Gitea Secrets Add to repository secrets: - `SSH_PRIVATE_KEY`: Your SSH private key for the instance - `SERVER_IP`: Your Scaleway instance IP - `SERVER_USER`: SSH user (usually `root` or `ubuntu`) ## Step 8: Create Deployment User (Recommended) For better security, create a dedicated deployment user: ```bash # On the Scaleway instance sudo useradd -m -s /bin/bash deployer sudo usermod -aG docker deployer sudo chown -R deployer:deployer /opt/notebook # Generate SSH key on your local machine ssh-keygen -t ed25519 -C "gitea-deployment" -f ~/.ssh/notebook_deploy # Copy public key to instance ssh-copy-id -i ~/.ssh/notebook_deploy.pub deployer@ ``` Then update the workflow to use `deployer` user. ## Cost Analysis ### Monthly Costs: - **DEV1-S Instance**: ~€7-10/month - **100 GB outbound traffic**: Included - **Additional traffic**: €0.01/GB - **Total**: ~€10/month for typical blog traffic ### Comparison with Object Storage: - **More predictable costs** - Better for high-traffic sites - More control over caching and optimization - Easier SSL/TLS management ## Monitoring Install monitoring tools: ```bash # Install Prometheus Node Exporter docker run -d \ --name=node-exporter \ --net="host" \ --pid="host" \ -v "/:/host:ro,rslave" \ quay.io/prometheus/node-exporter:latest \ --path.rootfs=/host ``` Or use Scaleway monitoring (free): - Enable in console under Instance → Monitoring - Set up alerts for CPU, memory, disk usage ## Backup Strategy 1. **Automated backups**: ```bash # Add to crontab 0 2 * * * tar -czf /backup/notebook-$(date +\%Y\%m\%d).tar.gz /opt/notebook ``` 2. **Use Scaleway snapshots**: ```bash scw instance snapshot create volume-id= name=notebook-backup ``` ## Security Hardening 1. **Configure firewall**: ```bash sudo ufw allow 22/tcp sudo ufw allow 80/tcp sudo ufw allow 443/tcp sudo ufw enable ``` 2. **Disable password authentication**: Edit `/etc/ssh/sshd_config`: ``` PasswordAuthentication no PubkeyAuthentication yes ``` 3. **Keep system updated**: ```bash sudo apt update && sudo apt upgrade -y ``` 4. **Install fail2ban**: ```bash sudo apt install fail2ban -y sudo systemctl enable fail2ban ``` ## Troubleshooting ### Check logs: ```bash docker-compose -f /opt/notebook/docker-compose.yml logs -f ``` ### Test Nginx config: ```bash docker-compose exec nginx nginx -t ``` ### Check SSL certificate: ```bash openssl s_client -connect notebook.arnodo.fr:443 -servername notebook.arnodo.fr ``` ## Performance Optimization Add to `nginx.conf`: ```nginx # HTTP/2 Server Push http2_push_preload on; # Connection optimization keepalive_timeout 65; keepalive_requests 100; # Buffer sizes client_body_buffer_size 128k; client_max_body_size 10m; ``` Enable Brotli compression (optional): ```bash # Add Brotli module to nginx container # Or use a pre-built image with Brotli support ``` --- This Docker-based approach gives you more control and can be more cost-effective for sites with consistent traffic patterns.