Hugo Production Deployment: Setup dan Best Practices
Hugo Production Deployment: Setup dan Best Practices
Deployment ke production adalah tahap kritis dalam lifecycle pengembangan website. Berbeda dengan development environment, production environment membutuhkan konfigurasi yang fokus pada reliability, security, dan performance. Panduan ini akan membahas setup production deployment untuk Hugo sites, mulai dari server configuration hingga monitoring dan maintenance.
Hugo sites adalah static files yang dapat dihosting di berbagai platform. Namun, production deployment yang proper membutuhkan lebih dari sekadar mengupload files. Ada aspek security, caching, SSL, dan monitoring yang perlu diperhatikan untuk operasional yang reliable.
Pre-Deployment Checklist
Sebelum deploy ke production, pastikan checklist berikut sudah dipenuhi:
# Production build
hugo --environment production --minify
# Verify build
ls -la public/
# Check for broken links
hugo --printI18nWarnings --printPathWarnings
# Verify all pages built
hugo --printUnusedTemplates
Server Configuration
Nginx Configuration
# /etc/nginx/sites-available/example.com
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# 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 Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self';" always;
# Gzip Compression
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript
text/xml application/xml application/xml+rss text/javascript;
# Root directory
root /var/www/example.com/public;
index index.html;
# Cache control for static assets
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location / {
try_files $uri $uri/ =404;
}
# Rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
location /api/ {
limit_req zone=api burst=20;
}
}
SSL/TLS dengan Let’s Encrypt
# Install Certbot
sudo apt install certbot python3-certbot-nginx
# Obtain and install certificate
sudo certbot --nginx -d example.com -d www.example.com
# Auto-renewal
sudo systemctl enable certbot.timer
Security Best Practices
File Permissions
# Set proper permissions
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
# Protect sensitive files
sudo chmod 600 /etc/letsencrypt/ -R
Security Headers
# Strong 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 Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;
Fail2ban Configuration
# /etc/fail2ban/jail.local
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 3
bantime = 600
findtime = 600
[nginx-noscript]
enabled = true
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 3
bantime = 86400
findtime = 3600
Performance Optimization
CDN Configuration
Cloudflare adalah pilihan popular untuk CDN:
# cloudflare-pages.yml dalam GitHub Actions
- name: Deploy to Cloudflare Pages
uses: cloudflare/pages-action@v1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: my-hugo-site
directory: public
Caching Strategy
# Aggressive caching untuk static assets
location ~* \.(css|js|ico|gif|svg|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# Shorter caching untuk HTML
location ~* \.html$ {
expires 3600;
add_header Cache-Control "public, must-revalidate";
}
Image Optimization CDN
# Cloudflare Polish untuk image optimization
add_header CF-Polite-Enable "on" always;
Monitoring dan Logging
Setup Monitoring
# Install Prometheus Node Exporter
sudo apt install prometheus-node-exporter
# Configure monitoring endpoint
curl http://localhost:9100/metrics
Log Rotation
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
Health Check Endpoint
Buat custom health check endpoint:
{{/* layouts/_default/health.html */}}
{{- define "main" -}}
{
"status": "healthy",
"timestamp": "{{ now.Format "2006-01-02T15:04:05Z07:00" }}",
"version": "{{ hugo.Version }}"
}
{{- end -}}
Backup dan Recovery
Backup Strategy
#!/bin/bash
# scripts/backup.sh
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/backup/example.com"
PUBLIC_DIR="/var/www/example.com/public"
# Create backup
tar -czf ${BACKUP_DIR}/backup_${DATE}.tar.gz ${PUBLIC_DIR}
# Keep only last 7 backups
ls -t ${BACKUP_DIR}/backup_*.tar.gz | tail -n +8 | xargs rm -f
# Upload to cloud storage
aws s3 cp ${BACKUP_DIR}/backup_${DATE}.tar.gz s3://my-backup-bucket/
Recovery Procedure
#!/bin/bash
# scripts/recover.sh
BACKUP_FILE=$1
TARGET_DIR="/var/www/example.com"
# Stop web server
sudo systemctl stop nginx
# Restore backup
sudo tar -xzf ${BACKUP_FILE} -C ${TARGET_DIR}
# Fix permissions
sudo chown -R www-data:www-data ${TARGET_DIR}
# Start web server
sudo systemctl start nginx
CI/CD Integration
Automated Deployment Script
#!/bin/bash
# scripts/deploy.sh
set -e
# Variables
SITE_DIR="/var/www/example.com"
REPO_DIR="/home/user/example.com"
DEPLOY_USER="www-data"
# Pull latest changes
cd ${REPO_DIR}
git pull origin main
# Build Hugo
hugo --environment production --minify
# Sync files
rsync -avz --delete \
${REPO_DIR}/public/ \
${SITE_DIR}/public/ \
--chown=${DEPLOY_USER}:${DEPLOY_USER}
# Reload nginx
sudo systemctl reload nginx
echo "Deployment completed successfully"
Systemd Service
# /etc/systemd/system/hugo-deploy.service
[Unit]
Description=Hugo Deployment Service
After=network.target
[Service]
Type=oneshot
User=deploy
ExecStart=/home/user/scripts/deploy.sh
Environment=DEPLOY_ENV=production
WorkingDirectory=/home/user
[Install]
WantedBy=multi-user.target
Scaling Considerations
Horizontal Scaling
Untuk website dengan traffic tinggi, gunakan CDN:
# Cloudflare configuration
- Enable Polish for image compression
- Enable Brotli compression
- Configure Page Rules for caching
- Enable DDoS protection
Load Balancing
# /etc/nginx/upstream.conf
upstream hugo_servers {
server 10.0.0.1:80;
server 10.0.0.2:80;
server 10.0.0.3:80;
keepalive 32;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://hugo_servers;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Maintenance Procedures
Zero-Downtime Deployment
#!/bin/bash
# scripts/zero-downtime-deploy.sh
set -e
NEW_DIR="/var/www/example.com/new"
CURRENT_DIR="/var/www/example.com/current"
RELEASES_DIR="/var/www/example.com/releases"
# Create release directory
mkdir -p ${RELEASES_DIR}/$(date +%Y%m%d_%H%M%S)
# Build to new directory
cd /home/user/example.com
hugo --environment production -d ${NEW_DIR}
# Symlink swap
ln -sfn ${NEW_DIR} ${CURRENT_DIR}
# Clean old releases (keep last 5)
ls -dt ${RELEASES_DIR}/* | tail -n +6 | xargs rm -rf
Kesimpulan
Production deployment untuk Hugo sites membutuhkan perhatian pada detail security, performance, dan reliability. Dengan mengikuti best practices yang dibahas dalam panduan ini, website Hugo Anda akan siap untuk production dengan operasional yang smooth dan aman.
Artikel Terkait
Link Postingan: https://www.tirinfo.com/hugo-production-deployment/