diff --git a/ci/deploy/.env.template b/ci/deploy/.env.template new file mode 100644 index 0000000..cc00483 --- /dev/null +++ b/ci/deploy/.env.template @@ -0,0 +1,6 @@ +# Docker Image Tags +DOCS_TAG=${DOCS_TAG:-latest} +WWW_TAG=${WWW_TAG:-latest} + +# Application Settings +DOMAIN=ermnvldmr.com diff --git a/ci/deploy/docker-compose.yml b/ci/deploy/docker-compose.yml new file mode 100644 index 0000000..8f00bda --- /dev/null +++ b/ci/deploy/docker-compose.yml @@ -0,0 +1,45 @@ +name: com-ermnvldmr + +services: + nginx: + image: nginx:stable-alpine + container_name: com-ermnvldmr-nginx + restart: always + ports: + - "80:80" + - "443:443" + volumes: + - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro + - ./nginx/conf.d:/etc/nginx/conf.d:ro + - ./nginx/certs:/etc/nginx/certs:ro + networks: + - com-ermnvldmr-direct + - com-ermnvldmr-enclave + deploy: + resources: + limits: + cpus: '0.50' + memory: 256M + security_opt: + - no-new-privileges:true + + docs: + image: ghcr.io/deytenit/www.ermnvldmr.com/docs:${DOCS_TAG} + container_name: com-ermnvldmr-docs + restart: always + networks: + - com-ermnvldmr-enclave + deploy: + resources: + limits: + cpus: '0.25' + memory: 128M + security_opt: + - no-new-privileges:true + +networks: + com-ermnvldmr-direct: + driver: bridge + com-ermnvldmr-enclave: + internal: true + driver: bridge diff --git a/ci/deploy/nginx/conf.d/docs.conf b/ci/deploy/nginx/conf.d/docs.conf new file mode 100644 index 0000000..d372d96 --- /dev/null +++ b/ci/deploy/nginx/conf.d/docs.conf @@ -0,0 +1,41 @@ +server { + listen 80; + server_name docs.ermnvldmr.com; + + location /.well-known/acme-challenge/ { + root /var/www/certbot; + } + + location / { + return 301 https://$host$request_uri; + } +} + +server { + listen 443 ssl; + http2 on; + server_name docs.ermnvldmr.com; + + ssl_certificate /etc/nginx/certs/live/docs.ermnvldmr.com/fullchain.pem; + ssl_certificate_key /etc/nginx/certs/live/docs.ermnvldmr.com/privkey.pem; + + # Optimized SSL settings + ssl_session_timeout 1d; + ssl_session_cache shared:SSL:50m; + ssl_session_tickets off; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; + ssl_prefer_server_ciphers off; + + # HSTS + add_header Strict-Transport-Security "max-age=63072000" always; + + location / { + proxy_pass http://com-ermnvldmr-docs:80; + proxy_http_version 1.1; + 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; + } +} diff --git a/ci/deploy/nginx/nginx.conf b/ci/deploy/nginx/nginx.conf new file mode 100644 index 0000000..b66627b --- /dev/null +++ b/ci/deploy/nginx/nginx.conf @@ -0,0 +1,30 @@ +user nginx; +worker_processes auto; +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + # Optimization + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + server_tokens off; + + # 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; + + include /etc/nginx/conf.d/*.conf; +}