add docker for server demo

This commit is contained in:
arifal
2025-06-26 18:28:26 +07:00
parent c33193d5f0
commit a7f578ca3d
23 changed files with 2420 additions and 431 deletions

View File

@@ -0,0 +1,55 @@
[mysqld]
# Basic Settings
default-storage-engine = innodb
sql-mode = "STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
max_connections = 200
max_user_connections = 180
# Character Set
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# InnoDB Settings
innodb_buffer_pool_size = 1G
innodb_buffer_pool_instances = 4
innodb_log_file_size = 256M
innodb_log_buffer_size = 64M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
innodb_open_files = 400
# Query Cache (disabled in MySQL 8.0+, but kept for compatibility)
query_cache_type = OFF
query_cache_size = 0
# Temp Tables
tmp_table_size = 64M
max_heap_table_size = 64M
# Logging
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 2
log_queries_not_using_indexes = 1
# Binary Logging
log-bin = mysql-bin
binlog_format = ROW
expire_logs_days = 7
max_binlog_size = 100M
# Safety
max_allowed_packet = 64M
bind-address = 0.0.0.0
# Performance Schema
performance_schema = ON
performance_schema_max_table_instances = 400
performance_schema_max_table_handles = 4000
[mysql]
default-character-set = utf8mb4
[client]
default-character-set = utf8mb4

32
docker/nginx/Dockerfile Normal file
View File

@@ -0,0 +1,32 @@
FROM nginx:alpine
# Install required packages
RUN apk add --no-cache \
openssl \
certbot \
certbot-nginx \
bash
# Create SSL directory
RUN mkdir -p /etc/nginx/ssl
# Copy SSL certificates (if they exist)
COPY ssl/ /etc/nginx/ssl/
# Copy Nginx configuration
COPY conf.d/ /etc/nginx/conf.d/
# Create log directories
RUN mkdir -p /var/log/nginx
# Copy SSL setup script
COPY ssl-setup.sh /usr/local/bin/ssl-setup.sh
RUN chmod +x /usr/local/bin/ssl-setup.sh
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost/health-check || exit 1
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]

View File

@@ -0,0 +1,113 @@
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
# Redirect HTTP to HTTPS
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name yourdomain.com www.yourdomain.com;
root /var/www/public;
index index.php index.html index.htm;
# SSL Configuration
ssl_certificate /etc/nginx/ssl/certificate.crt;
ssl_certificate_key /etc/nginx/ssl/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Security Headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Gzip Compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied expired no-cache no-store private auth;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/x-javascript
application/xml+rss
application/javascript
application/json
application/xml
image/svg+xml;
# Client Max Body Size
client_max_body_size 100M;
# Health check endpoint
location /health-check {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# Handle static files
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
try_files $uri =404;
}
# Deny access to sensitive files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
location ~ ^/(\.env|\.git|composer\.(json|lock)|package\.(json|lock)|webpack\.(mix\.js|config\.js)|.*\.md)$ {
deny all;
access_log off;
log_not_found off;
}
# Laravel-specific rules
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass app:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
# Production optimizations
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_connect_timeout 60s;
fastcgi_send_timeout 60s;
fastcgi_read_timeout 60s;
}
# Error pages
error_page 404 /index.php;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# Logging
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log warn;
}

View File

@@ -0,0 +1,137 @@
# Reverse Proxy Configuration for Sibedas PBG Web
# This configuration handles SSL termination and routes traffic to the appropriate containers
# Upstream for Sibedas application
upstream sibedas_backend {
server sibedas_app:9000;
keepalive 32;
}
# Rate limiting
limit_req_zone $binary_remote_addr zone=sibedas_limit:10m rate=10r/s;
# HTTP to HTTPS redirect
server {
listen 80;
server_name _;
# Redirect all HTTP traffic to HTTPS
return 301 https://$host$request_uri;
}
# HTTPS Server for Sibedas
server {
listen 443 ssl http2;
server_name sibedas.yourdomain.com; # Change this to your domain
# SSL Configuration
ssl_certificate /etc/nginx/ssl/sibedas.crt;
ssl_certificate_key /etc/nginx/ssl/sibedas.key;
# SSL Security Settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-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;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:; connect-src 'self'; frame-ancestors 'none';" always;
# Rate limiting
limit_req zone=sibedas_limit burst=20 nodelay;
# Client max body size
client_max_body_size 100M;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;
# Root directory
root /var/www/public;
index index.php index.html index.htm;
# Handle Laravel routes
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP-FPM configuration
location ~ \.php$ {
fastcgi_pass sibedas_backend;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
# FastCGI optimizations
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
}
# Static files caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf|txt)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# Deny access to sensitive files
location ~ /\. {
deny all;
}
location ~ /\.ht {
deny all;
}
# Health check endpoint
location /health-check {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# Logging
access_log /var/log/nginx/sibedas_access.log;
error_log /var/log/nginx/sibedas_error.log;
}
# Additional server blocks for other applications can be added here
# Example:
# server {
# listen 443 ssl http2;
# server_name other-app.yourdomain.com;
#
# ssl_certificate /etc/nginx/ssl/other-app.crt;
# ssl_certificate_key /etc/nginx/ssl/other-app.key;
#
# location / {
# proxy_pass http://other_app_container:port;
# 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;
# }
# }

View File

@@ -0,0 +1,58 @@
# Internal Nginx Configuration for Sibedas PBG Web
# This configuration is for the internal container, accessed by reverse proxy
server {
listen 80;
server_name localhost;
# Root directory
root /var/www/public;
index index.php index.html index.htm;
# Handle Laravel routes
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP-FPM configuration
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
# FastCGI optimizations
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
}
# Static files caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|pdf|txt)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# Deny access to sensitive files
location ~ /\. {
deny all;
}
location ~ /\.ht {
deny all;
}
# Health check endpoint
location /health-check {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
# Logging
access_log /var/log/nginx/sibedas_internal_access.log;
error_log /var/log/nginx/sibedas_internal_error.log;
}

123
docker/nginx/ssl-setup.sh Normal file
View File

@@ -0,0 +1,123 @@
#!/bin/bash
# SSL Setup Script for Sibedas PBG Web
# This script handles SSL certificate generation and renewal
set -e
DOMAIN="${DOMAIN:-sibedas.yourdomain.com}"
EMAIL="${EMAIL:-admin@yourdomain.com}"
SSL_DIR="/etc/nginx/ssl"
CERT_FILE="$SSL_DIR/sibedas.crt"
KEY_FILE="$SSL_DIR/sibedas.key"
# Function to generate self-signed certificate
generate_self_signed() {
echo "Generating self-signed SSL certificate for $DOMAIN..."
# Create SSL directory if it doesn't exist
mkdir -p "$SSL_DIR"
# Generate self-signed certificate
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout "$KEY_FILE" \
-out "$CERT_FILE" \
-subj "/C=ID/ST=Jakarta/L=Jakarta/O=Sibedas/OU=IT/CN=$DOMAIN/emailAddress=$EMAIL"
echo "Self-signed certificate generated successfully!"
}
# Function to setup Let's Encrypt certificate
setup_letsencrypt() {
echo "Setting up Let's Encrypt certificate for $DOMAIN..."
# Check if certbot is available
if ! command -v certbot &> /dev/null; then
echo "Certbot not found. Installing..."
apk add --no-cache certbot certbot-nginx
fi
# Stop nginx temporarily
nginx -s stop || true
# Get certificate
certbot certonly --standalone \
--email "$EMAIL" \
--agree-tos \
--no-eff-email \
-d "$DOMAIN"
# Copy certificates to nginx ssl directory
cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem "$CERT_FILE"
cp /etc/letsencrypt/live/$DOMAIN/privkey.pem "$KEY_FILE"
# Set proper permissions
chmod 644 "$CERT_FILE"
chmod 600 "$KEY_FILE"
# Start nginx
nginx
echo "Let's Encrypt certificate setup completed!"
}
# Function to renew Let's Encrypt certificate
renew_certificate() {
echo "Renewing Let's Encrypt certificate..."
certbot renew --quiet
# Copy renewed certificates
cp /etc/letsencrypt/live/$DOMAIN/fullchain.pem "$CERT_FILE"
cp /etc/letsencrypt/live/$DOMAIN/privkey.pem "$KEY_FILE"
# Reload nginx
nginx -s reload
echo "Certificate renewal completed!"
}
# Function to check certificate validity
check_certificate() {
if [ -f "$CERT_FILE" ] && [ -f "$KEY_FILE" ]; then
echo "Certificate files exist."
echo "Certificate details:"
openssl x509 -in "$CERT_FILE" -text -noout | grep -E "(Subject:|Not Before|Not After)"
return 0
else
echo "Certificate files not found."
return 1
fi
}
# Main script logic
case "${1:-setup}" in
"setup")
if [ "$SSL_TYPE" = "letsencrypt" ]; then
setup_letsencrypt
else
generate_self_signed
fi
;;
"renew")
renew_certificate
;;
"check")
check_certificate
;;
"self-signed")
generate_self_signed
;;
"letsencrypt")
setup_letsencrypt
;;
*)
echo "Usage: $0 {setup|renew|check|self-signed|letsencrypt}"
echo ""
echo "Environment variables:"
echo " DOMAIN: Domain name (default: sibedas.yourdomain.com)"
echo " EMAIL: Email address for Let's Encrypt (default: admin@yourdomain.com)"
echo " SSL_TYPE: Type of SSL (letsencrypt or self-signed, default: self-signed)"
exit 1
;;
esac

14
docker/nginx/ssl/.gitignore vendored Normal file
View File

@@ -0,0 +1,14 @@
# SSL Certificates - Do not commit these files
*.crt
*.key
*.pem
*.p12
*.pfx
# Let's Encrypt
letsencrypt/
live/
archive/
# Keep this directory in git but ignore certificate files
!.gitignore

View File

@@ -6,13 +6,13 @@ pidfile=/var/run/supervisord.pid
[program:laravel-queue-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/pupr/artisan queue:work --queue=default --timeout=82800 --tries=3 --memory=512 --sleep=3
directory=/var/www/pupr
command=php /var/www/artisan queue:work --queue=default --timeout=82800 --tries=3 --memory=512 --sleep=3
directory=/var/www
autostart=true
autorestart=true
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/pupr/storage/logs/queue-worker.log
stdout_logfile=/var/www/storage/logs/queue-worker.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=5
stopasgroup=true
@@ -22,13 +22,13 @@ priority=10
[program:laravel-scheduler]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/pupr/artisan schedule:work
directory=/var/www/pupr
command=php /var/www/artisan schedule:work
directory=/var/www
autostart=true
autorestart=true
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/pupr/storage/logs/scheduler.log
stdout_logfile=/var/www/storage/logs/scheduler.log
stdout_logfile_maxbytes=10MB
stdout_logfile_backups=5
stopasgroup=true