partial update create nginx proxy https

This commit is contained in:
2025-06-26 17:19:21 +07:00
parent fc98479362
commit 9b3889ef1f
6 changed files with 674 additions and 53 deletions

289
DEPLOYMENT.md Normal file
View File

@@ -0,0 +1,289 @@
# CKB Application Deployment Guide
## Overview
This guide explains how to deploy the CKB Laravel application with Docker, SSL certificate, and reverse proxy configuration.
## Prerequisites
- Ubuntu/Debian server
- Docker and Docker Compose installed
- Domain pointing to server IP
- Nginx installed on main server
- Root/sudo access
## Architecture
```
Internet → Nginx (Port 80/443) → Docker Container (Port 8082) → Laravel App
```
## File Structure
```
/var/www/ckb/
├── docker-compose.prod.yml # Docker services configuration
├── Dockerfile # Laravel app container
├── docker/
│ ├── nginx-proxy.conf # Internal nginx proxy
│ ├── php.ini # PHP configuration
│ ├── mysql.cnf # MySQL configuration
│ └── supervisord.conf # Process manager
├── nginx-ckb-reverse-proxy.conf # Main server nginx config
├── deploy-ckb.sh # Deployment script
├── setup-ssl.sh # SSL certificate setup script
└── DEPLOYMENT.md # This file
```
## Container Names and Volumes
All containers and volumes are prefixed with `ckb-` to avoid conflicts:
### Containers:
- `ckb-laravel-app` - Laravel application
- `ckb-mariadb` - Database
- `ckb-redis` - Cache/Queue
- `ckb-nginx-proxy` - Internal nginx proxy
### Volumes:
- `ckb_mysql_data` - Database data
- `ckb_redis_data` - Redis data
- `ckb_nginx_logs` - Nginx logs
- `ckb_storage_logs` - Laravel logs
- `ckb_storage_cache` - Laravel cache
## Step-by-Step Deployment
### Step 1: Prepare the Application
```bash
cd /var/www/ckb
# Make scripts executable
chmod +x deploy-ckb.sh
chmod +x setup-ssl.sh
```
### Step 2: Deploy Docker Application
```bash
# Run deployment script
./deploy-ckb.sh
```
This script will:
- Stop existing containers
- Build and start new containers
- Check if containers are running
- Verify port 8082 is accessible
### Step 3: Setup SSL Certificate
```bash
# Run SSL setup script (requires sudo)
sudo ./setup-ssl.sh
```
This script will:
- Install certbot if not present
- Create temporary nginx configuration
- Generate Let's Encrypt certificate
- Update nginx with SSL configuration
- Setup auto-renewal
### Step 4: Manual Verification
```bash
# Check if containers are running
docker ps | grep ckb
# Check if port 8082 is accessible
curl -I http://localhost:8082
# Check SSL certificate
sudo certbot certificates
# Test HTTPS access
curl -I https://bengkel.digitaloasis.xyz
```
## Configuration Files
### docker-compose.prod.yml
- Updated container names with `ckb-` prefix
- Removed certbot service (handled by main server)
- Updated APP_URL to use HTTPS
- Specific volume names to avoid conflicts
### nginx-proxy.conf
- Simplified configuration (no SSL handling)
- Proxy to `ckb-app` container
- Rate limiting and security headers
- Static file caching
### nginx-ckb-reverse-proxy.conf
- Main server nginx configuration
- SSL termination
- Reverse proxy to port 8082
- Security headers and SSL settings
## Environment Variables
Create `.env` file in `/var/www/ckb/`:
```env
APP_ENV=production
APP_DEBUG=false
APP_URL=https://bengkel.digitaloasis.xyz
DB_DATABASE=ckb_production
DB_USERNAME=laravel
DB_PASSWORD=your_password
DB_ROOT_PASSWORD=your_root_password
REDIS_PASSWORD=your_redis_password
```
## Monitoring and Maintenance
### View Logs
```bash
# Docker logs
docker-compose -f docker-compose.prod.yml logs -f
# Nginx logs (main server)
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log
# Laravel logs
docker exec ckb-laravel-app tail -f /var/www/html/storage/logs/laravel.log
```
### SSL Certificate Renewal
```bash
# Manual renewal
sudo certbot renew
# Check renewal status
sudo certbot certificates
```
### Container Management
```bash
# Restart all services
docker-compose -f docker-compose.prod.yml restart
# Update application
git pull
docker-compose -f docker-compose.prod.yml up -d --build
# Stop all services
docker-compose -f docker-compose.prod.yml down
# Remove all data (WARNING: This will delete all data)
docker-compose -f docker-compose.prod.yml down -v
```
## Troubleshooting
### Port 8082 Not Accessible
```bash
# Check if container is running
docker ps | grep ckb-nginx-proxy
# Check container logs
docker-compose -f docker-compose.prod.yml logs ckb-nginx-proxy
# Check if port is bound
netstat -tlnp | grep 8082
```
### SSL Certificate Issues
```bash
# Check certificate status
sudo certbot certificates
# Test certificate
sudo certbot renew --dry-run
# Check nginx configuration
sudo nginx -t
```
### Database Connection Issues
```bash
# Check database container
docker exec ckb-mariadb mysql -u root -p -e "SHOW DATABASES;"
# Check Laravel database connection
docker exec ckb-laravel-app php artisan tinker
```
### Permission Issues
```bash
# Fix Laravel permissions
docker exec ckb-laravel-app chown -R www-data:www-data /var/www/html
docker exec ckb-laravel-app chmod -R 775 /var/www/html/storage
docker exec ckb-laravel-app chmod -R 775 /var/www/html/bootstrap/cache
```
## Security Considerations
1. **Firewall**: Ensure only necessary ports are open
2. **SSL**: Certificate auto-renewal is configured
3. **Rate Limiting**: Configured for login and API endpoints
4. **Security Headers**: HSTS, XSS protection, etc.
5. **File Permissions**: Proper Laravel file permissions
6. **Database**: Strong passwords and limited access
## Backup Strategy
### Database Backup
```bash
# Create backup
docker exec ckb-mariadb mysqldump -u root -p ckb_production > backup.sql
# Restore backup
docker exec -i ckb-mariadb mysql -u root -p ckb_production < backup.sql
```
### Application Backup
```bash
# Backup application files
tar -czf ckb-backup-$(date +%Y%m%d).tar.gz /var/www/ckb/
# Backup volumes
docker run --rm -v ckb_mysql_data:/data -v $(pwd):/backup alpine tar czf /backup/mysql-backup.tar.gz -C /data .
```
## Performance Optimization
1. **Nginx**: Gzip compression enabled
2. **Laravel**: Production optimizations
3. **Database**: Proper indexing
4. **Redis**: Caching and session storage
5. **Static Files**: Long-term caching headers
## Support
For issues or questions:
1. Check logs first
2. Verify configuration files
3. Test connectivity step by step
4. Check system resources
5. Review security settings

105
deploy-ckb.sh Executable file
View File

@@ -0,0 +1,105 @@
#!/bin/bash
# CKB Application Deployment Script
# This script sets up SSL certificate and deploys the CKB application
set -e
echo "=== CKB Application Deployment Script ==="
echo "Domain: bengkel.digitaloasis.xyz"
echo "Port: 8082"
echo ""
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if running as root
if [[ $EUID -eq 0 ]]; then
print_error "This script should not be run as root"
exit 1
fi
# Check if we're in the correct directory
if [ ! -f "docker-compose.prod.yml" ]; then
print_error "Please run this script from the CKB application directory (/var/www/ckb)"
exit 1
fi
print_status "Starting CKB application deployment..."
# Step 1: Stop existing containers
print_status "Stopping existing containers..."
docker-compose -f docker-compose.prod.yml down
# Step 2: Build and start containers
print_status "Building and starting containers..."
docker-compose -f docker-compose.prod.yml up -d --build
# Step 3: Wait for containers to be ready
print_status "Waiting for containers to be ready..."
sleep 10
# Step 4: Check if containers are running
print_status "Checking container status..."
if docker ps | grep -q "ckb-laravel-app"; then
print_status "CKB Laravel app is running"
else
print_error "CKB Laravel app is not running"
exit 1
fi
if docker ps | grep -q "ckb-nginx-proxy"; then
print_status "CKB Nginx proxy is running"
else
print_error "CKB Nginx proxy is not running"
exit 1
fi
# Step 5: Check if port 8082 is accessible
print_status "Checking if port 8082 is accessible..."
if curl -s -o /dev/null -w "%{http_code}" http://localhost:8082 | grep -q "200\|301\|302"; then
print_status "Port 8082 is accessible"
else
print_warning "Port 8082 might not be accessible yet, waiting..."
sleep 5
if curl -s -o /dev/null -w "%{http_code}" http://localhost:8082 | grep -q "200\|301\|302"; then
print_status "Port 8082 is now accessible"
else
print_error "Port 8082 is not accessible"
print_status "Checking container logs..."
docker-compose -f docker-compose.prod.yml logs ckb-nginx-proxy
exit 1
fi
fi
print_status "CKB application deployment completed successfully!"
echo ""
print_status "Next steps:"
echo "1. Configure Nginx reverse proxy on the main server:"
echo " sudo cp nginx-ckb-reverse-proxy.conf /etc/nginx/sites-available/bengkel.digitaloasis.xyz"
echo " sudo ln -s /etc/nginx/sites-available/bengkel.digitaloasis.xyz /etc/nginx/sites-enabled/"
echo ""
echo "2. Generate SSL certificate:"
echo " sudo certbot certonly --webroot --webroot-path=/var/www/html --email admin@digitaloasis.xyz --agree-tos --no-eff-email -d bengkel.digitaloasis.xyz -d www.bengkel.digitaloasis.xyz"
echo ""
echo "3. Test and reload Nginx:"
echo " sudo nginx -t"
echo " sudo systemctl reload nginx"
echo ""
print_status "Application will be accessible at: https://bengkel.digitaloasis.xyz"

View File

@@ -1,32 +1,32 @@
services: services:
app: ckb-app:
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: ckb-app-prod container_name: ckb-laravel-app
restart: unless-stopped restart: unless-stopped
working_dir: /var/www/html working_dir: /var/www/html
volumes: volumes:
- ./storage:/var/www/html/storage - ./storage:/var/www/html/storage
- ./bootstrap/cache:/var/www/html/bootstrap/cache - ./bootstrap/cache:/var/www/html/bootstrap/cache
- ./docker/php.ini:/usr/local/etc/php/conf.d/local.ini - ./docker/php.ini:/usr/local/etc/php/conf.d/local.ini
- storage_logs:/var/www/html/storage/logs - ckb_storage_logs:/var/www/html/storage/logs
- storage_cache:/var/www/html/storage/framework - ckb_storage_cache:/var/www/html/storage/framework
environment: environment:
- APP_ENV=production - APP_ENV=production
- APP_DEBUG=false - APP_DEBUG=false
- APP_URL=http://bengkel.digitaloasis.xyz:8082 - APP_URL=https://bengkel.digitaloasis.xyz
- TRUSTED_PROXIES=* - TRUSTED_PROXIES=*
depends_on: depends_on:
- db - ckb-db
- redis - ckb-redis
networks: networks:
- ckb-network - ckb-network
db: ckb-db:
image: mariadb:10.6 image: mariadb:10.6
platform: linux/amd64 platform: linux/amd64
container_name: ckb-mysql-prod container_name: ckb-mariadb
restart: unless-stopped restart: unless-stopped
environment: environment:
MYSQL_DATABASE: ${DB_DATABASE:-ckb_production} MYSQL_DATABASE: ${DB_DATABASE:-ckb_production}
@@ -34,7 +34,7 @@ services:
MYSQL_PASSWORD: ${DB_PASSWORD:-password} MYSQL_PASSWORD: ${DB_PASSWORD:-password}
MYSQL_USER: ${DB_USERNAME:-laravel} MYSQL_USER: ${DB_USERNAME:-laravel}
volumes: volumes:
- mysql_data:/var/lib/mysql - ckb_mysql_data:/var/lib/mysql
- ./ckb.sql:/docker-entrypoint-initdb.d/01-init.sql:ro - ./ckb.sql:/docker-entrypoint-initdb.d/01-init.sql:ro
- ./docker/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro - ./docker/mysql.cnf:/etc/mysql/conf.d/mysql.cnf:ro
expose: expose:
@@ -43,19 +43,19 @@ services:
- ckb-network - ckb-network
command: --default-authentication-plugin=mysql_native_password command: --default-authentication-plugin=mysql_native_password
redis: ckb-redis:
image: redis:7-alpine image: redis:7-alpine
container_name: ckb-redis-prod container_name: ckb-redis
restart: unless-stopped restart: unless-stopped
command: redis-server --appendonly yes ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD} command: redis-server --appendonly yes ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD}
volumes: volumes:
- redis_data:/data - ckb_redis_data:/data
expose: expose:
- "6379" - "6379"
networks: networks:
- ckb-network - ckb-network
nginx-proxy: ckb-nginx-proxy:
image: nginx:alpine image: nginx:alpine
container_name: ckb-nginx-proxy container_name: ckb-nginx-proxy
restart: unless-stopped restart: unless-stopped
@@ -63,42 +63,24 @@ services:
- "8082:80" - "8082:80"
volumes: volumes:
- ./docker/nginx-proxy.conf:/etc/nginx/nginx.conf:ro - ./docker/nginx-proxy.conf:/etc/nginx/nginx.conf:ro
- certbot_www:/var/www/certbot:ro - ckb_nginx_logs:/var/log/nginx
- nginx_logs:/var/log/nginx
depends_on: depends_on:
- app - ckb-app
networks: networks:
- ckb-network - ckb-network
environment: environment:
- DOMAIN=bengkel.digitaloasis.xyz - DOMAIN=bengkel.digitaloasis.xyz
certbot:
image: certbot/certbot
container_name: ckb-certbot
restart: "no"
volumes:
- ssl_certificates:/etc/letsencrypt
- certbot_www:/var/www/certbot
command: certonly --webroot --webroot-path=/var/www/certbot --email admin@digitaloasis.xyz --agree-tos --no-eff-email -d bengkel.digitaloasis.xyz -d www.bengkel.digitaloasis.xyz
depends_on:
- nginx-proxy
networks:
- ckb-network
volumes: volumes:
mysql_data: ckb_mysql_data:
driver: local driver: local
redis_data: ckb_redis_data:
driver: local driver: local
ssl_certificates: ckb_nginx_logs:
driver: local driver: local
certbot_www: ckb_storage_logs:
driver: local driver: local
nginx_logs: ckb_storage_cache:
driver: local
storage_logs:
driver: local
storage_cache:
driver: local driver: local
networks: networks:

View File

@@ -42,8 +42,8 @@ http {
limit_req_zone $binary_remote_addr zone=api:10m rate=60r/m; limit_req_zone $binary_remote_addr zone=api:10m rate=60r/m;
# Upstream to Laravel app # Upstream to Laravel app
upstream app { upstream ckb-app {
server app:80; server ckb-app:80;
} }
# HTTP server configuration # HTTP server configuration
@@ -51,14 +51,9 @@ http {
listen 80; listen 80;
server_name bengkel.digitaloasis.xyz www.bengkel.digitaloasis.xyz localhost _; server_name bengkel.digitaloasis.xyz www.bengkel.digitaloasis.xyz localhost _;
# Let's Encrypt challenge
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# Handle static files with proper headers # Handle static files with proper headers
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf)$ { location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|otf)$ {
proxy_pass http://app; proxy_pass http://ckb-app;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -79,7 +74,7 @@ http {
# Handle Laravel Mix versioned assets # Handle Laravel Mix versioned assets
location ~* \.(css|js)\?id=[a-zA-Z0-9]+ { location ~* \.(css|js)\?id=[a-zA-Z0-9]+ {
proxy_pass http://app; proxy_pass http://ckb-app;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -101,7 +96,7 @@ http {
# Rate limiting for login endpoints # Rate limiting for login endpoints
location ~ ^/(login|register|password) { location ~ ^/(login|register|password) {
limit_req zone=login burst=5 nodelay; limit_req zone=login burst=5 nodelay;
proxy_pass http://app; proxy_pass http://ckb-app;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -116,7 +111,7 @@ http {
# Rate limiting for API endpoints # Rate limiting for API endpoints
location /api/ { location /api/ {
limit_req zone=api burst=20 nodelay; limit_req zone=api burst=20 nodelay;
proxy_pass http://app; proxy_pass http://ckb-app;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
@@ -131,16 +126,16 @@ http {
# Health check endpoint # Health check endpoint
location /health { location /health {
access_log off; access_log off;
proxy_pass http://app; proxy_pass http://ckb-app;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
} }
# Main application for HTTP (catch-all) # Main application (catch-all)
location / { location / {
proxy_pass http://app; proxy_pass http://ckb-app;
proxy_set_header Host $host; proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

View File

@@ -0,0 +1,59 @@
# HTTP server (redirect to HTTPS)
server {
listen 80;
server_name bengkel.digitaloasis.xyz www.bengkel.digitaloasis.xyz;
# Let's Encrypt challenge
location /.well-known/acme-challenge/ {
root /var/www/html;
}
# Redirect to HTTPS
location / {
return 301 https://$server_name$request_uri;
}
}
# HTTPS server
server {
listen 443 ssl http2;
server_name bengkel.digitaloasis.xyz www.bengkel.digitaloasis.xyz;
# SSL configuration
ssl_certificate /etc/letsencrypt/live/bengkel.digitaloasis.xyz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bengkel.digitaloasis.xyz/privkey.pem;
# SSL security settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
# Proxy to Docker application on port 8082
location / {
proxy_pass http://localhost:8082;
proxy_set_header Host $host;
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;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Port $server_port;
# Proxy timeouts
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
# Buffer settings
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
}

191
setup-ssl.sh Executable file
View File

@@ -0,0 +1,191 @@
#!/bin/bash
# SSL Certificate Setup Script for CKB Application
# This script sets up SSL certificate using Let's Encrypt
set -e
echo "=== SSL Certificate Setup for CKB Application ==="
echo "Domain: bengkel.digitaloasis.xyz"
echo ""
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Function to print colored output
print_status() {
echo -e "${GREEN}[INFO]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
print_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check if running as root
if [[ $EUID -ne 0 ]]; then
print_error "This script must be run as root (use sudo)"
exit 1
fi
# Check if certbot is installed
if ! command -v certbot &> /dev/null; then
print_status "Installing certbot..."
apt update
apt install -y certbot
fi
# Check if nginx is installed
if ! command -v nginx &> /dev/null; then
print_error "Nginx is not installed. Please install Nginx first."
exit 1
fi
# Step 1: Create temporary Nginx configuration for Let's Encrypt challenge
print_status "Creating temporary Nginx configuration for Let's Encrypt challenge..."
cat > /etc/nginx/sites-available/bengkel.digitaloasis.xyz << 'EOF'
server {
listen 80;
server_name bengkel.digitaloasis.xyz www.bengkel.digitaloasis.xyz;
# Root directory untuk Let's Encrypt challenge
root /var/www/html;
# Let's Encrypt challenge location
location /.well-known/acme-challenge/ {
root /var/www/html;
}
# Redirect semua traffic HTTP ke HTTPS (akan diaktifkan setelah SSL)
location / {
return 301 https://$server_name$request_uri;
}
}
EOF
# Step 2: Enable the site
print_status "Enabling Nginx site..."
ln -sf /etc/nginx/sites-available/bengkel.digitaloasis.xyz /etc/nginx/sites-enabled/
# Step 3: Test and reload Nginx
print_status "Testing Nginx configuration..."
nginx -t
print_status "Reloading Nginx..."
systemctl reload nginx
# Step 4: Generate SSL certificate
print_status "Generating SSL certificate with Let's Encrypt..."
certbot certonly --webroot \
--webroot-path=/var/www/html \
--email admin@digitaloasis.xyz \
--agree-tos \
--no-eff-email \
-d bengkel.digitaloasis.xyz \
-d www.bengkel.digitaloasis.xyz
# Step 5: Check if certificate was generated successfully
if [ -f "/etc/letsencrypt/live/bengkel.digitaloasis.xyz/fullchain.pem" ]; then
print_status "SSL certificate generated successfully!"
else
print_error "SSL certificate generation failed!"
exit 1
fi
# Step 6: Update Nginx configuration with SSL
print_status "Updating Nginx configuration with SSL..."
cat > /etc/nginx/sites-available/bengkel.digitaloasis.xyz << 'EOF'
# HTTP server (redirect to HTTPS)
server {
listen 80;
server_name bengkel.digitaloasis.xyz www.bengkel.digitaloasis.xyz;
# Let's Encrypt challenge
location /.well-known/acme-challenge/ {
root /var/www/html;
}
# Redirect to HTTPS
location / {
return 301 https://$server_name$request_uri;
}
}
# HTTPS server
server {
listen 443 ssl http2;
server_name bengkel.digitaloasis.xyz www.bengkel.digitaloasis.xyz;
# SSL configuration
ssl_certificate /etc/letsencrypt/live/bengkel.digitaloasis.xyz/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/bengkel.digitaloasis.xyz/privkey.pem;
# SSL security settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
# Proxy to Docker application on port 8082
location / {
proxy_pass http://localhost:8082;
proxy_set_header Host $host;
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;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Port $server_port;
# Proxy timeouts
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
# Buffer settings
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
}
EOF
# Step 7: Test and reload Nginx
print_status "Testing Nginx configuration with SSL..."
nginx -t
print_status "Reloading Nginx with SSL configuration..."
systemctl reload nginx
# Step 8: Setup auto-renewal
print_status "Setting up SSL certificate auto-renewal..."
(crontab -l 2>/dev/null; echo "0 12 * * * /usr/bin/certbot renew --quiet") | crontab -
# Step 9: Test SSL certificate
print_status "Testing SSL certificate..."
if curl -s -o /dev/null -w "%{http_code}" https://bengkel.digitaloasis.xyz | grep -q "200\|301\|302"; then
print_status "SSL certificate is working correctly!"
else
print_warning "SSL certificate might not be working yet. Please check manually."
fi
print_status "SSL certificate setup completed successfully!"
echo ""
print_status "Certificate information:"
certbot certificates
echo ""
print_status "Your application should now be accessible at: https://bengkel.digitaloasis.xyz"