사용 기호 설명
| 기호 | 의미 | 
| @ | 브라우저 | 
| ~$ | 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