Try to connect up nginx in prod server
Some checks failed
Podman Rootless Demo / test-backend (push) Has been skipped
Podman Rootless Demo / test-frontend (push) Has been skipped
Podman Rootless Demo / build-backend (push) Has been skipped
Podman Rootless Demo / build-frontend (push) Has been skipped
Podman Rootless Demo / deploy-prod (push) Failing after 20s
Some checks failed
Podman Rootless Demo / test-backend (push) Has been skipped
Podman Rootless Demo / test-frontend (push) Has been skipped
Podman Rootless Demo / build-backend (push) Has been skipped
Podman Rootless Demo / build-frontend (push) Has been skipped
Podman Rootless Demo / deploy-prod (push) Failing after 20s
This commit is contained in:
parent
9a927bcb8b
commit
80f8f75208
3 changed files with 58 additions and 140 deletions
|
|
@ -245,6 +245,21 @@ jobs:
|
|||
podman --remote pull "$REGISTRY_HOST/$APP_NAME/sharenet-backend-api-postgres:$IMAGE_TAG"
|
||||
podman --remote pull "$REGISTRY_HOST/$APP_NAME/sharenet-frontend:$IMAGE_TAG"
|
||||
|
||||
- name: Prepare in-pod nginx config on host
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# create dir on host (via user namespace)
|
||||
podman --remote unshare mkdir -p /opt/sharenet/nginx /opt/sharenet/volumes/nginx-cache
|
||||
# render temp config (inside the job container)
|
||||
apk add --no-cache gettext >/dev/null
|
||||
envsubst < nginx/nginx.conf > /tmp/nginx.conf
|
||||
# write it onto the host
|
||||
podman --remote unshare sh -c 'cat > /opt/sharenet/nginx/nginx.conf' < /tmp/nginx.conf
|
||||
# reasonable perms for rootless mount
|
||||
podman --remote unshare chown -R 1001:1001 /opt/sharenet
|
||||
podman --remote unshare chmod 0755 /opt/sharenet /opt/sharenet/nginx /opt/sharenet/volumes /opt/sharenet/volumes/nginx-cache
|
||||
podman --remote unshare chmod 0644 /opt/sharenet/nginx/nginx.conf || true
|
||||
|
||||
- name: Install envsubst (Alpine)
|
||||
run: apk add --no-cache gettext
|
||||
|
||||
|
|
|
|||
|
|
@ -150,27 +150,19 @@ spec:
|
|||
capabilities:
|
||||
drop: ["ALL"]
|
||||
ports:
|
||||
- containerPort: 80
|
||||
hostPort: 8080
|
||||
protocol: TCP
|
||||
- containerPort: 443
|
||||
hostPort: 8443
|
||||
protocol: TCP
|
||||
- containerPort: 8080 # inside pod
|
||||
hostIP: 127.0.0.1 # only loopback on host
|
||||
hostPort: 18080 # high port exposed to host
|
||||
- containerPort: 8090 # health inside pod (not exposed)
|
||||
volumeMounts:
|
||||
- { name: nginx-run, mountPath: /var/run, readOnly: false }
|
||||
- { name: nginx-conf, mountPath: /etc/nginx/nginx.conf, readOnly: true, subPath: nginx.conf }
|
||||
- { name: nginx-cache, mountPath: /var/cache/nginx, readOnly: false }
|
||||
- { name: letsencrypt, mountPath: /etc/letsencrypt, readOnly: true }
|
||||
- { name: nginx-conf, mountPath: /etc/nginx/nginx.conf, readOnly: true, subPath: nginx.conf }
|
||||
# Health check
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8090
|
||||
scheme: HTTP
|
||||
httpGet: { path: /healthz, port: 8090, scheme: HTTP }
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
# Resource limits
|
||||
resources:
|
||||
requests:
|
||||
|
|
@ -193,15 +185,7 @@ spec:
|
|||
emptyDir: { medium: Memory }
|
||||
- name: nginx-run
|
||||
emptyDir: {}
|
||||
- name: nginx-conf
|
||||
hostPath:
|
||||
path: /opt/sharenet/nginx
|
||||
type: Directory
|
||||
- name: nginx-cache
|
||||
hostPath:
|
||||
path: /opt/sharenet/volumes/nginx-cache
|
||||
type: DirectoryOrCreate
|
||||
- name: letsencrypt
|
||||
hostPath:
|
||||
path: /etc/letsencrypt
|
||||
type: Directory
|
||||
hostPath: { path: /opt/sharenet/volumes/nginx-cache, type: DirectoryOrCreate }
|
||||
- name: nginx-conf
|
||||
hostPath: { path: /opt/sharenet/nginx, type: Directory }
|
||||
117
nginx/nginx.conf
117
nginx/nginx.conf
|
|
@ -1,118 +1,37 @@
|
|||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
pid /var/run/nginx.pid;
|
||||
events { worker_connections 1024; }
|
||||
|
||||
http {
|
||||
upstream frontend {
|
||||
server frontend:3000;
|
||||
}
|
||||
|
||||
upstream backend {
|
||||
server backend:3001;
|
||||
}
|
||||
|
||||
# Rate limiting
|
||||
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
|
||||
limit_req_zone $binary_remote_addr zone=frontend:10m rate=30r/s;
|
||||
|
||||
# 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;
|
||||
|
||||
# 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;
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
|
||||
# health
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
# Redirect HTTP to HTTPS
|
||||
return 301 https://$host$request_uri;
|
||||
listen 8090;
|
||||
location = /healthz { return 200 "ok\n"; add_header Content-Type text/plain; }
|
||||
}
|
||||
|
||||
# public HTTP entrypoint (host will terminate TLS and proxy here)
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name _;
|
||||
listen 8080;
|
||||
|
||||
# SSL configuration
|
||||
# These paths match Let's Encrypt certificate files copied in the CI/CD setup guide
|
||||
ssl_certificate /etc/nginx/ssl/fullchain.pem;
|
||||
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
|
||||
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;
|
||||
|
||||
# Frontend routes
|
||||
# frontend default
|
||||
location / {
|
||||
limit_req zone=frontend burst=20 nodelay;
|
||||
|
||||
proxy_pass http://frontend;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_pass http://127.0.0.1:${PROD_FRONTEND_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-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
}
|
||||
|
||||
# API routes
|
||||
# backend API
|
||||
location /api/ {
|
||||
limit_req zone=api burst=10 nodelay;
|
||||
|
||||
proxy_pass http://backend/;
|
||||
proxy_http_version 1.1;
|
||||
proxy_pass http://127.0.0.1:${PROD_BACKEND_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-For $remote_addr;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# CORS headers
|
||||
add_header Access-Control-Allow-Origin * always;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
||||
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
|
||||
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header Access-Control-Allow-Origin *;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
|
||||
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization";
|
||||
add_header Access-Control-Max-Age 1728000;
|
||||
add_header Content-Type 'text/plain; charset=utf-8';
|
||||
add_header Content-Length 0;
|
||||
return 204;
|
||||
}
|
||||
}
|
||||
|
||||
# Health check endpoint
|
||||
location /health {
|
||||
access_log off;
|
||||
proxy_pass http://backend/health;
|
||||
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;
|
||||
add_header Content-Type application/json;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue