your-project/
├── docker-compose.yml
├── nginx/
│ ├── nginx.conf
│ ├── certs/
│ │ ├── fullchain.pem
│ │ └── privkey.pem
│ └── logs/ # 로그 디렉토리 (마운트됨)
├── static/
│ └── index.html
└── backend/
├── Dockerfile
└── (Spring 소스 코드 등)
version: '3.8'
services:
nginx:
image: nginx:stable
container_name: nginx
restart: always
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
- ./static:/usr/share/nginx/html:ro
- ./nginx/certs:/etc/nginx/certs:ro
- ./nginx/logs:/var/log/nginx
depends_on:
backend:
condition: service_healthy
networks:
- frontend
backend:
image: your-backend-image # 예: junhyunny/my-spring-app
container_name: backend
restart: always
ports:
- "8080:8080" # 필요시 외부 접근 허용, 내부만 사용시 expose로 변경 가능
environment:
- SPRING_PROFILES_ACTIVE=prod
healthcheck:
test: ["CMD", "curl", "--fail", "--silent", "--connect-timeout", "5", "<http://localhost:8080/actuator/health>"]
interval: 30s
timeout: 10s
retries: 3
networks:
- frontend
networks:
frontend:
driver: bridge
worker_processes auto;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
# Gzip 압축
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript;
# 캐시 처리 (정적 리소스)
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
# HTTP → HTTPS 리디렉션
server {
listen 80;
server_name localhost;
return 301 https://$host$request_uri;
}
# HTTPS 메인 서버
server {
listen 443 ssl http2;
server_name localhost;
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/privkey.pem;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html; # SPA 라우팅 대응
}
location /api/ {
rewrite ^/api(/.*)$ $1 break; # prefix 유지
proxy_pass <http://backend:8080>;
proxy_http_version 1.1;
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 ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 7d;
add_header Cache-Control "public";
}
}
}
| 항목 | Perplexity 예제 | 개선된 버전 (GPT) |
|---|---|---|
| API 경로 proxy | /api/ → /로 prefix 손실 | rewrite로 prefix 유지 |
| gzip 압축 | ❌ 없음 | ✅ 실무에서 필수 적용 |
| 정적 파일 캐싱 | ❌ 없음 | ✅ Cache-Control, expires |
| HTTP/2 지원 | ❌ 없음 | ✅ listen 443 ssl http2; |
| healthcheck | 기본 curl만 | --silent, --connect-timeout 추가 |
| 로그 디렉토리 | 폴더 유무 확인 안됨 | :rw 권한 명시 및 폴더 구성 제안 |
| SPA 지원 | ❌ 없음 | ✅ try_files $uri /index.html |
| 설정 유효성 검사 | ❌ 없음 | 📌 운영 시 nginx -t 필수 검증 필요 |
주요 피드백 반영 포인트
worker_processes auto;로 CPU 코어 수에 맞춰 성능 최적화