From b0a073e9efdd2f8234945883918b2e3788405131 Mon Sep 17 00:00:00 2001 From: scarf Date: Fri, 11 Aug 2023 20:43:28 +0900 Subject: [PATCH 1/5] =?UTF-8?q?build:=20=EA=B0=9C=EB=B0=9C=20=EC=84=9C?= =?UTF-8?q?=EB=B2=84=EC=9A=A9=20=EC=BB=B4=ED=8F=AC=EC=A6=88=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 1 + .gitignore | 3 +- docker-compose.dev.yaml | 51 ++++++++++++++++++++++ init-letsencrypt.sh | 81 +++++++++++++++++++++++++++++++++++ nginx.dev/conf.d/default.conf | 77 +++++++++++++++++++++++++++++++++ nginx.dev/nginx.conf | 31 ++++++++++++++ nginx.dev/nginx.dockerfile | 9 ++++ scripts/init-dev.sh | 31 ++++++++++++++ scripts/start-dev.sh | 3 ++ scripts/start.sh | 4 +- scripts/stop-dev.sh | 3 ++ scripts/stop.sh | 2 + 12 files changed, 294 insertions(+), 2 deletions(-) create mode 100644 docker-compose.dev.yaml create mode 100755 init-letsencrypt.sh create mode 100644 nginx.dev/conf.d/default.conf create mode 100644 nginx.dev/nginx.conf create mode 100644 nginx.dev/nginx.dockerfile create mode 100755 scripts/init-dev.sh create mode 100755 scripts/start-dev.sh mode change 100644 => 100755 scripts/start.sh create mode 100755 scripts/stop-dev.sh mode change 100644 => 100755 scripts/stop.sh diff --git a/.dockerignore b/.dockerignore index 0c7125d0..b7dc2c03 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,5 @@ **/node_modules **/.env +**/.env.* database .github diff --git a/.gitignore b/.gitignore index 08a5fc9a..c4a819e4 100644 --- a/.gitignore +++ b/.gitignore @@ -122,4 +122,5 @@ package-lock.json .idea # nginx -.htpasswd +nginx.dev/certbot +**/*.htpasswd diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml new file mode 100644 index 00000000..4fce69dc --- /dev/null +++ b/docker-compose.dev.yaml @@ -0,0 +1,51 @@ +# https://github.com/wmnnd/nginx-certbot +# https://scribe.rip/@pentacent/nginx-and-lets-encrypt-with-docker-in-less-than-5-minutes-b4b8a60d3a71 +services: + nginx: + container_name: nginx + image: nginx:1.25.1-alpine + # image: nginx:dev + # build: + # context: nginx.dev + # dockerfile: nginx.dockerfile + restart: unless-stopped + ports: + - 80:80 + - 443:443 + environment: + - TZ=Asia/Seoul + volumes: + - ./nginx.dev/nginx.conf:/etc/nginx/nginx.conf + - ./nginx.dev/conf.d:/etc/nginx/conf.d + + - ./nginx.dev/certbot/conf:/etc/letsencrypt + - ./nginx.dev/certbot/www:/var/www/certbot + + - ./logs/nginx:/var/log/nginx/ + # command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx'" + + certbot: + image: certbot/dns-route53 + restart: unless-stopped + volumes: + - ./nginx.dev/certbot/conf:/etc/letsencrypt + - ./nginx.dev/certbot/www:/var/www/certbot + + - ./logs/certbot:/var/log/letsencrypt + entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" + env_file: + - .env.certbot + + backend: + container_name: backend + image: backend:dev + build: + context: . + restart: on-failure + entrypoint: ["./node_modules/.bin/vite-node", "src/server.ts"] + volumes: + - ./logs/backend:/app/backend/logs + env_file: .env.rds + environment: + - MODE=RDS + - TZ=Asia/Seoul diff --git a/init-letsencrypt.sh b/init-letsencrypt.sh new file mode 100755 index 00000000..bd9ee262 --- /dev/null +++ b/init-letsencrypt.sh @@ -0,0 +1,81 @@ +#!/bin/bash + +if ! [ -x "$(command -v docker)" ]; then + echo 'Error: docker is not installed.' >&2 + exit 1 +fi + +domains=("dev.42library.kr") +rsa_key_size=4096 +data_path="./nginx/certbot" +email="42.4.youkim@gmail.com" # Adding a valid address is strongly recommended +staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits +compose=docker-compose.dev.yaml + +if [ -d "$data_path" ]; then + read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision + if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then + exit + fi +fi + + +if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then + echo "### Downloading recommended TLS parameters ..." + mkdir -p "$data_path/conf" + curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf" + curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem" + echo +fi + +echo "### Creating dummy certificate for $domains ..." +path="/etc/letsencrypt/live/$domains" +mkdir -p "$data_path/conf/live/$domains" +sudo docker compose -f $compose run --rm --entrypoint "\ + openssl req -x509 -nodes -newkey rsa:$rsa_key_size -days 1\ + -keyout '$path/privkey.pem' \ + -out '$path/fullchain.pem' \ + -subj '/CN=localhost'" certbot +echo + + +echo "### Starting nginx ..." +sudo docker compose -f $compose up --force-recreate -d nginx +echo + +echo "### Deleting dummy certificate for $domains ..." +sudo docker compose -f $compose run --rm --entrypoint "\ + rm -Rf /etc/letsencrypt/live/$domains && \ + rm -Rf /etc/letsencrypt/archive/$domains && \ + rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot +echo + + +echo "### Requesting Let's Encrypt certificate for $domains ..." +#Join $domains to -d args +domain_args="" +for domain in "${domains[@]}"; do + domain_args="$domain_args -d $domain" +done + +# Select appropriate email arg +case "$email" in + "") email_arg="--register-unsafely-without-email" ;; + *) email_arg="--email $email" ;; +esac + +# Enable staging mode if needed +if [ $staging != "0" ]; then staging_arg="--staging"; fi + +sudo docker compose -f $compose run --rm --entrypoint "\ + certbot certonly -n --dns-route53 \ + $staging_arg \ + --agree-tos \ + $email_arg \ + $domain_args \ + --rsa-key-size $rsa_key_size \ + --force-renewal" certbot +echo + +echo "### Reloading nginx ..." +sudo docker compose -f $compose exec nginx nginx -s reload diff --git a/nginx.dev/conf.d/default.conf b/nginx.dev/conf.d/default.conf new file mode 100644 index 00000000..01ec7260 --- /dev/null +++ b/nginx.dev/conf.d/default.conf @@ -0,0 +1,77 @@ +server { + listen 80; + server_name dev.42library.kr; + + access_log /dev/stdout main; + # access_log /var/log/nginx/access.log main; + + location /.well-known/acme-challenge/ { + root /var/www/certbot; + } + location / { + return 301 https://$host$request_uri; # Redirect all HTTP to HTTPS + } +} + +server { + listen 443 ssl; + server_name dev.42library.kr; + + access_log /var/log/nginx/https.access.log main; + + # SSL configuration + ssl_certificate /etc/letsencrypt/live/dev.42library.kr/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/dev.42library.kr/privkey.pem; + ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; + include /etc/letsencrypt/options-ssl-nginx.conf; + + # Add HTTP Strict Transport Security (HSTS) to enforce HTTPS + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # Enforces HTTPS on all requests + + # Security headers + add_header X-Content-Type-Options "nosniff" always; # Prevents MIME type sniffing + add_header X-Frame-Options "SAMEORIGIN" always; # Prevents clickjacking + add_header X-XSS-Protection "1; mode=block" always; # Helps protect against XSS attacks + add_header Content-Security-Policy "default-src 'self';" always; # Limits sources of content to only trusted domains + + + location /api/ { + # Add rate limiting + limit_req zone=api burst=5; + + proxy_pass http://backend: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 $scheme; + } + location /swagger/ { + auth_basic "Admin page"; + auth_basic_user_file /etc/nginx/conf.d/.htpasswd; + + proxy_pass http://backend: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 $scheme; + } + location /swagger-v2/ { + auth_basic "Admin page"; + auth_basic_user_file /etc/nginx/conf.d/.htpasswd; + + proxy_pass http://backend: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 $scheme; + } + + # redirect server error pages to the static page /50x.html + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/nginx.dev/nginx.conf b/nginx.dev/nginx.conf new file mode 100644 index 00000000..399e94b6 --- /dev/null +++ b/nginx.dev/nginx.conf @@ -0,0 +1,31 @@ +user nginx; +worker_processes auto; +# error_log /var/log/nginx/error.log warn; +error_log /dev/stdout info; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + server_tokens off; + + log_format main '[$time_iso8601] $remote_addr - $host $remote_user ' + '"$request" $status b=$body_bytes_sent ' + '"$http_referer" "$http_user_agent" ' + 'ssl=$ssl_cipher rt=$request_time'; + + sendfile off; + # tcp_nopush on; + + keepalive_timeout 65; + + #gzip on; + + limit_req_zone $binary_remote_addr zone=api:10m rate=1r/s; + + include /etc/nginx/conf.d/*.conf; +} diff --git a/nginx.dev/nginx.dockerfile b/nginx.dev/nginx.dockerfile new file mode 100644 index 00000000..abe1fa5e --- /dev/null +++ b/nginx.dev/nginx.dockerfile @@ -0,0 +1,9 @@ +FROM nginx:1.25.1-alpine + +# drop symlinks, logs are bind-mounted +RUN unlink /var/log/nginx/access.log +RUN unlink /var/log/nginx/error.log + +COPY ./nginx.conf /etc/nginx/nginx.conf +COPY ./conf.d /etc/nginx/conf.d + diff --git a/scripts/init-dev.sh b/scripts/init-dev.sh new file mode 100755 index 00000000..dcffa22b --- /dev/null +++ b/scripts/init-dev.sh @@ -0,0 +1,31 @@ +sudo apt-get update +sudo apt-get upgrade -y + +# https://docs.docker.com/engine/install/debian/ +for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do sudo apt-get remove $pkg; done + +# setup apt repository (and install utils) +sudo apt-get -y install ca-certificates curl gnupg git fish + +sudo install -m 0755 -d /etc/apt/keyrings +curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg +sudo chmod a+r /etc/apt/keyrings/docker.gpg + +echo \ + "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \ + "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list > /dev/null + +sudo apt-get update + +# install docker engine +sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + +# setup backend +git clone https://github.com/jiphyeonjeon-42/backend + +# change shell to fish +sudo chsh admin -s /usr/bin/fish + +# change timezone to KST +sudo timedatectl set-timezone Asia/Seoul diff --git a/scripts/start-dev.sh b/scripts/start-dev.sh new file mode 100755 index 00000000..1832e97f --- /dev/null +++ b/scripts/start-dev.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +docker compose -f docker-compose.dev.yaml up $@ diff --git a/scripts/start.sh b/scripts/start.sh old mode 100644 new mode 100755 index b7fa4a4c..1d4730d2 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -1 +1,3 @@ -docker-compose -f ~/backend-express/docker-compose.yaml up -d --build \ No newline at end of file +#!/bin/sh + +docker-compose -f ~/backend-express/docker-compose.yaml up -d --build diff --git a/scripts/stop-dev.sh b/scripts/stop-dev.sh new file mode 100755 index 00000000..d0046dd4 --- /dev/null +++ b/scripts/stop-dev.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +docker compose -f docker-compose.dev.yaml down diff --git a/scripts/stop.sh b/scripts/stop.sh old mode 100644 new mode 100755 index 4cc06a2a..914ede23 --- a/scripts/stop.sh +++ b/scripts/stop.sh @@ -1 +1,3 @@ +#!/bin/sh + docker-compose -f ~/backend-express/docker-compose.yaml down From 80d5037fa031d8d84e8911100b7d779c5cfb30f4 Mon Sep 17 00:00:00 2001 From: scarf Date: Wed, 16 Aug 2023 09:22:12 +0900 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20localhost=20https=20=ED=97=88?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/app.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/app.ts b/backend/src/app.ts index aa7be1de..ce1b4d07 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -31,6 +31,7 @@ app.use( cors({ origin: [ 'http://localhost:4242', + 'https://localhost:4242', 'http://42library.kr', 'https://42library.kr', 'http://42jip.com', From 61a784237328d6bbaf5ceed3637a8cd2d764cd92 Mon Sep 17 00:00:00 2001 From: scarf Date: Wed, 16 Aug 2023 09:43:24 +0900 Subject: [PATCH 3/5] =?UTF-8?q?build(docker):=20=ED=95=84=EC=9A=94=20?= =?UTF-8?q?=EC=97=86=EB=8A=94=20=ED=8C=8C=EC=9D=BC=EA=B3=BC=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 20 ++++++++++++++++- Dockerfile | 6 +++-- backend/package.json | 2 +- pnpm-lock.yaml | 52 +++++++++++++++++++++----------------------- 4 files changed, 49 insertions(+), 31 deletions(-) diff --git a/.dockerignore b/.dockerignore index b7dc2c03..4901616f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,23 @@ +.* +.git +.github +**/logs **/node_modules **/.env **/.env.* database -.github +**/dist +**/*.md +**/.vscode +**/.eslintrc.json +**/*.log +**/.npmignore +**/LICENSE +docker-compose* +Dockerfile +appspec.yml +scripts +packages +nginx* +docs +backend/jest.config.js diff --git a/Dockerfile b/Dockerfile index 91750237..2adc9a24 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,13 +13,15 @@ FROM pnpm-installed as workspace COPY ./pnpm-lock.yaml . COPY patches patches -RUN pnpm fetch +RUN pnpm fetch --prod FROM workspace as prod ADD . ./ -RUN pnpm -r install --frozen-lockfile --offline +RUN pnpm -r install --frozen-lockfile --offline --prod RUN pnpm -r run build +RUN rm -rf /app/.pnpm-store + WORKDIR /app/backend diff --git a/backend/package.json b/backend/package.json index 8e288697..520e33a0 100644 --- a/backend/package.json +++ b/backend/package.json @@ -79,7 +79,7 @@ "ts-pattern": "^5.0.1", "typeorm": "^0.3.11", "vite": "^4.4.7", - "vite-node": "https://github.com/scarf005/vitest/releases/download/v0.33.0-2023-07-30/vite-node-0.33.0.tgz", + "vite-node": "^0.34.1", "vite-tsconfig-paths": "^4.2.0", "winston": "^3.6.0", "winston-daily-rotate-file": "^4.6.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a7a36b96..e46fdb85 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -121,8 +121,8 @@ importers: specifier: ^4.4.7 version: 4.4.7(@types/node@18.16.1) vite-node: - specifier: https://github.com/scarf005/vitest/releases/download/v0.33.0-2023-07-30/vite-node-0.33.0.tgz - version: '@github.com/scarf005/vitest/releases/download/v0.33.0-2023-07-30/vite-node-0.33.0.tgz(@types/node@18.16.1)' + specifier: ^0.34.1 + version: 0.34.1(@types/node@18.16.1) vite-tsconfig-paths: specifier: ^4.2.0 version: 4.2.0(typescript@5.1.6)(vite@4.4.7) @@ -6949,6 +6949,7 @@ packages: /typescript@5.1.6: resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==} engines: {node: '>=14.17'} + hasBin: true /ufo@1.2.0: resolution: {integrity: sha512-RsPyTbqORDNDxqAdQPQBpgqhWle1VcTSou/FraClYlHf6TZnQcGslpLcAphNR+sQW4q5lLWLbOsRlh9j24baQg==} @@ -7084,6 +7085,28 @@ packages: engines: {node: '>= 0.8'} dev: false + /vite-node@0.34.1(@types/node@18.16.1): + resolution: {integrity: sha512-odAZAL9xFMuAg8aWd7nSPT+hU8u2r9gU3LRm9QKjxBEF2rRdWpMuqkrkjvyVQEdNFiBctqr2Gg4uJYizm5Le6w==} + engines: {node: '>=v14.18.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + mlly: 1.4.0 + pathe: 1.1.1 + picocolors: 1.0.0 + vite: 4.4.7(@types/node@18.16.1) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + dev: false + /vite-tsconfig-paths@4.2.0(typescript@5.1.6)(vite@4.4.7): resolution: {integrity: sha512-jGpus0eUy5qbbMVGiTxCL1iB9ZGN6Bd37VGLJU39kTDD6ZfULTTb1bcc5IeTWqWJKiWV5YihCaibeASPiGi8kw==} peerDependencies: @@ -7403,28 +7426,3 @@ packages: /zod@3.22.2: resolution: {integrity: sha512-wvWkphh5WQsJbVk1tbx1l1Ly4yg+XecD+Mq280uBGt9wa5BKSWf4Mhp6GmrkPixhMxmabYY7RbzlwVP32pbGCg==} - - '@github.com/scarf005/vitest/releases/download/v0.33.0-2023-07-30/vite-node-0.33.0.tgz(@types/node@18.16.1)': - resolution: {tarball: https://github.com/scarf005/vitest/releases/download/v0.33.0-2023-07-30/vite-node-0.33.0.tgz} - id: '@github.com/scarf005/vitest/releases/download/v0.33.0-2023-07-30/vite-node-0.33.0.tgz' - name: vite-node - version: 0.33.0 - engines: {node: '>=v14.18.0'} - hasBin: true - dependencies: - cac: 6.7.14 - debug: 4.3.4 - mlly: 1.4.0 - pathe: 1.1.1 - picocolors: 1.0.0 - vite: 4.4.7(@types/node@18.16.1) - transitivePeerDependencies: - - '@types/node' - - less - - lightningcss - - sass - - stylus - - sugarss - - supports-color - - terser - dev: false From 42eda9dfbd154964ce57f9182fc429c4303c4253 Mon Sep 17 00:00:00 2001 From: scarf Date: Wed, 16 Aug 2023 11:09:52 +0900 Subject: [PATCH 4/5] =?UTF-8?q?fix:=2042=20api=20=ED=97=88=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nginx.dev/conf.d/default.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nginx.dev/conf.d/default.conf b/nginx.dev/conf.d/default.conf index 01ec7260..19b68a8c 100644 --- a/nginx.dev/conf.d/default.conf +++ b/nginx.dev/conf.d/default.conf @@ -32,8 +32,8 @@ server { add_header X-Content-Type-Options "nosniff" always; # Prevents MIME type sniffing add_header X-Frame-Options "SAMEORIGIN" always; # Prevents clickjacking add_header X-XSS-Protection "1; mode=block" always; # Helps protect against XSS attacks - add_header Content-Security-Policy "default-src 'self';" always; # Limits sources of content to only trusted domains - + # Limits sources of content to only trusted domains + add_header Content-Security-Policy "default-src 'self'; frame-src 'self' https://api.intra.42.fr;" always; location /api/ { # Add rate limiting From 349805c697a7e5c289112a4cfcd6daa5d05d68af Mon Sep 17 00:00:00 2001 From: scarf Date: Wed, 16 Aug 2023 11:30:23 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20https=20=EB=AA=A8=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/src/@types/process.env.d.ts | 13 ++++++++++--- backend/src/config/JwtOption.ts | 10 +++++++--- backend/src/config/config.type.ts | 4 ++-- backend/src/config/getConnectOption.ts | 2 +- backend/src/config/modeOption.ts | 2 +- docker-compose.dev.yaml | 6 ++++-- 6 files changed, 25 insertions(+), 12 deletions(-) diff --git a/backend/src/@types/process.env.d.ts b/backend/src/@types/process.env.d.ts index e2dee0e0..fb1cda30 100644 --- a/backend/src/@types/process.env.d.ts +++ b/backend/src/@types/process.env.d.ts @@ -35,8 +35,15 @@ export declare global { /** 42 API OAuth 리다이렉트 URL */ REDIRECT_URL: string; - /** 레포지토리 선택 모드 */ - MODE: 'local' | 'RDS' | 'prod'; + /** + * 레포지토리 선택 모드 + * + * - local: 호스트 머신의 DB에 연결 + * - prod: 도커 컨테이너의 DB에 연결 + * - RDS: AWS RDS에 연결 + * - https: RDS + SSL에 연결 + */ + MODE: 'local' | 'RDS' | 'prod' | 'https'; // local 또는 prod MODE에서 /** MySQL 데이터베이스 이름 */ @@ -48,7 +55,7 @@ export declare global { /** MySQL 데이터베이스 사용자 이름 */ MYSQL_USER?: string; - // RDS MODE에서 + // RDS 또는 https MODE에서 /** RDS 데이터베이스 이름 */ RDS_DB_NAME?: string; /** RDS 데이터베이스 주소 */ diff --git a/backend/src/config/JwtOption.ts b/backend/src/config/JwtOption.ts index e3553141..ffd0a186 100644 --- a/backend/src/config/JwtOption.ts +++ b/backend/src/config/JwtOption.ts @@ -2,15 +2,19 @@ import { z } from 'zod'; import { JwtOption, OauthUrlOption } from './config.type'; import { nonempty } from './envObject'; import { Mode } from './modeOption'; +import { match } from 'ts-pattern'; type getJwtOption = (mode: Mode) => (option: OauthUrlOption) => JwtOption; export const getJwtOption: getJwtOption = (mode) => ({ redirectURL, clientURL }) => { const redirectDomain = new URL(redirectURL).hostname; const clientDomain = new URL(clientURL).hostname; + const secure = mode === 'prod' || mode === 'https'; - const issuer = mode === 'local' ? 'localhost' : redirectDomain; - const domain = mode === 'prod' ? clientDomain : 'localhost'; - const secure = mode === 'prod'; + const issuer = secure ? redirectDomain : 'localhost'; + const domain = match(mode) + .with('prod', () => clientDomain) + .with('https', () => undefined) + .otherwise(() => 'localhost'); return { issuer, domain, secure }; }; diff --git a/backend/src/config/config.type.ts b/backend/src/config/config.type.ts index a234e9a7..69d1a86e 100644 --- a/backend/src/config/config.type.ts +++ b/backend/src/config/config.type.ts @@ -3,10 +3,10 @@ import { levels } from './logOption'; /** JWT 발급 옵션 */ export type JwtOption = { /** JWT 발급자 */ - issuer: string | 'localhost' + issuer: string | 'localhost'; /** JWT 도메인 */ - domain: string | 'localhost' + domain: string | 'localhost' | undefined; /** Cookie Secure 사용 여부 */ secure: boolean; diff --git a/backend/src/config/getConnectOption.ts b/backend/src/config/getConnectOption.ts index 9573d808..80eee87e 100644 --- a/backend/src/config/getConnectOption.ts +++ b/backend/src/config/getConnectOption.ts @@ -6,7 +6,7 @@ import { Mode } from './modeOption'; /** DB 모드에 따라 사용할 DB 연결 옵션 스키마를 고르는 함수 */ const getConnectOptionSchema = (mode: Mode) => { if (mode === 'local') return localSchema; - if (mode === 'RDS') return rdsSchema; + if (mode === 'RDS' || mode === 'https') return rdsSchema; return prodSchema; }; diff --git a/backend/src/config/modeOption.ts b/backend/src/config/modeOption.ts index e18e37ee..fd799eb3 100644 --- a/backend/src/config/modeOption.ts +++ b/backend/src/config/modeOption.ts @@ -1,7 +1,7 @@ import { z } from 'zod'; /** DB 모드를 정의하는 스키마 */ -export const modeSchema = z.enum(['local', 'RDS', 'prod']); +export const modeSchema = z.enum(['local', 'RDS', 'prod', 'https']); /** DB 선택 모드 */ export type Mode = z.infer; diff --git a/docker-compose.dev.yaml b/docker-compose.dev.yaml index 4fce69dc..f48a3897 100644 --- a/docker-compose.dev.yaml +++ b/docker-compose.dev.yaml @@ -44,8 +44,10 @@ services: restart: on-failure entrypoint: ["./node_modules/.bin/vite-node", "src/server.ts"] volumes: + - ./backend/src:/app/backend/src + - ./logs/backend:/app/backend/logs - env_file: .env.rds + env_file: .env.https environment: - - MODE=RDS + - MODE=https - TZ=Asia/Seoul