7.8 KiB
7.8 KiB
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
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:
# 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:
mkdir -p /opt/notebook
cd /opt/notebook
Create docker-compose.yml:
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:
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 <INSTANCE_IP_ADDRESS>
Step 5: Setup SSL Certificate
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:
# 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:
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 instanceSERVER_IP: Your Scaleway instance IPSERVER_USER: SSH user (usuallyrootorubuntu)
Step 8: Create Deployment User (Recommended)
For better security, create a dedicated deployment user:
# 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@<instance-ip>
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:
# 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
- Automated backups:
# Add to crontab
0 2 * * * tar -czf /backup/notebook-$(date +\%Y\%m\%d).tar.gz /opt/notebook
- Use Scaleway snapshots:
scw instance snapshot create volume-id=<volume-id> name=notebook-backup
Security Hardening
- Configure firewall:
sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
- Disable password authentication:
Edit
/etc/ssh/sshd_config:
PasswordAuthentication no
PubkeyAuthentication yes
- Keep system updated:
sudo apt update && sudo apt upgrade -y
- Install fail2ban:
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
Troubleshooting
Check logs:
docker-compose -f /opt/notebook/docker-compose.yml logs -f
Test Nginx config:
docker-compose exec nginx nginx -t
Check SSL certificate:
openssl s_client -connect notebook.arnodo.fr:443 -servername notebook.arnodo.fr
Performance Optimization
Add to nginx.conf:
# 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):
# 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.