From 98bacbfafc117cdc6757699a86de0f697519f80d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=ED=95=9C=EB=8F=99=ED=98=84?= <hando1220@ajou.ac.kr> Date: Wed, 12 Mar 2025 00:27:36 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20APM=20=EB=8F=84=EC=BB=A4=20=EC=9D=B4?= =?UTF-8?q?=EB=AF=B8=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + Dockerfile | 39 ++++++++ compose.yaml | 10 ++ rootfs/docker-entrypoint.sh | 18 ++++ rootfs/etc/nginx/conf.d/apm.conf | 32 +++++++ rootfs/etc/nginx/conf.d/default.conf | 36 +++++++ rootfs/etc/nginx/conf.d/include/assets.conf | 31 ++++++ .../include/letsencrypt-acme-challenge.conf | 30 ++++++ rootfs/etc/nginx/conf.d/include/log.conf | 4 + rootfs/etc/nginx/conf.d/include/proxy.conf | 7 ++ .../etc/nginx/conf.d/include/ssl-ciphers.conf | 3 + rootfs/etc/nginx/mime.types | 96 +++++++++++++++++++ rootfs/etc/nginx/nginx.conf | 69 +++++++++++++ rootfs/var/www/html/index.html | 11 +++ 14 files changed, 387 insertions(+) create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 compose.yaml create mode 100644 rootfs/docker-entrypoint.sh create mode 100644 rootfs/etc/nginx/conf.d/apm.conf create mode 100644 rootfs/etc/nginx/conf.d/default.conf create mode 100644 rootfs/etc/nginx/conf.d/include/assets.conf create mode 100644 rootfs/etc/nginx/conf.d/include/letsencrypt-acme-challenge.conf create mode 100644 rootfs/etc/nginx/conf.d/include/log.conf create mode 100644 rootfs/etc/nginx/conf.d/include/proxy.conf create mode 100644 rootfs/etc/nginx/conf.d/include/ssl-ciphers.conf create mode 100644 rootfs/etc/nginx/mime.types create mode 100644 rootfs/etc/nginx/nginx.conf create mode 100644 rootfs/var/www/html/index.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..adbb97d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +data/ \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..33c1519 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,39 @@ +FROM node:22-alpine AS base + +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable + +FROM base AS build + +WORKDIR /app +COPY proxy-manager-frontend/ ./ + +RUN pnpm install --frozen-lockfile +RUN pnpm run build + +FROM nginx:stable-alpine + +COPY rootfs/ / +COPY --from=build /app/dist /app/frontend + +VOLUME ["/data"] + +ARG PUID=1000 +ARG PGID=1000 +ENV PUID=${PUID} +ENV PGID=${PGID} + +RUN chmod +x /docker-entrypoint.sh + +EXPOSE 80 81 443 + +ENTRYPOINT ["/docker-entrypoint.sh"] +CMD ["nginx", "-g", "daemon off;"] + +LABEL org.label-schema.schema-version="1.0" +LABEL org.label-schema.license="MIT" +LABEL org.label-schema.name="aolda-proxy-manager" +LABEL org.label-schema.description="Aolda Proxy Manager" +LABEL org.label-schema.url="https://git.ajou.ac.kr/aolda/proxy-manager" +LABEL org.label-schema.vcs-url="https://git.ajou.ac.kr/aolda/proxy-manager.git" diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..414f6ae --- /dev/null +++ b/compose.yaml @@ -0,0 +1,10 @@ +services: + nginx: + image: aolda-proxy-manager + restart: unless-stopped + ports: + - '80:80' + - '81:81' + - '443:443' + volumes: + - ./data:/data diff --git a/rootfs/docker-entrypoint.sh b/rootfs/docker-entrypoint.sh new file mode 100644 index 0000000..970305b --- /dev/null +++ b/rootfs/docker-entrypoint.sh @@ -0,0 +1,18 @@ +#!/bin/sh +set -e + +# Create necessary directories +mkdir -p /data/custom_ssl /data/logs /data/access /data/nginx /data/letsencrypt-acme-challenge /data/nginx/default_host /data/nginx/default_www /data/nginx/proxy_host /data/nginx/redirection_host /data/nginx/stream /data/nginx/dead_host /data/nginx/temp +mkdir -p /etc/letsencrypt /run/nginx /tmp/nginx/body /var/log/nginx /var/lib/nginx/cache/public /var/lib/nginx/cache/private /var/cache/nginx/proxy_temp + +# Set proper permissions +chown -R ${PUID:-1000}:${PGID:-1000} /data +chown -R ${PUID:-1000}:${PGID:-1000} /etc/letsencrypt +chown -R ${PUID:-1000}:${PGID:-1000} /run/nginx +chown -R ${PUID:-1000}:${PGID:-1000} /tmp/nginx +chown -R ${PUID:-1000}:${PGID:-1000} /var/cache/nginx +chown -R ${PUID:-1000}:${PGID:-1000} /var/lib/nginx +chown -R ${PUID:-1000}:${PGID:-1000} /var/log/nginx + +# Execute the main command +exec "$@" diff --git a/rootfs/etc/nginx/conf.d/apm.conf b/rootfs/etc/nginx/conf.d/apm.conf new file mode 100644 index 0000000..ddf7b9a --- /dev/null +++ b/rootfs/etc/nginx/conf.d/apm.conf @@ -0,0 +1,32 @@ +server { + listen 81 default; + listen [::]:81 default; + + server_name aoldaproxymanager; + root /app/frontend; + access_log /dev/null; + + location /api { + return 302 /api/; + } + + location /api/ { + add_header X-Served-By $host; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Scheme $scheme; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $remote_addr; + proxy_pass http://127.0.0.1:8080/; + + proxy_read_timeout 15m; + proxy_send_timeout 15m; + } + + location / { + index index.html; + if ($request_uri ~ ^/(.*)\.html$) { + return 302 /$1; + } + try_files $uri $uri.html $uri/ /index.html; + } +} \ No newline at end of file diff --git a/rootfs/etc/nginx/conf.d/default.conf b/rootfs/etc/nginx/conf.d/default.conf new file mode 100644 index 0000000..bc64d12 --- /dev/null +++ b/rootfs/etc/nginx/conf.d/default.conf @@ -0,0 +1,36 @@ +server { + listen 80; + listen [::]:80; + + set $forward_scheme "http"; + set $server "127.0.0.1"; + set $port "80"; + + server_name default-aoldaproxymanager; + access_log /data/logs/fallback_access.log standard; + error_log /data/logs/fallback_error.log warn; + include conf.d/include/assets.conf; + include conf.d/include/letsencrypt-acme-challenge.conf; + + location / { + index index.html; + root /var/www/html; + } +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + + set $forward_scheme "https"; + set $server "127.0.0.1"; + set $port "443"; + + server_name localhost; + access_log /data/logs/fallback_access.log standard; + error_log /dev/null crit; + include conf.d/include/ssl-ciphers.conf; + ssl_reject_handshake on; + + return 444; +} \ No newline at end of file diff --git a/rootfs/etc/nginx/conf.d/include/assets.conf b/rootfs/etc/nginx/conf.d/include/assets.conf new file mode 100644 index 0000000..8914b58 --- /dev/null +++ b/rootfs/etc/nginx/conf.d/include/assets.conf @@ -0,0 +1,31 @@ +location ~* ^.*\.(css|js|jpe?g|gif|png|webp|woff|woff2|eot|ttf|svg|ico|css\.map|js\.map)$ { + if_modified_since off; + + # Use the public cache + proxy_cache public-cache; + proxy_cache_key $host$request_uri; + + # Ignore these headers for media + proxy_ignore_headers Set-Cookie Cache-Control Expires X-Accel-Expires; + + # Cache 200s and also 404s (not ideal but there are a few 404 images for some reason) + proxy_cache_valid any 30m; + proxy_cache_valid 404 1m; + + # Strip this header to avoid If-Modified-Since requests + proxy_hide_header Last-Modified; + proxy_hide_header Cache-Control; + proxy_hide_header Vary; + + proxy_cache_bypass 0; + proxy_no_cache 0; + + proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_404; + proxy_connect_timeout 5s; + proxy_read_timeout 45s; + + expires @30m; + access_log off; + + include conf.d/include/proxy.conf; +} \ No newline at end of file diff --git a/rootfs/etc/nginx/conf.d/include/letsencrypt-acme-challenge.conf b/rootfs/etc/nginx/conf.d/include/letsencrypt-acme-challenge.conf new file mode 100644 index 0000000..4a60e85 --- /dev/null +++ b/rootfs/etc/nginx/conf.d/include/letsencrypt-acme-challenge.conf @@ -0,0 +1,30 @@ +# Rule for legitimate ACME Challenge requests (like /.well-known/acme-challenge/xxxxxxxxx) +# We use ^~ here, so that we don't check other regexes (for speed-up). We actually MUST cancel +# other regex checks, because in our other config files have regex rule that denies access to files with dotted names. +location ^~ /.well-known/acme-challenge/ { + # Since this is for letsencrypt authentication of a domain and they do not give IP ranges of their infrastructure + # we need to open up access by turning off auth and IP ACL for this location. + auth_basic off; + auth_request off; + allow all; + + # Set correct content type. According to this: + # https://community.letsencrypt.org/t/using-the-webroot-domain-verification-method/1445/29 + # Current specification requires "text/plain" or no content header at all. + # It seems that "text/plain" is a safe option. + default_type "text/plain"; + + # This directory must be the same as in /etc/letsencrypt/cli.ini + # as "webroot-path" parameter. Also don't forget to set "authenticator" parameter + # there to "webroot". + # Do NOT use alias, use root! Target directory is located here: + # /var/www/common/letsencrypt/.well-known/acme-challenge/ + root /data/letsencrypt-acme-challenge; +} + +# Hide /acme-challenge subdirectory and return 404 on all requests. +# It is somewhat more secure than letting Nginx return 403. +# Ending slash is important! +location = /.well-known/acme-challenge/ { + return 404; +} \ No newline at end of file diff --git a/rootfs/etc/nginx/conf.d/include/log.conf b/rootfs/etc/nginx/conf.d/include/log.conf new file mode 100644 index 0000000..90ec8b4 --- /dev/null +++ b/rootfs/etc/nginx/conf.d/include/log.conf @@ -0,0 +1,4 @@ +log_format proxy '[$time_local] $upstream_cache_status $upstream_status $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] [Sent-to $server] "$http_user_agent" "$http_referer"'; +log_format standard '[$time_local] $status - $request_method $scheme $host "$request_uri" [Client $remote_addr] [Length $body_bytes_sent] [Gzip $gzip_ratio] "$http_user_agent" "$http_referer"'; + +access_log /data/logs/fallback_access.log proxy; \ No newline at end of file diff --git a/rootfs/etc/nginx/conf.d/include/proxy.conf b/rootfs/etc/nginx/conf.d/include/proxy.conf new file mode 100644 index 0000000..17eaa78 --- /dev/null +++ b/rootfs/etc/nginx/conf.d/include/proxy.conf @@ -0,0 +1,7 @@ +add_header X-Served-By $host; +proxy_set_header Host $host; +proxy_set_header X-Forwarded-Scheme $scheme; +proxy_set_header X-Forwarded-Proto $scheme; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header X-Real-IP $remote_addr; +proxy_pass $forward_scheme://$server:$port$request_uri; \ No newline at end of file diff --git a/rootfs/etc/nginx/conf.d/include/ssl-ciphers.conf b/rootfs/etc/nginx/conf.d/include/ssl-ciphers.conf new file mode 100644 index 0000000..84b9aec --- /dev/null +++ b/rootfs/etc/nginx/conf.d/include/ssl-ciphers.conf @@ -0,0 +1,3 @@ +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; \ No newline at end of file diff --git a/rootfs/etc/nginx/mime.types b/rootfs/etc/nginx/mime.types new file mode 100644 index 0000000..c230212 --- /dev/null +++ b/rootfs/etc/nginx/mime.types @@ -0,0 +1,96 @@ +types { + text/html html htm shtml; + text/css css; + text/xml xml; + image/gif gif; + image/jpeg jpeg jpg; + application/javascript js; + application/atom+xml atom; + application/rss+xml rss; + + text/mathml mml; + text/plain txt; + text/vnd.sun.j2me.app-descriptor jad; + text/vnd.wap.wml wml; + text/x-component htc; + + image/png png; + image/svg+xml svg svgz; + image/tiff tif tiff; + image/vnd.wap.wbmp wbmp; + image/webp webp; + image/x-icon ico; + image/x-jng jng; + image/x-ms-bmp bmp; + + font/woff woff; + font/woff2 woff2; + + application/java-archive jar war ear; + application/json json; + application/mac-binhex40 hqx; + application/msword doc; + application/pdf pdf; + application/postscript ps eps ai; + application/rtf rtf; + application/vnd.apple.mpegurl m3u8; + application/vnd.google-earth.kml+xml kml; + application/vnd.google-earth.kmz kmz; + application/vnd.ms-excel xls; + application/vnd.ms-fontobject eot; + application/vnd.ms-powerpoint ppt; + application/vnd.oasis.opendocument.graphics odg; + application/vnd.oasis.opendocument.presentation odp; + application/vnd.oasis.opendocument.spreadsheet ods; + application/vnd.oasis.opendocument.text odt; + application/vnd.openxmlformats-officedocument.presentationml.presentation + pptx; + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + xlsx; + application/vnd.openxmlformats-officedocument.wordprocessingml.document + docx; + application/vnd.wap.wmlc wmlc; + application/x-7z-compressed 7z; + application/x-cocoa cco; + application/x-java-archive-diff jardiff; + application/x-java-jnlp-file jnlp; + application/x-makeself run; + application/x-perl pl pm; + application/x-pilot prc pdb; + application/x-rar-compressed rar; + application/x-redhat-package-manager rpm; + application/x-sea sea; + application/x-shockwave-flash swf; + application/x-stuffit sit; + application/x-tcl tcl tk; + application/x-x509-ca-cert der pem crt; + application/x-xpinstall xpi; + application/xhtml+xml xhtml; + application/xspf+xml xspf; + application/zip zip; + + application/octet-stream bin exe dll; + application/octet-stream deb; + application/octet-stream dmg; + application/octet-stream iso img; + application/octet-stream msi msp msm; + + audio/midi mid midi kar; + audio/mpeg mp3; + audio/ogg ogg; + audio/x-m4a m4a; + audio/x-realaudio ra; + + video/3gpp 3gpp 3gp; + video/mp2t ts; + video/mp4 mp4; + video/mpeg mpeg mpg; + video/quicktime mov; + video/webm webm; + video/x-flv flv; + video/x-m4v m4v; + video/x-mng mng; + video/x-ms-asf asx asf; + video/x-ms-wmv wmv; + video/x-msvideo avi; +} \ No newline at end of file diff --git a/rootfs/etc/nginx/nginx.conf b/rootfs/etc/nginx/nginx.conf new file mode 100644 index 0000000..bda8d2c --- /dev/null +++ b/rootfs/etc/nginx/nginx.conf @@ -0,0 +1,69 @@ +# Run nginx in foreground +# daemon off; +pid /run/nginx/nginx.pid; +# user nginx; + +# Set number of worker processes automatically based on number of CPU cores. +worker_processes auto; + +# Enables the use of JIT for regular expressions to speed-up their processing. +pcre_jit on; + +error_log /data/logs/fallback_error.log warn; + +events { + include /data/nginx/custom/events[.]conf; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + sendfile on; + server_tokens off; + tcp_nopush on; + tcp_nodelay on; + client_body_temp_path /tmp/nginx/body 1 2; + keepalive_timeout 90s; + proxy_connect_timeout 90s; + proxy_send_timeout 90s; + proxy_read_timeout 90s; + ssl_prefer_server_ciphers on; + gzip on; + proxy_ignore_client_abort off; + client_max_body_size 2000m; + server_names_hash_bucket_size 1024; + proxy_http_version 1.1; + proxy_set_header X-Forwarded-Scheme $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Accept-Encoding ""; + proxy_cache off; + proxy_cache_path /var/lib/nginx/cache/public levels=1:2 keys_zone=public-cache:30m max_size=192m; + proxy_cache_path /var/lib/nginx/cache/private levels=1:2 keys_zone=private-cache:5m max_size=1024m; + + # Log format and fallback log file + include /etc/nginx/conf.d/include/log.conf; + + # Default upstream scheme + map $host $forward_scheme { + default http; + } + + # Files generated by Proxy Manager + include /etc/nginx/conf.d/*.conf; + include /data/nginx/proxy_host/*.conf; + include /data/nginx/redirection_host/*.conf; + + # Custom + include /data/nginx/custom/http[.]conf; +} + +stream { + # Files generated by Proxy Manager + include /data/nginx/stream/*.conf; + + # Custom + include /data/nginx/custom/stream[.]conf; +} + +# Custom +include /data/nginx/custom/root[.]conf; \ No newline at end of file diff --git a/rootfs/var/www/html/index.html b/rootfs/var/www/html/index.html new file mode 100644 index 0000000..f7948c8 --- /dev/null +++ b/rootfs/var/www/html/index.html @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html lang="ko"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>Aolda</title> + </head> + <body> + Hello, Aolda! + </body> +</html> -- GitLab