Project Deployment with Nginx and SSL
Índice
Section titled “Índice”- Prerrequisitos
- Conexión al Server
- Configurar Variables de Entorno
- Primer Despliegue de Prueba
- Configurar Nginx
- Habilitar Sitio en Nginx
- Validar Configuración de Nginx
- Generar Certificado SSL
- Aplicar Configuración Final
- Verificación Final
Prerrequisitos
Section titled “Prerrequisitos”- Acceso SSH al servidor
- Deployer instalado y configurado localmente
- DNS del Dominio apuntando al servidor
- Certbot instalado en el servidor
1. Conexión al Server
Section titled “1. Conexión al Server”ssh user@ip_server2. Crear Estructura del Proyecto
Section titled “2. Crear Estructura del Proyecto”- Crear carpeta
sudo mkdir -p /var/www/{mi_proyecto} - Asignar permisos y propietario:
# Asignar propietario (reemplaza 'tu_usuario' con tu usuario SSH)sudo chown -R tu_usuario:www-data /var/www/{mi_proyecto}
# Establecer permisos adecuadossudo chmod -R 755 /var/www/{mi_proyecto}Nota: Usar www-data como grupo permite que Nginx lea los archivos correctamente.
3. Configurar Variables de Entorno
Section titled “3. Configurar Variables de Entorno”- En tu proyecto local, configurar archivos
.env.productiony.env.development
DEPLOY_REPOSITORY=repository_pathDEPLOY_BRANCH=mainDEPLOY_HOST=ip_serverDEPLOY_USER=user_serverDEPLOY_PROJECT_PATH=/var/www/{mi_proyecto}- Verifica que estos archivos estén en
.gitignore
4. Primer Despliegue de Prueba
Section titled “4. Primer Despliegue de Prueba”- Ejecutar desde el proyecto local
dep deploy production
Verifica que:
- ✅ El despliegue se complete sin errores
- ✅ La carpeta current se haya creado en /var/www/{mi_proyecto}/
- ✅ Los archivos estén en /var/www/{mi_proyecto}/current/dist/
5. Configurar Nginx
Section titled “5. Configurar Nginx”- Crear archivo de configuración
sudo nano /etc/nginx/sites-available/{mi_proyecto} - Configuración nginx:
# HTTP to HTTPS redirectserver { listen 80; listen [::]:80; server_name {mi_proyecto} www.{mi_proyecto};
# Permitir validación de Certbot location ^~ /.well-known/acme-challenge/ { default_type "text/plain"; root /var/www/{mi_proyecto}/current/dist; }
location / { return 301 https://{mi_proyecto}$request_uri; }}
# HTTPS www to non-www redirectserver { listen 443 ssl http2; listen [::]:443 ssl http2; server_name www.{mi_proyecto};
ssl_certificate /etc/letsencrypt/live/{mi_proyecto}/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/{mi_proyecto}/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
return 301 https://{mi_proyecto}$request_uri;}
# Main HTTPS serverserver { listen 443 ssl http2; listen [::]:443 ssl http2; server_name {mi_proyecto};
# SSL Configuration ssl_certificate /etc/letsencrypt/live/{mi_proyecto}/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/{mi_proyecto}/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Directorio del build de Astro root /var/www/{mi_proyecto}/current/dist; index index.html;
# Logs access_log /var/log/nginx/{mi_proyecto}.access.log; error_log /var/log/nginx/{mi_proyecto}.error.log;
# Compresión Gzip gzip on; gzip_vary on; gzip_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml+rss application/rss+xml font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml; gzip_min_length 1000;
# Configuración para sitio estático (Astro) location / { try_files $uri $uri/ $uri.html /404.html =404; }
# Caché agresivo para assets estáticos location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|webp|avif)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; }
# Bloquear archivos ocultos location ~ /\. { deny all; access_log off; log_not_found off; }
# Headers de seguridad 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;
# CSP básico (ajustar según necesidades) add_header Content-Security-Policy "default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval'; img-src 'self' data: blob: https:; connect-src 'self' https: wss:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:;" always;}Importante: Solo un servidor puede tener la directiva default_server. Si encuentras otro, remuévela de tu configuración.
6. Habilitar Sitio en Nginx
Section titled “6. Habilitar Sitio en Nginx”- Crear enlace simbólico
sudo ln -s /etc/nginx/sites-available/{mi_proyecto} /etc/nginx/sites-enabled/{mi_proyecto}
7. Validar Configuración de Nginx
Section titled “7. Validar Configuración de Nginx”- Comentar TODAS las líneas que empiezan con
ssl_en los bloques HTTPS (puerto 443, incluyendossl_certificateeinclude) Ejemplo de qué comentar:
# ssl_certificate /etc/letsencrypt/live/{mi_proyecto}/fullchain.pem;# ssl_certificate_key /etc/letsencrypt/live/{mi_proyecto}/privkey.pem;# include /etc/letsencrypt/options-ssl-nginx.conf;# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;- Ejecutar
sudo nginx -t - Resultado esperado:
nginx: the configuration file /etc/nginx/nginx.conf syntax is oknginx: configuration file /etc/nginx/nginx.conf test is successfulSi hay errores:
- Revisa la sintaxis del archivo
- Verifica que las rutas existan
- Comprueba los permisos
8. Generar Certificado SSL
Section titled “8. Generar Certificado SSL”- Recarga nginx
sudo systemctl reload nginx - Genera el certificado
sudo certbot --nginx certonly -d {mi_proyecto} -d www.{mi_proyecto} - Configurar renovación automática
# Verificar que el timer esté activosudo systemctl status certbot.timer
# Probar renovaciónsudo certbot renew --dry-run9. Aplicar Configuración Final
Section titled “9. Aplicar Configuración Final”- Descomenta las líneas SSL si las comentaste antes
sudo nano /etc/nginx/sites-available/{mi_proyecto} - Verifica la configuración
sudo nginx -t - Recarga Nginx
sudo systemctl reload nginx
# Descomenta las líneas ssl_ si las comentaste antessudo nano /etc/nginx/sites-available/{mi_proyecto}
# Verifica la configuraciónsudo nginx -t
# Recarga Nginxsudo systemctl reload nginx10. Verificación Final
Section titled “10. Verificación Final”Comprobar que el sitio funciona
# Estado de Nginxsudo systemctl status nginx
# Ver logs en tiempo realsudo tail -f /var/log/nginx/{mi_proyecto}.access.logsudo tail -f /var/log/nginx/{mi_proyecto}.error.logPruebas desde navegador:
- ✅ http://{mi_proyecto} → redirige a https
- ✅ https://www.{mi_proyecto} → redirige a https://{mi_proyecto}
- ✅ https://{mi_proyecto} → muestra el sitio
- ✅ Certificado SSL válido (candado verde)