Slave/prod deploy #12
@@ -0,0 +1,46 @@
|
||||
FROM node:22.23.4-alpine AS frontend-builder
|
||||
|
||||
WORKDIR /frontend
|
||||
|
||||
COPY frontend/package*.json .
|
||||
COPY frontend/patches ./patches
|
||||
|
||||
RUN npm ci
|
||||
|
||||
COPY frontend/ .
|
||||
|
||||
ARG VITE_API_BASE_URL
|
||||
ARG VITE_CLEARNET_SCHEME
|
||||
ARG VITE_CLEARNET_DOMAIN
|
||||
ARG VITE_ONION_HOSTNAME
|
||||
ARG VITE_ALTCHA_ENABLED
|
||||
ARG VITE_ALTCHA_MAX_NUMBER
|
||||
ARG VITE_UPLOAD_MAX_QUEUE_SIZE
|
||||
ARG VITE_VALIDATION_UPLOAD_MAX_VIEWS_MAX
|
||||
ARG VITE_VALIDATION_UPLOAD_MAX_IMAGE_BYTES
|
||||
|
||||
ENV VITE_API_BASE_URL=$VITE_API_BASE_URL \
|
||||
VITE_CLEARNET_SCHEME=$VITE_CLEARNET_SCHEME \
|
||||
VITE_CLEARNET_DOMAIN=$VITE_CLEARNET_DOMAIN \
|
||||
VITE_ONION_HOSTNAME=$VITE_ONION_HOSTNAME \
|
||||
VITE_ALTCHA_ENABLED=$VITE_ALTCHA_ENABLED \
|
||||
VITE_ALTCHA_MAX_NUMBER=$VITE_ALTCHA_MAX_NUMBER \
|
||||
VITE_UPLOAD_MAX_QUEUE_SIZE=$VITE_UPLOAD_MAX_QUEUE_SIZE \
|
||||
VITE_VALIDATION_UPLOAD_MAX_VIEWS_MAX=$VITE_VALIDATION_UPLOAD_MAX_VIEWS_MAX \
|
||||
VITE_VALIDATION_UPLOAD_MAX_IMAGE_BYTES=$VITE_VALIDATION_UPLOAD_MAX_IMAGE_BYTES
|
||||
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:1.29.4-alpine
|
||||
|
||||
RUN apk add --no-cache gettext
|
||||
|
||||
COPY --from=frontend-builder /frontend/dist /usr/share/nginx/html
|
||||
|
||||
COPY nginx/conf.d/ /etc/nginx/templates/conf.d/
|
||||
COPY nginx/snippets/private-image-locations.conf.template /etc/nginx/templates/snippets/
|
||||
COPY nginx/docker-entrypoint.sh /docker-entrypoint.sh
|
||||
|
||||
RUN chmod +x /docker-entrypoint.sh
|
||||
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
@@ -0,0 +1,28 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name ${CLEARNET_DOMAIN} www.${CLEARNET_DOMAIN};
|
||||
|
||||
access_log off;
|
||||
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/certbot;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name ${CLEARNET_DOMAIN} www.${CLEARNET_DOMAIN};
|
||||
|
||||
access_log off;
|
||||
|
||||
ssl_certificate /etc/nginx/certs/live/${CLEARNET_DOMAIN}/fullchain.pem;
|
||||
ssl_certificate_key /etc/nginx/certs/live/${CLEARNET_DOMAIN}/privkey.pem;
|
||||
|
||||
${ONION_LOCATION_HEADER}
|
||||
|
||||
include /etc/nginx/snippets/private-image-locations.conf;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
server {
|
||||
listen 8080;
|
||||
server_name _;
|
||||
|
||||
access_log off;
|
||||
|
||||
include /etc/nginx/snippets/private-image-locations.conf;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
max_image_bytes="${VALIDATION_UPLOAD_MAX_IMAGE_BYTES:?}"
|
||||
json_padding="${VALIDATION_UPLOAD_JSON_BODY_PADDING_BYTES:?}"
|
||||
|
||||
UPLOAD_MAX_REQUEST_BODY_BYTES=$(( (max_image_bytes * 4 + 2) / 3 + json_padding ))
|
||||
|
||||
export UPLOAD_MAX_REQUEST_BODY_BYTES BACKEND_PORT
|
||||
|
||||
render_locations() {
|
||||
envsubst '${BACKEND_PORT} ${UPLOAD_MAX_REQUEST_BODY_BYTES}' \
|
||||
< /etc/nginx/templates/snippets/private-image-locations.conf.template \
|
||||
> /etc/nginx/snippets/private-image-locations.conf
|
||||
}
|
||||
|
||||
render_server() {
|
||||
template_path="$1"
|
||||
output_path="$2"
|
||||
surface="$3"
|
||||
|
||||
if [ "$surface" = "clearnet" ]; then
|
||||
if [ -n "${ONION_HOSTNAME:-}" ]; then
|
||||
export ONION_LOCATION_HEADER="add_header Onion-Location \"http://${ONION_HOSTNAME}\$request_uri\";"
|
||||
else
|
||||
export ONION_LOCATION_HEADER=""
|
||||
fi
|
||||
|
||||
export CLEARNET_DOMAIN
|
||||
|
||||
envsubst '${CLEARNET_DOMAIN} ${ONION_LOCATION_HEADER}' \
|
||||
< "$template_path" \
|
||||
> "$output_path"
|
||||
|
||||
return
|
||||
fi
|
||||
|
||||
cp "$template_path" "$output_path"
|
||||
}
|
||||
|
||||
mkdir -p /etc/nginx/snippets
|
||||
|
||||
render_locations
|
||||
render_server /etc/nginx/templates/conf.d/clearnet.conf.template /etc/nginx/conf.d/clearnet.conf clearnet
|
||||
render_server /etc/nginx/templates/conf.d/onion.conf.template /etc/nginx/conf.d/onion.conf onion
|
||||
|
||||
exec nginx -g 'daemon off;'
|
||||
@@ -0,0 +1,48 @@
|
||||
location ^~ /i/ {
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Cross-Origin-Resource-Policy "cross-origin" always;
|
||||
add_header Cache-Control "private, no-store" always;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_pass http://backend:${BACKEND_PORT};
|
||||
}
|
||||
|
||||
location /api {
|
||||
client_max_body_size ${UPLOAD_MAX_REQUEST_BODY_BYTES};
|
||||
|
||||
add_header Cache-Control "no-store" always;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
|
||||
proxy_pass http://backend:${BACKEND_PORT};
|
||||
}
|
||||
|
||||
location /pgadmin {
|
||||
proxy_set_header X-Script-Name /pgadmin;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
||||
proxy_pass_header Set-Cookie;
|
||||
|
||||
proxy_pass http://pgadmin;
|
||||
|
||||
proxy_redirect off;
|
||||
}
|
||||
|
||||
location / {
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header Cache-Control "no-store" always;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
Reference in New Issue
Block a user