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