283 lines
7.9 KiB
Bash
Executable File
283 lines
7.9 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Script untuk setup SSL certificate dengan Let's Encrypt untuk domain bengkel.digitaloasis.xyz
|
|
# Usage: ./docker-ssl-setup.sh
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Configuration
|
|
DOMAIN="bengkel.digitaloasis.xyz"
|
|
WWW_DOMAIN="www.bengkel.digitaloasis.xyz"
|
|
EMAIL="admin@digitaloasis.xyz"
|
|
COMPOSE_FILE="docker-compose.prod.yml"
|
|
|
|
# Function to print colored output
|
|
print_status() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
print_success() {
|
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
}
|
|
|
|
print_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
print_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
# Function to check if Docker is running
|
|
check_docker() {
|
|
if ! docker info > /dev/null 2>&1; then
|
|
print_error "Docker is not running. Please start Docker first."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Function to check if domain is pointing to this server
|
|
check_domain() {
|
|
print_status "Checking if domain $DOMAIN is pointing to this server..."
|
|
|
|
# Get current server IP
|
|
SERVER_IP=$(curl -s ifconfig.me || curl -s icanhazip.com || echo "Unable to detect")
|
|
|
|
# Get domain IP
|
|
DOMAIN_IP=$(dig +short $DOMAIN | head -n1)
|
|
|
|
print_status "Server IP: $SERVER_IP"
|
|
print_status "Domain IP: $DOMAIN_IP"
|
|
|
|
if [[ "$SERVER_IP" != "$DOMAIN_IP" ]]; then
|
|
print_warning "Domain might not be pointing to this server!"
|
|
print_warning "Please make sure DNS is configured correctly before proceeding."
|
|
read -p "Continue anyway? (y/N): " -n 1 -r
|
|
echo ""
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
print_status "SSL setup cancelled."
|
|
exit 0
|
|
fi
|
|
else
|
|
print_success "Domain is correctly pointing to this server!"
|
|
fi
|
|
}
|
|
|
|
# Function to create temporary nginx config for initial certificate
|
|
create_temp_nginx() {
|
|
print_status "Creating temporary nginx configuration for initial certificate..."
|
|
|
|
cat > docker/nginx-temp.conf << 'EOF'
|
|
events {
|
|
worker_connections 1024;
|
|
}
|
|
|
|
http {
|
|
server {
|
|
listen 80;
|
|
server_name bengkel.digitaloasis.xyz www.bengkel.digitaloasis.xyz;
|
|
|
|
location /.well-known/acme-challenge/ {
|
|
root /var/www/certbot;
|
|
}
|
|
|
|
location / {
|
|
return 200 'SSL setup in progress...';
|
|
add_header Content-Type text/plain;
|
|
}
|
|
}
|
|
}
|
|
EOF
|
|
}
|
|
|
|
# Function to start nginx with temporary config
|
|
start_temp_nginx() {
|
|
print_status "Starting nginx with temporary configuration..."
|
|
|
|
# Update docker-compose to use temporary config
|
|
sed -i 's|nginx-proxy.conf|nginx-temp.conf|g' $COMPOSE_FILE
|
|
|
|
# Start nginx-proxy
|
|
docker-compose -f $COMPOSE_FILE up -d nginx-proxy
|
|
|
|
# Wait for nginx to be ready
|
|
sleep 10
|
|
}
|
|
|
|
# Function to obtain SSL certificate
|
|
obtain_certificate() {
|
|
print_status "Obtaining SSL certificate from Let's Encrypt..."
|
|
|
|
# Run certbot
|
|
docker-compose -f $COMPOSE_FILE run --rm certbot certonly \
|
|
--webroot \
|
|
--webroot-path=/var/www/certbot \
|
|
--email $EMAIL \
|
|
--agree-tos \
|
|
--no-eff-email \
|
|
--force-renewal \
|
|
-d $DOMAIN \
|
|
-d $WWW_DOMAIN
|
|
|
|
if [[ $? -eq 0 ]]; then
|
|
print_success "SSL certificate obtained successfully!"
|
|
else
|
|
print_error "Failed to obtain SSL certificate!"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Function to setup certificate files
|
|
setup_certificate_files() {
|
|
print_status "Setting up certificate files for nginx..."
|
|
|
|
# Copy certificates to nginx ssl directory
|
|
docker run --rm \
|
|
-v ckb_ssl_certificates:/source \
|
|
-v ckb_ssl_certificates:/target \
|
|
alpine sh -c "
|
|
mkdir -p /target/live/$DOMAIN
|
|
cp -L /source/live/$DOMAIN/fullchain.pem /target/fullchain.pem
|
|
cp -L /source/live/$DOMAIN/privkey.pem /target/privkey.pem
|
|
chmod 644 /target/fullchain.pem
|
|
chmod 600 /target/privkey.pem
|
|
"
|
|
|
|
print_success "Certificate files setup completed!"
|
|
}
|
|
|
|
# Function to restore production nginx config
|
|
restore_production_config() {
|
|
print_status "Restoring production nginx configuration..."
|
|
|
|
# Restore original config
|
|
sed -i 's|nginx-temp.conf|nginx-proxy.conf|g' $COMPOSE_FILE
|
|
|
|
# Restart nginx with SSL configuration
|
|
docker-compose -f $COMPOSE_FILE up -d nginx-proxy
|
|
|
|
print_success "Production nginx configuration restored!"
|
|
}
|
|
|
|
# Function to test SSL certificate
|
|
test_ssl() {
|
|
print_status "Testing SSL certificate..."
|
|
|
|
sleep 10
|
|
|
|
# Test HTTPS connection
|
|
if curl -s --max-time 10 https://$DOMAIN > /dev/null; then
|
|
print_success "HTTPS is working correctly!"
|
|
else
|
|
print_warning "HTTPS test failed. Please check the configuration."
|
|
fi
|
|
|
|
# Test certificate validity
|
|
if openssl s_client -connect $DOMAIN:443 -servername $DOMAIN < /dev/null 2>/dev/null | openssl x509 -noout -dates; then
|
|
print_success "Certificate information retrieved successfully!"
|
|
else
|
|
print_warning "Could not retrieve certificate information."
|
|
fi
|
|
}
|
|
|
|
# Function to setup certificate renewal
|
|
setup_renewal() {
|
|
print_status "Setting up automatic certificate renewal..."
|
|
|
|
# Create renewal script
|
|
cat > docker-ssl-renew.sh << 'EOF'
|
|
#!/bin/bash
|
|
|
|
# SSL Certificate Renewal Script
|
|
# Add this to crontab: 0 12 * * * /path/to/docker-ssl-renew.sh
|
|
|
|
docker-compose -f docker-compose.prod.yml run --rm certbot renew --quiet
|
|
|
|
# Reload nginx if certificate was renewed
|
|
if [[ $? -eq 0 ]]; then
|
|
# Copy renewed certificates
|
|
docker run --rm \
|
|
-v ckb_ssl_certificates:/source \
|
|
-v ckb_ssl_certificates:/target \
|
|
alpine sh -c "
|
|
cp -L /source/live/bengkel.digitaloasis.xyz/fullchain.pem /target/fullchain.pem
|
|
cp -L /source/live/bengkel.digitaloasis.xyz/privkey.pem /target/privkey.pem
|
|
"
|
|
|
|
# Reload nginx
|
|
docker-compose -f docker-compose.prod.yml exec nginx-proxy nginx -s reload
|
|
fi
|
|
EOF
|
|
|
|
chmod +x docker-ssl-renew.sh
|
|
|
|
print_success "Certificate renewal script created: docker-ssl-renew.sh"
|
|
print_status "To setup automatic renewal, add this to crontab:"
|
|
echo "0 12 * * * $(pwd)/docker-ssl-renew.sh"
|
|
}
|
|
|
|
# Function to show final information
|
|
show_final_info() {
|
|
echo ""
|
|
print_success "🎉 SSL setup completed successfully!"
|
|
echo ""
|
|
print_status "Your application is now available at:"
|
|
echo " 🌐 https://bengkel.digitaloasis.xyz"
|
|
echo " 🌐 https://www.bengkel.digitaloasis.xyz"
|
|
echo ""
|
|
print_status "SSL Certificate Information:"
|
|
echo " 📅 Domain: $DOMAIN, $WWW_DOMAIN"
|
|
echo " 📧 Email: $EMAIL"
|
|
echo " 🔄 Auto-renewal: Setup docker-ssl-renew.sh in crontab"
|
|
echo ""
|
|
print_status "Useful Commands:"
|
|
echo " - Check certificate: openssl s_client -connect $DOMAIN:443 -servername $DOMAIN"
|
|
echo " - Renew certificate: ./docker-ssl-renew.sh"
|
|
echo " - View logs: docker-compose -f $COMPOSE_FILE logs nginx-proxy"
|
|
echo " - Test renewal: docker-compose -f $COMPOSE_FILE run --rm certbot renew --dry-run"
|
|
}
|
|
|
|
# Main execution
|
|
echo "================================================"
|
|
print_status "🔒 SSL Certificate Setup for CKB Production"
|
|
print_status "Domain: $DOMAIN"
|
|
echo "================================================"
|
|
echo ""
|
|
|
|
# Check prerequisites
|
|
check_docker
|
|
check_domain
|
|
|
|
# Ask for confirmation
|
|
print_warning "This will setup SSL certificate for $DOMAIN"
|
|
print_status "Make sure your application is not currently running."
|
|
read -p "Continue with SSL setup? (y/N): " -n 1 -r
|
|
echo ""
|
|
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
print_status "SSL setup cancelled."
|
|
exit 0
|
|
fi
|
|
|
|
# Execute SSL setup
|
|
print_status "Starting SSL certificate setup process..."
|
|
|
|
create_temp_nginx
|
|
start_temp_nginx
|
|
obtain_certificate
|
|
setup_certificate_files
|
|
restore_production_config
|
|
test_ssl
|
|
setup_renewal
|
|
|
|
# Show final information
|
|
show_final_info
|
|
|
|
print_success "✅ SSL setup completed successfully!" |