commit 9d0631338c405b60eff7b8b6bb9db86708d4f4f3 Author: devwill1004-dotcom Date: Sat Mar 7 05:06:47 2026 +0800 init: add server infra config files with log volume mounts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bd301a4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.bak +*.sql diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b3f4385 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,273 @@ +version: '3.8' + +networks: + gitea-net: + driver: bridge + +volumes: + mysql_data: + gitea_data: + jenkins_data: + mysql_oms_data: + mysql_triple_data: + +services: + + # ────────────────────────────────────────── + # MySQL 8.0 — Gitea/Jenkins용 + # ────────────────────────────────────────── + mysql: + image: mysql:8.0 + container_name: mysql + restart: always + networks: + - gitea-net + environment: + MYSQL_ROOT_PASSWORD: root1234! + MYSQL_DATABASE: gitea + MYSQL_CHARACTER_SET_SERVER: utf8mb4 + MYSQL_COLLATION_SERVER: utf8mb4_unicode_ci + volumes: + - mysql_data:/var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-proot1234!"] + interval: 10s + timeout: 5s + retries: 10 + + # ────────────────────────────────────────── + # MySQL 8.0 — omsDB + # ────────────────────────────────────────── + mysql-oms: + image: mysql:8.0 + container_name: mysql-oms + restart: always + networks: + - gitea-net + ports: + - "3308:3306" + environment: + TZ: Asia/Seoul + MYSQL_ROOT_PASSWORD: root1234 + MYSQL_DATABASE: omsDB + MYSQL_CHARACTER_SET_SERVER: utf8mb4 + MYSQL_COLLATION_SERVER: utf8mb4_unicode_ci + volumes: + - mysql_oms_data:/var/lib/mysql + - ./innodb8.cnf:/etc/mysql/conf.d/innodb.cnf:ro + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-proot1234"] + interval: 10s + timeout: 5s + retries: 10 + + # ────────────────────────────────────────── + # MySQL 8.0 — triple_db + # ────────────────────────────────────────── + mysql-triple: + image: mysql:8.0 + container_name: mysql-triple + restart: always + networks: + - gitea-net + ports: + - "3309:3306" + environment: + TZ: Asia/Seoul + MYSQL_ROOT_PASSWORD: root1234 + MYSQL_DATABASE: triple_db + MYSQL_CHARACTER_SET_SERVER: utf8mb4 + MYSQL_COLLATION_SERVER: utf8mb4_unicode_ci + volumes: + - mysql_triple_data:/var/lib/mysql + - ./innodb8.cnf:/etc/mysql/conf.d/innodb.cnf:ro + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-proot1234"] + interval: 10s + timeout: 5s + retries: 10 + + # ────────────────────────────────────────── + # Gitea + # ────────────────────────────────────────── + gitea: + image: gitea/gitea:latest + container_name: gitea + restart: always + networks: + - gitea-net + depends_on: + mysql: + condition: service_healthy + environment: + - USER_UID=1000 + - USER_GID=1000 + - GITEA__database__DB_TYPE=mysql + - GITEA__database__HOST=mysql:3306 + - GITEA__database__NAME=gitea + - GITEA__database__USER=root + - GITEA__database__PASSWD=root1234! + - GITEA__server__DOMAIN=git.gong-dev.com + - GITEA__server__SSH_DOMAIN=git.gong-dev.com + - GITEA__server__ROOT_URL=https://git.gong-dev.com/ + - GITEA__server__HTTP_PORT=3000 + volumes: + - gitea_data:/data + expose: + - "3000" + + # ────────────────────────────────────────── + # Jenkins + # ────────────────────────────────────────── + jenkins: + image: jenkins/jenkins:lts + container_name: jenkins + user: root + restart: always + networks: + - gitea-net + volumes: + - jenkins_data:/var/jenkins_home + - /var/run/docker.sock:/var/run/docker.sock + - /usr/bin/docker:/usr/bin/docker + - /opt/gitea-stack:/opt/gitea-stack + - /opt/docker-cli-plugins:/usr/local/lib/docker/cli-plugins + expose: + - "8080" + + # ────────────────────────────────────────── + # Nginx (reverse proxy) + # ────────────────────────────────────────── + nginx: + image: nginx:alpine + container_name: nginx + restart: always + networks: + - gitea-net + depends_on: + - gitea + - jenkins + ports: + - "80:80" + - "443:443" + volumes: + - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro + - /etc/ssl/origin-ca:/etc/ssl/origin-ca:ro + - /etc/ssl/acme:/etc/ssl/acme:ro + + # ────────────────────────────────────────── + # pkcasino01 — 카지노 프론트엔드 + # ────────────────────────────────────────── + pkcasino01: + image: pkcasino01:latest + container_name: pkcasino01 + restart: always + networks: + - gitea-net + expose: + - "80" + + # ────────────────────────────────────────── + # agent_oms — 에이전트 어드민 프론트엔드 + # ────────────────────────────────────────── + agent-oms: + image: agent_oms:latest + container_name: agent-oms + restart: always + networks: + - gitea-net + expose: + - "80" + + # ────────────────────────────────────────── + # first_vendor_panel — 벤더 패널 프론트엔드 + # ────────────────────────────────────────── + first-vendor-panel: + image: first_vendor_panel:latest + container_name: first-vendor-panel + restart: always + networks: + - gitea-net + expose: + - "80" + + # ────────────────────────────────────────── + # oms_api — OMS 백엔드 API + # ────────────────────────────────────────── + oms-api: + image: oms_api:latest + container_name: oms-api + restart: always + networks: + - gitea-net + depends_on: + mysql-oms: + condition: service_healthy + mysql-triple: + condition: service_healthy + volumes: + - /home/log/triple:/home/log/triple + expose: + - "8080" + environment: + - SPRING_DATASOURCE1_JDBC_URL=jdbc:mysql://mysql-oms:3306/omsDB?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&autoReconnect=true&useEncoding=true&characterEncoding=utf-8&allowMultiQueries=true + - SPRING_DATASOURCE2_JDBC_URL=jdbc:mysql://mysql-oms:3306/omsDB?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&autoReconnect=true&useEncoding=true&characterEncoding=utf-8&allowMultiQueries=true + - SPRING_DATASOURCE3_JDBC_URL=jdbc:mysql://mysql-triple:3306/triple_db?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&autoReconnect=true&useEncoding=true&characterEncoding=utf-8 + - SPRING_DATASOURCE1_USERNAME=root + - SPRING_DATASOURCE1_PASSWORD=root1234 + - SPRING_DATASOURCE2_USERNAME=root + - SPRING_DATASOURCE2_PASSWORD=root1234 + - SPRING_DATASOURCE3_USERNAME=root + - SPRING_DATASOURCE3_PASSWORD=root1234 + + # ────────────────────────────────────────── + # first_vendor_api — Triple 벤더 API + # ────────────────────────────────────────── + first-vendor-api: + image: first_vendor_api:latest + container_name: first-vendor-api + restart: always + networks: + - gitea-net + depends_on: + mysql-triple: + condition: service_healthy + volumes: + - /home/log/triple:/home/log/triple + expose: + - "8080" + environment: + - SPRING_DATASOURCE1_JDBC_URL=jdbc:mysql://mysql-triple:3306/triple_db?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&autoReconnect=true&useEncoding=true&characterEncoding=utf-8 + - SPRING_DATASOURCE2_JDBC_URL=jdbc:mysql://mysql-triple:3306/triple_db?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&autoReconnect=true&useEncoding=true&characterEncoding=utf-8 + - SPRING_DATASOURCE1_USERNAME=root + - SPRING_DATASOURCE1_PASSWORD=root1234 + - SPRING_DATASOURCE2_USERNAME=root + - SPRING_DATASOURCE2_PASSWORD=root1234 + - SPRING_AUTOCONFIGURE_EXCLUDE=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration + + + # ────────────────────────────────────────── + # first_vendor_batch — Triple 배치 서버 + # ────────────────────────────────────────── + first-vendor-batch: + image: first_vendor_batch:latest + container_name: first-vendor-batch + restart: always + networks: + - gitea-net + depends_on: + mysql-triple: + condition: service_healthy + volumes: + - /home/log/triple:/home/log/triple + expose: + - "8080" + environment: + - SPRING_DATASOURCE1_JDBC_URL=jdbc:mysql://mysql-triple:3306/triple_db?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&autoReconnect=true&useEncoding=true&characterEncoding=utf-8 + - SPRING_DATASOURCE2_JDBC_URL=jdbc:mysql://mysql-triple:3306/triple_db?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&autoReconnect=true&useEncoding=true&characterEncoding=utf-8 + - SPRING_DATASOURCE1_USERNAME=root + - SPRING_DATASOURCE1_PASSWORD=root1234 + - SPRING_DATASOURCE2_USERNAME=root + - SPRING_DATASOURCE2_PASSWORD=root1234 + - SPRING_AUTOCONFIGURE_EXCLUDE=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration + diff --git a/innodb8.cnf b/innodb8.cnf new file mode 100644 index 0000000..22411f7 --- /dev/null +++ b/innodb8.cnf @@ -0,0 +1,4 @@ +[mysqld] +innodb_file_per_table = 1 +character-set-server = utf8mb4 +collation-server = utf8mb4_unicode_ci diff --git a/nginx/default.conf b/nginx/default.conf new file mode 100644 index 0000000..882891f --- /dev/null +++ b/nginx/default.conf @@ -0,0 +1,368 @@ +# 버퍼 설정 +proxy_buffering on; +proxy_buffer_size 128k; +proxy_buffers 4 256k; +proxy_busy_buffers_size 256k; +client_body_buffer_size 128k; +client_header_buffer_size 1k; +large_client_header_buffers 4 8k; + +# Cloudflare IP 허용 여부 +geo $cloudflare_ip { + default 0; + # IPv4 + 103.21.244.0/22 1; + 103.22.200.0/22 1; + 103.31.4.0/22 1; + 104.16.0.0/13 1; + 104.24.0.0/14 1; + 108.162.192.0/18 1; + 131.0.72.0/22 1; + 141.101.64.0/18 1; + 162.158.0.0/15 1; + 172.64.0.0/13 1; + 173.245.48.0/20 1; + 188.114.96.0/20 1; + 190.93.240.0/20 1; + 197.234.240.0/22 1; + 198.41.128.0/17 1; + # IPv6 + 2400:cb00::/32 1; + 2606:4700::/32 1; + 2803:f800::/32 1; + 2405:b500::/32 1; + 2405:8100::/32 1; + 2a06:98c0::/29 1; + 2c0f:f248::/32 1; +} + +map $http_user_agent $blocked_agent { + default 0; + ~*masscan 1; + ~*nikto 1; + ~*sqlmap 1; + ~*nmap 1; + ~*zgrab 1; + ~*python-requests 1; + ~*go-http-client 1; + ~*libwww-perl 1; + ~*scrapy 1; + ~*dirbuster 1; + ~*nuclei 1; + ~*WPScan 1; +} + +# Docker internal DNS resolver (allows missing upstreams at startup) +resolver 127.0.0.11 valid=30s; + +# HTTP -> HTTPS redirect +server { + listen 80; + server_name git.gong-dev.com jenkins.gong-dev.com pk.gong-dev.com + casino.gong-dev.com admin.gong-dev.com vendor.gong-dev.com + api.gong-dev.com vapi.gong-dev.com batch.gong-dev.com; + return 301 https://$host$request_uri; +} + +# Gitea HTTPS +server { + listen 443 ssl; + server_name git.gong-dev.com; + client_max_body_size 2048m; + server_tokens off; + + ssl_certificate /etc/ssl/acme/fullchain.pem; + ssl_certificate_key /etc/ssl/acme/key.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + if ($blocked_agent) { return 403; } + if ($http_user_agent = "") { return 403; } + + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + proxy_pass http://gitea:3000; + 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 https; + proxy_read_timeout 300; + proxy_connect_timeout 300; + proxy_send_timeout 300; + } +} + +# Jenkins HTTPS +server { + listen 443 ssl; + server_name jenkins.gong-dev.com; + server_tokens off; + + ssl_certificate /etc/ssl/acme/fullchain.pem; + ssl_certificate_key /etc/ssl/acme/key.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + if ($blocked_agent) { return 403; } + if ($http_user_agent = "") { return 403; } + + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + proxy_pass http://jenkins:8080; + 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 https; + proxy_read_timeout 300; + proxy_connect_timeout 300; + proxy_send_timeout 300; + } +} + +# casino.gong-dev.com — pkcasino01 +server { + listen 443 ssl; + server_name casino.gong-dev.com; + server_tokens off; + + ssl_certificate /etc/ssl/acme/fullchain.pem; + ssl_certificate_key /etc/ssl/acme/key.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + if ($blocked_agent) { return 403; } + if ($http_user_agent = "") { return 403; } + + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + set $backend "http://pkcasino01:80"; + proxy_pass $backend; + 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 https; + proxy_read_timeout 60; + proxy_connect_timeout 60; + } +} + +# admin.gong-dev.com — agent_oms +server { + listen 443 ssl; + server_name admin.gong-dev.com; + server_tokens off; + + ssl_certificate /etc/ssl/acme/fullchain.pem; + ssl_certificate_key /etc/ssl/acme/key.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + if ($blocked_agent) { return 403; } + if ($http_user_agent = "") { return 403; } + + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + set $backend "http://agent-oms:80"; + proxy_pass $backend; + 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 https; + proxy_read_timeout 60; + proxy_connect_timeout 60; + } +} + +# vendor.gong-dev.com — first_vendor_panel +server { + listen 443 ssl; + server_name vendor.gong-dev.com; + server_tokens off; + + ssl_certificate /etc/ssl/acme/fullchain.pem; + ssl_certificate_key /etc/ssl/acme/key.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + if ($blocked_agent) { return 403; } + if ($http_user_agent = "") { return 403; } + + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + set $backend "http://first-vendor-panel:80"; + proxy_pass $backend; + 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 https; + proxy_read_timeout 60; + proxy_connect_timeout 60; + } +} + +# api.gong-dev.com — oms_api +server { + listen 443 ssl; + server_name api.gong-dev.com; + server_tokens off; + client_max_body_size 20m; + + ssl_certificate /etc/ssl/acme/fullchain.pem; + ssl_certificate_key /etc/ssl/acme/key.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + if ($blocked_agent) { return 403; } + if ($http_user_agent = "") { return 403; } + + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + set $backend "http://oms-api:8080"; + proxy_pass $backend; + 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 https; + proxy_read_timeout 300; + proxy_connect_timeout 300; + proxy_send_timeout 300; + } +} + +# vapi.gong-dev.com — first_vendor_api +server { + listen 443 ssl; + server_name vapi.gong-dev.com; + server_tokens off; + client_max_body_size 20m; + + ssl_certificate /etc/ssl/acme/fullchain.pem; + ssl_certificate_key /etc/ssl/acme/key.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + if ($blocked_agent) { return 403; } + if ($http_user_agent = "") { return 403; } + + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + set $backend "http://first-vendor-api:8080"; + proxy_pass $backend; + 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 https; + proxy_read_timeout 300; + proxy_connect_timeout 300; + proxy_send_timeout 300; + } +} + +# batch.gong-dev.com — first_vendor_batch +server { + listen 443 ssl; + server_name batch.gong-dev.com; + server_tokens off; + + ssl_certificate /etc/ssl/acme/fullchain.pem; + ssl_certificate_key /etc/ssl/acme/key.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + if ($blocked_agent) { return 403; } + if ($http_user_agent = "") { return 403; } + + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + set $backend "http://first-vendor-batch:8080"; + proxy_pass $backend; + 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 https; + proxy_read_timeout 300; + proxy_connect_timeout 300; + proxy_send_timeout 300; + } +} + +# pk.gong-dev.com — pkcasino01 +server { + listen 443 ssl; + server_name pk.gong-dev.com; + server_tokens off; + + ssl_certificate /etc/ssl/acme/fullchain.pem; + ssl_certificate_key /etc/ssl/acme/key.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + if ($blocked_agent) { return 403; } + if ($http_user_agent = "") { return 403; } + + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + add_header Referrer-Policy "strict-origin-when-cross-origin" always; + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + + location / { + set $backend "http://pkcasino01:80"; + proxy_pass $backend; + 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 https; + proxy_read_timeout 60; + proxy_connect_timeout 60; + } +}