05.1.Clouds‐GCP - yojulab/learn_DevOps GitHub Wiki

사용 기호 설명

기호 의미
@ 브라우저
~$ 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. 서비스 접속 확인

최종 접속 테스트

서비스 URL 대상 서버
Spring Boot (HTTPS) https://cocolabhub.store/ :8080
Spring Boot (HTTPS) https://www.cocolabhub.store/ :8080
FastAPI (HTTPS) https://fast.cocolabhub.store/ :8000
이미지 서비스 https://fast.cocolabhub.store/images/empty.txt :8000

접속 확인 명령어

# 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