사용 기호 설명
| 기호 |
의미 |
| @ |
브라우저 |
| ~$ |
VM 터미널 |
| ~# |
VM 내 Docker 컨테이너 |
| > |
별도 터미널 |
1. GCP VM 인스턴스 생성 및 기본 설정
VM 인스턴스 생성
graph TB
A[GCP 콘솔] --> B[새 프로젝트 생성]
B --> C[Compute Engine > VM 인스턴스]
C --> D[VM 설정]
D --> E[SSH 연결]
subgraph VM_설정
D1[이름: team-spring-mysql-fastapi-mongo]
D2[디스크: 50GB]
D3[방화벽: HTTP/HTTPS 허용]
end
D --> D1
D --> D2
D --> D3
기본 패키지 설치 (in GCP)
@ 새 프로젝트 생성: 'test-myproject'
@ Compute Engine > VM 인스턴스 > 'team-spring-mysql-fastapi-mongo' 생성
- 디스크 크기: 50GB
- 방화벽: HTTP/HTTPS 트래픽 허용
@ SSH 연결 클릭
~$ sudo apt-get update && sudo apt install -y unzip docker-compose nginx certbot python3-certbot-nginx dnsutils nano vim
# Docker Compose 바이너리 설치
~$ docker-compose --version
# 시스템 상태 확인
~$ lscpu
~$ df -h
~$ sudo systemctl status nginx
~$ wget 127.0.0.1
2. DNS 관리 및 서브도메인 설정
메인 도메인 및 서브도메인 DNS 설정
graph LR
A[DNS 관리자] --> B[메인 도메인 설정]
A --> C[서브도메인 설정]
subgraph DNS_Records
B1["@ → GCP_VM_IP"]
B2["www → GCP_VM_IP"]
C1["fast → GCP_VM_IP"]
end
B --> B1
B --> B2
C --> C1
DNS 설정 과정
@ https://dns.gabia.com/ (가비아 DNS 관리)
> 도메인 관리 > 'cocolabhub.store' 선택
> DNS 레코드 설정:
- @ (A 레코드) → VM 외부 IP
- www (A 레코드) → VM 외부 IP
- fast (A 레코드) → VM 외부 IP
# DNS 전파 확인
~$ nslookup cocolabhub.store
~$ nslookup www.cocolabhub.store
~$ nslookup fast.cocolabhub.store
3. Docker 컨테이너 설치 및 구성
Docker 환경 설정
~$ sudo docker system prune
@ https://cocolabhub.com/teams/list
> 원하는 팀의 'shell' 버튼 클릭
~$ wget -O docker_files.zip http://cocolabhub.com/comodules/r/download/[PROJECT_ID]
~$ unzip docker_files.zip -d docker_folder && cd ./docker_folder
~/docker_folder$ sudo docker-compose build --no-cache
~/docker_folder$ sudo docker-compose --project-name teams_java_jupyterlab_mysql up -d
# 컨테이너 상태 확인
~$ sudo docker ps
~$ sudo docker exec -it [CONTAINER_NAME] bash
4. FastAPI 서버 설정
FastAPI 서버 구성 및 실행
# 기존 FastAPI 프로세스 종료
~# ps aux | grep uvicorn
~# kill -9 [PID]
# 환경 설정
~# apt-get update && apt install -y nano
~# cd /apps/fastapis/app && nano .env
# 최신 코드 업데이트
/apps/fastapis/app# cd ../ && git pull
# FastAPI 서버 실행
/apps/fastapis# nohup uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 --workers 2 &
/apps/fastapis# tail -f nohup.out
# 로컬 테스트
outside_docker:~$ wget http://localhost:8000
5. Spring Boot 서버 설정
Spring Boot 애플리케이션 구성
# 기존 Spring Boot 프로세스 종료
~# ps aux | grep gradlew
~# kill -9 [PID]
# 애플리케이션 설정 파일 수정
~# cd /apps/springboots && nano ./src/main/resources/application.properties
application.properties 주요 설정
server.address=0.0.0.0
server.port=8080
spring.datasource.url=jdbc:mysql://[fastapi_spring-db_mysql_8-1]:3306/cocolang
remote.server.url=http://[cocolabhub.store]:80/images/
Spring Boot 서버 실행
/apps/springboots# chmod +x ./gradlew && nohup ./gradlew bootRun &
/apps/springboots# tail -f nohup.out
/apps/springboots# exit
# 로컬 테스트
outside_docker:~$ wget http://localhost:8080
6. HTTPS 인증서 및 Nginx 설정
SSL 인증서 발급 (메인 도메인 + 서브도메인)
# 모든 도메인에 대해 SSL 인증서 발급
~$ sudo certbot --nginx -d cocolabhub.store -d www.cocolabhub.store -d fast.cocolabhub.store
Nginx 설정 파일 구성
~$ sudo rm /etc/nginx/sites-available/default
~$ sudo nano /etc/nginx/sites-available/default
Nginx 설정 파일 내용
# HTTP to HTTPS 리다이렉트
server {
listen 80;
server_name cocolabhub.store www.cocolabhub.store fast.cocolabhub.store;
# Let's Encrypt 인증을 위한 예외
location /.well-known/acme-challenge/ {
root /var/www/html;
}
# 모든 HTTP 요청을 HTTPS로 리다이렉트
location / {
return 301 https://$server_name$request_uri;
}
}
# HTTPS - Spring Boot (메인 도메인)
server {
listen 443 ssl http2;
server_name cocolabhub.store www.cocolabhub.store;
ssl_certificate /etc/letsencrypt/live/cocolabhub.store/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cocolabhub.store/privkey.pem;
# SSL 보안 설정
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
location / {
proxy_pass http://localhost: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 $scheme;
}
}
# HTTPS - FastAPI (서브도메인)
server {
listen 443 ssl http2;
server_name fast.cocolabhub.store;
ssl_certificate /etc/letsencrypt/live/cocolabhub.store/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/cocolabhub.store/privkey.pem;
# SSL 보안 설정
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
location / {
proxy_pass http://localhost:8000;
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;
}
}
Nginx 설정 적용
# 설정 파일 문법 검사
~$ sudo nginx -t
# Nginx 재시작
~$ sudo systemctl restart nginx
# 서비스 상태 확인
~$ sudo systemctl status nginx
7. 최종 서비스 구성도
graph TB
subgraph Internet
U1[사용자 - Spring Boot]
U2[사용자 - FastAPI]
end
subgraph "DNS (cocolabhub.store)"
D1[@ → GCP VM IP]
D2[www → GCP VM IP]
D3[fast → GCP VM IP]
end
subgraph "GCP VM Instance"
subgraph "Nginx (포트 80/443)"
N1[HTTP → HTTPS 리다이렉트]
N2[HTTPS Proxy]
end
subgraph "Docker 컨테이너"
S1[Spring Boot :8080]
F1[FastAPI :8000]
M1[MySQL :3306]
end
end
U1 --> D1
U1 --> D2
U2 --> D3
D1 --> N2
D2 --> N2
D3 --> N2
N2 --> S1
N2 --> F1
S1 --> M1
F1 --> M1
8. 서비스 접속 확인
최종 접속 테스트
접속 확인 명령어
# HTTPS 접속 테스트
@ https://cocolabhub.store/ -> Spring Boot
@ https://www.cocolabhub.store/ -> Spring Boot
@ https://fast.cocolabhub.store/ -> FastAPI
@ https://fast.cocolabhub.store/images/empty.txt -> FastAPI
# 서버 상태 확인
~$ curl -I https://cocolabhub.store/
~$ curl -I https://fast.cocolabhub.store/
9. 유지보수 및 모니터링
SSL 인증서 자동 갱신 설정
# 자동 갱신 테스트
~$ sudo certbot renew --dry-run
# cron 작업 설정 (선택사항)
~$ sudo crontab -e
# 다음 라인 추가: 0 12 * * * /usr/bin/certbot renew --quiet
서비스 상태 모니터링
# Docker 컨테이너 상태 확인
~$ sudo docker ps -a
# 서비스 로그 확인
~$ sudo docker logs [CONTAINER_NAME]
# Nginx 로그 확인
~$ sudo tail -f /var/log/nginx/access.log
~$ sudo tail -f /var/log/nginx/error.log
10. 트러블슈팅
일반적인 문제 해결
| 문제 |
해결 방법 |
| SSL 인증서 오류 |
sudo certbot renew 실행 |
| Nginx 설정 오류 |
sudo nginx -t로 문법 검사 |
| 서브도메인 접속 불가 |
DNS 전파 확인 (nslookup fast.cocolabhub.store) |
| 컨테이너 접속 불가 |
sudo docker ps로 상태 확인 |
서비스 재시작 순서
# 1. Docker 컨테이너 재시작
~$ sudo docker-compose restart
# 2. Nginx 재시작
~$ sudo systemctl restart nginx
# 3. 전체 시스템 재부팅 (필요시)
~$ sudo reboot