GCP VM을 사용한 서버 배포
소규모 서버 배포
GCP VM 준비
가장 저렴한 E2-micro(vCPU 2, 1GB 메모리)를 사용하고 Ubuntu 24.04 LTS를 사용합니다 vm생성후 ssh 접속을 통해 동작을 확인합니다
vm 인스턴스에서 초기 준비를 합니다. docker, docker-compose, docker rootless를 설치합니다
sudo apt update && sudo apt upgrade -y
sudo sh -eux <<EOF
# Install newuidmap & newgidmap binaries
apt-get install -y uidmap
EOF
dockerd-rootless-setuptool.sh install
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
또한 ssh 연결 종료후 서버 동작 유지를 위해 linger를 활성화 합니다 sudo loginctl enable-linger $(whoami)
GCP 방화벽 설정
VPC 네트워크 > 방화벽 > 방화벽 규칙 만들기 메뉴를 통해서 위에서 생성한 인스턴스에 대해 TCP 포트 8000을 허용합니다
GCP IAM 설정
gcloud compute ssh 를 사용하여 외부에서 인스턴스 제어를 위해 필요합니다
IAM 및 관리자 > 서비스계정 메뉴로 이동후 상단의 +서비스 계정 만들기 메뉴를 클릭합니다
서비스 계정 이름 입력 후 아래 3개 역할을 추가합니다
- 서비스 계정 사용자(Service Account User)
- Compute 인스턴스 관리자(Compute Instance Admin)
- Compute OS 로그인 (Compute OS Login)
Docker 작성
Dockerfile.backend 백엔드는 코틀린/스프링부트 조합입니다
FROM gradle:8.5.0-jdk17 AS build
WORKDIR /home/gradle/src
COPY build.gradle.kts settings.gradle.kts gradlew ./
COPY gradle ./gradle
RUN chmod +x ./gradlew
RUN ./gradlew dependencies --no-daemon
COPY src ./src
RUN ./gradlew bootJar -x test
FROM openjdk:17.0.1-jdk-slim
WORKDIR /app
COPY --from=build /home/gradle/src/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Dockerfile.frontend 프론트는 리액트로 구성되어 있습니다
FROM node:18-alpine AS build
WORKDIR /app/frontend
COPY frontend/package.json frontend/package-lock.json ./
RUN npm install
COPY frontend/ ./
RUN npm run build
FROM nginx:stable-alpine
COPY --from=build /app/frontend/dist /usr/share/nginx/html
COPY nginx.default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
GCP vm에서 사용할 docker-compose.yml 입니다
services:
backend:
image: your-docker-hub/backend:1.0
container_name: backend
restart: always
ports:
- "8080:8080"
networks:
- custom-net
frontend:
image: your-docker-hub/frontend:1.0
container_name: frontend
restart: always
ports:
- "8000:80"
depends_on:
- backend
networks:
- custom-net
networks:
custom-net:
driver: bridge
Github actions 워크플로우 작성
buildx 를 사용해서 backend, frontend 이미지를 빌드하고 dockerhub에 업로드합니다 이후 gcloud를 사용하여 gcp vm에 저장소를 최신화 하고 docker-compose 를 사용하여 최신상태 서버로 재시작합니다
name: CI/CD Pipeline to GCP VM
on:
push:
branches:
- main
jobs:
# 첫 번째 Job: Docker 이미지 빌드 및 푸시
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: $
password: $
- name: Build and push Backend image
run: |
export DOCKER_USER=$
export VERSION=1.0
docker buildx build \
--platform linux/amd64 \
-t $DOCKER_USER/backend:$VERSION \
-f Dockerfile.backend \
--push .
- name: Build and push Frontend image
run: |
export DOCKER_USER=$
export VERSION=1.0
docker buildx build \
--platform linux/amd64 \
-t $DOCKER_USER/frontend:$VERSION \
-f Dockerfile.frontend \
--push .
# 두 번째 Job: GCP VM에 배포
deploy:
needs: build # 'build' Job이 성공해야만 이 Job이 실행됨
runs-on: ubuntu-latest
steps:
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v2
with:
credentials_json: $
- name: Deploy to GCP VM via gcloud
run: |
gcloud compute ssh $@$ \
--project=$ \
--zone us-central1-c \
--command="cd ~/workspace && git pull --rebase && docker-compose pull && docker-compose up -d"
해야할일
- 고정 IP 주소 또는 도메인 연결
- Nginx 리버스 프록시 구성
- HTTPS/SSL 적용