- 사전 요구사항
- Artifact Registry 설정
- Docker 이미지 빌드 및 푸시
- 환경 설정 파일 준비
- Credentials 디렉토리 생성
- MySQL Exporter 설정
- 인스턴스별 배포 순서
- 헬스체크 및 검증
- 롤백 절차
- 이미지 버전 동기화 체크리스트
- 트러블슈팅
- gcloud CLI: 설치 및 인증 완료
- Docker: 로컬에 설치되어 있어야 함
- Git: backend 레포지토리 클론 필요
# gcloud 설치 확인
gcloud version
# gcloud 인증
gcloud auth login
gcloud config set project <your-project-id>
# Docker 설치 확인
docker --version- GCE 인스턴스 6개 생성 완료
speedcam-db(MySQL)speedcam-mq(RabbitMQ)speedcam-app(Traefik + Django API)speedcam-ocr(OCR Worker)speedcam-alert(Alert Worker)speedcam-mon(Monitoring Stack)
- VPC 네트워크 설정 완료 (내부 IP 통신 가능)
- 방화벽 규칙 설정 완료
# 인스턴스 내부 IP 확인
gcloud compute instances list --filter="name~speedcam" \
--format="table(name, networkInterfaces[0].networkIP, networkInterfaces[0].accessConfigs[0].natIP)"예시 출력:
NAME INTERNAL_IP EXTERNAL_IP
speedcam-db 10.178.0.11 34.xxx.xxx.xxx
speedcam-mq 10.178.0.12 34.xxx.xxx.xxx
speedcam-app 10.178.0.13 34.xxx.xxx.xxx
speedcam-ocr 10.178.0.14 34.xxx.xxx.xxx
speedcam-alert 10.178.0.15 34.xxx.xxx.xxx
speedcam-mon 10.178.0.20 34.xxx.xxx.xxx
# Artifact Registry 저장소 생성 (asia-northeast3 리전)
gcloud artifacts repositories create speedcam \
--repository-format=docker \
--location=asia-northeast3 \
--description="SpeedCam Docker Images"
# 생성 확인
gcloud artifacts repositories list --location=asia-northeast3# Artifact Registry 인증 구성
gcloud auth configure-docker asia-northeast3-docker.pkg.dev중요: 이미지 빌드는 backend 레포지토리에서 수행합니다.
# backend 레포지토리 클론 (아직 없다면)
git clone <backend-repo-url>
cd <backend-repo-path>
# 최신 코드 풀
git checkout main
git pull origin main# Artifact Registry 경로 설정
export PROJECT_ID=<your-project-id>
export REGION=asia-northeast3
export ARTIFACT_REGISTRY="${REGION}-docker.pkg.dev/${PROJECT_ID}/speedcam"
# 이미지 태그 설정 (버전 관리)
export IMAGE_TAG=$(date +%Y%m%d-%H%M%S) # 예: 20260208-143052
# 또는 Git 커밋 해시 사용
# export IMAGE_TAG=$(git rev-parse --short HEAD)# 1. speedcam-main 이미지 (Django API 서버)
docker build -f docker/main.Dockerfile \
-t ${ARTIFACT_REGISTRY}/speedcam-main:${IMAGE_TAG} \
-t ${ARTIFACT_REGISTRY}/speedcam-main:latest \
.
# 2. speedcam-ocr 이미지 (OCR Worker)
docker build -f docker/ocr.Dockerfile \
-t ${ARTIFACT_REGISTRY}/speedcam-ocr:${IMAGE_TAG} \
-t ${ARTIFACT_REGISTRY}/speedcam-ocr:latest \
.
# 3. speedcam-alert 이미지 (Alert Worker)
docker build -f docker/alert.Dockerfile \
-t ${ARTIFACT_REGISTRY}/speedcam-alert:${IMAGE_TAG} \
-t ${ARTIFACT_REGISTRY}/speedcam-alert:latest \
.# speedcam-main 푸시
docker push ${ARTIFACT_REGISTRY}/speedcam-main:${IMAGE_TAG}
docker push ${ARTIFACT_REGISTRY}/speedcam-main:latest
# speedcam-ocr 푸시
docker push ${ARTIFACT_REGISTRY}/speedcam-ocr:${IMAGE_TAG}
docker push ${ARTIFACT_REGISTRY}/speedcam-ocr:latest
# speedcam-alert 푸시
docker push ${ARTIFACT_REGISTRY}/speedcam-alert:${IMAGE_TAG}
docker push ${ARTIFACT_REGISTRY}/speedcam-alert:latest# 업로드된 이미지 확인
gcloud artifacts docker images list ${ARTIFACT_REGISTRY} --include-tagscd /path/to/depoly# 환경 변수 템플릿 복사
cp env/hosts.env.example env/hosts.env
cp env/backend.env.example env/backend.env
cp env/mysql.env.example env/mysql.env
cp env/rabbitmq.env.example env/rabbitmq.envnano env/hosts.env수정 내용:
# 인스턴스 내부 IP 설정 (실제 IP로 교체)
export DB_HOST=10.178.0.11
export MQ_HOST=10.178.0.12
export APP_HOST=10.178.0.13
export OCR_HOST=10.178.0.14
export ALERT_HOST=10.178.0.15
export MON_HOST=10.178.0.20
# Artifact Registry 경로 (your-project-id 교체)
export ARTIFACT_REGISTRY=asia-northeast3-docker.pkg.dev/<your-project-id>/speedcam
# RabbitMQ 비밀번호
export RABBITMQ_PASSWORD=<production-password>
# Grafana 비밀번호
export GRAFANA_PASSWORD=<grafana-admin-password>
# 도메인 설정 (선택사항 - 없으면 비워두기)
export DOMAIN=
# 도메인이 있다면: export DOMAIN=autonotify.store
export ACME_EMAIL=your-email@example.com
export TRAEFIK_AUTH_USER=admin:$$2y$$05$$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxnano env/backend.env수정 내용:
# Django
SECRET_KEY=<production-secret-key-at-least-50-chars>
DJANGO_SETTINGS_MODULE=config.settings.prod
DEBUG=False
# Database (hosts.env의 DB_HOST IP로 교체)
DB_HOST=10.178.0.11
DB_PORT=3306
DB_USER=sa
DB_PASSWORD=<production-password>
DB_NAME=speedcam
DB_NAME_VEHICLES=speedcam_vehicles
DB_NAME_DETECTIONS=speedcam_detections
DB_NAME_NOTIFICATIONS=speedcam_notifications
# RabbitMQ / Celery (hosts.env의 MQ_HOST IP로 교체)
CELERY_BROKER_URL=amqp://sa:<password>@10.178.0.12:5672//
RABBITMQ_HOST=10.178.0.12
MQTT_PORT=1883
MQTT_USER=sa
MQTT_PASS=<password>
# GCS / Firebase
GOOGLE_APPLICATION_CREDENTIALS=/app/credentials/gcp-cloud-storage.json
FIREBASE_CREDENTIALS=/app/credentials/firebase-service-account.json
# Workers
OCR_CONCURRENCY=4
ALERT_CONCURRENCY=100
OCR_MOCK=false
FCM_MOCK=false
# Gunicorn
GUNICORN_WORKERS=4
GUNICORN_THREADS=2
# Logging
LOG_LEVEL=info
# CORS (프론트엔드 도메인 또는 IP)
CORS_ALLOWED_ORIGINS=http://localhost:3000
# OpenTelemetry (hosts.env의 MON_HOST IP로 교체)
OTEL_EXPORTER_OTLP_ENDPOINT=http://10.178.0.20:4317
OTEL_EXPORTER_OTLP_PROTOCOL=grpc
OTEL_RESOURCE_ATTRIBUTES=service.namespace=speedcam,deployment.environment=prod
OTEL_TRACES_SAMPLER=parentbased_tracealways
OTEL_PYTHON_LOG_CORRELATION=truenano env/mysql.env수정 내용:
MYSQL_ROOT_PASSWORD=<production-root-password>
MYSQL_USER=sa
MYSQL_PASSWORD=<production-password>
MYSQL_DATABASE=speedcamnano env/rabbitmq.env수정 내용:
RABBITMQ_DEFAULT_USER=sa
RABBITMQ_DEFAULT_PASS=<production-password>
RABBITMQ_DEFAULT_VHOST=/# hosts.env 로드 및 설정 파일 생성
source env/hosts.env
./scripts/setup-env.sh생성되는 파일:
config/traefik/dynamic_conf.yml(도메인 모드 또는 IP 모드)config/monitoring/prometheus/prometheus.ymlconfig/monitoring/promtail/promtail-config.yml
- IAM 및 관리자 → 서비스 계정으로 이동
- 서비스 계정 생성:
speedcam-gcs-sa - 역할 부여: Storage 객체 관리자
- 키 생성 → JSON 다운로드 →
gcp-cloud-storage.json으로 저장
- 프로젝트 설정 → 서비스 계정으로 이동
- 새 비공개 키 생성 클릭
- JSON 다운로드 →
firebase-service-account.json으로 저장
# depoly 레포지토리에 credentials 디렉토리 생성
mkdir -p config/credentials
# 다운로드한 JSON 파일을 credentials 디렉토리로 이동
mv ~/Downloads/gcp-cloud-storage.json config/credentials/
mv ~/Downloads/firebase-service-account.json config/credentials/
# 권한 설정
chmod 600 config/credentials/*.json디렉토리 구조:
config/
└── credentials/
├── gcp-cloud-storage.json
└── firebase-service-account.json
# 디렉토리 생성
mkdir -p config/monitoring/mysqld-exporter
# 설정 파일 생성
nano config/monitoring/mysqld-exporter/.my.cnf파일 내용:
[client]
user=sa
password=<production-password>
host=localhost
port=3306chmod 600 config/monitoring/mysqld-exporter/.my.cnf배포 순서: DB → MQ → MON → APP → OCR → ALERT
# 배포 디렉토리 압축 (로컬에서)
cd /path/to/depoly
tar -czf speedcam-deploy.tar.gz \
compose/ \
config/ \
env/ \
scripts/
# 압축 파일 확인
ls -lh speedcam-deploy.tar.gz# 배포 파일 전송
gcloud compute scp speedcam-deploy.tar.gz speedcam-db:~/ --zone=asia-northeast3-a
# 또는 외부 IP 직접 사용
# scp speedcam-deploy.tar.gz username@34.xxx.xxx.xxx:~/# SSH 접속
gcloud compute ssh speedcam-db --zone=asia-northeast3-a인스턴스 내부 작업:
# 압축 해제
tar -xzf speedcam-deploy.tar.gz
# Artifact Registry 인증
gcloud auth configure-docker asia-northeast3-docker.pkg.dev
# 환경 변수 로드
source env/hosts.env
# Docker Compose 실행
docker compose -f compose/docker-compose.db.yml up -d
# 로그 확인
docker logs speedcam-mysql
docker logs speedcam-mysqld-exporter
docker logs speedcam-promtail
docker logs speedcam-cadvisor
# 헬스체크
docker ps# MySQL 접속 테스트
docker exec -it speedcam-mysql mysql -u sa -p
# SQL 실행 (MySQL 콘솔에서)
SHOW DATABASES;
USE speedcam;
SHOW TABLES;
EXIT;exitgcloud compute scp speedcam-deploy.tar.gz speedcam-mq:~/ --zone=asia-northeast3-agcloud compute ssh speedcam-mq --zone=asia-northeast3-a인스턴스 내부 작업:
# 압축 해제
tar -xzf speedcam-deploy.tar.gz
# Artifact Registry 인증
gcloud auth configure-docker asia-northeast3-docker.pkg.dev
# 환경 변수 로드
source env/hosts.env
# Docker Compose 실행
docker compose -f compose/docker-compose.mq.yml up -d
# 로그 확인
docker logs speedcam-rabbitmq
docker logs speedcam-promtail
docker logs speedcam-cadvisor
# 헬스체크
docker ps# 브라우저에서 접속
# http://<speedcam-mq 외부 IP>:15672
# 로그인: sa / <production-password>exitgcloud compute scp speedcam-deploy.tar.gz speedcam-mon:~/ --zone=asia-northeast3-agcloud compute ssh speedcam-mon --zone=asia-northeast3-a인스턴스 내부 작업:
# 압축 해제
tar -xzf speedcam-deploy.tar.gz
# Artifact Registry 인증
gcloud auth configure-docker asia-northeast3-docker.pkg.dev
# 환경 변수 로드
source env/hosts.env
# Docker Compose 실행
docker compose -f compose/docker-compose.mon.yml up -d
# 로그 확인
docker logs speedcam-prometheus
docker logs speedcam-grafana
docker logs speedcam-loki
docker logs speedcam-jaeger
docker logs speedcam-otel-collector
docker logs speedcam-celery-exporter
docker logs speedcam-promtail
docker logs speedcam-cadvisor
# 헬스체크
docker ps# 브라우저에서 접속
# http://<speedcam-mon 외부 IP>:3000
# 로그인: admin / <GRAFANA_PASSWORD>exitgcloud compute scp speedcam-deploy.tar.gz speedcam-app:~/ --zone=asia-northeast3-agcloud compute ssh speedcam-app --zone=asia-northeast3-a인스턴스 내부 작업:
# 압축 해제
tar -xzf speedcam-deploy.tar.gz
# Artifact Registry 인증
gcloud auth configure-docker asia-northeast3-docker.pkg.dev
# 환경 변수 로드
source env/hosts.env
# Docker Compose 실행
docker compose -f compose/docker-compose.app.yml up -d
# 로그 확인
docker logs speedcam-traefik
docker logs speedcam-main
docker logs speedcam-flower
docker logs speedcam-promtail
docker logs speedcam-cadvisor
# 헬스체크
docker ps# Django API 헬스체크
curl http://localhost:8000/health/
# Flower 접속 확인 (브라우저)
# http://<speedcam-app 외부 IP>:5555exitgcloud compute scp speedcam-deploy.tar.gz speedcam-ocr:~/ --zone=asia-northeast3-agcloud compute ssh speedcam-ocr --zone=asia-northeast3-a인스턴스 내부 작업:
# 압축 해제
tar -xzf speedcam-deploy.tar.gz
# Artifact Registry 인증
gcloud auth configure-docker asia-northeast3-docker.pkg.dev
# 환경 변수 로드
source env/hosts.env
# Docker Compose 실행
docker compose -f compose/docker-compose.ocr.yml up -d
# 로그 확인
docker logs speedcam-ocr
docker logs speedcam-promtail
docker logs speedcam-cadvisor
# 헬스체크
docker ps# Flower에서 OCR Worker 확인
# http://<speedcam-app 외부 IP>:5555
# Workers 탭에서 "ocr@<hostname>" 활성화 확인exitgcloud compute scp speedcam-deploy.tar.gz speedcam-alert:~/ --zone=asia-northeast3-agcloud compute ssh speedcam-alert --zone=asia-northeast3-a인스턴스 내부 작업:
# 압축 해제
tar -xzf speedcam-deploy.tar.gz
# Artifact Registry 인증
gcloud auth configure-docker asia-northeast3-docker.pkg.dev
# 환경 변수 로드
source env/hosts.env
# Docker Compose 실행
docker compose -f compose/docker-compose.alert.yml up -d
# 로그 확인
docker logs speedcam-alert
docker logs speedcam-promtail
docker logs speedcam-cadvisor
# 헬스체크
docker ps# Flower에서 Alert Worker 확인
# http://<speedcam-app 외부 IP>:5555
# Workers 탭에서 "alert@<hostname>" 활성화 확인exit# speedcam-db에 SSH 접속
gcloud compute ssh speedcam-db --zone=asia-northeast3-a
# MySQL 접속 테스트
docker exec -it speedcam-mysql mysql -u sa -p -e "SELECT 1;"
# 데이터베이스 확인
docker exec -it speedcam-mysql mysql -u sa -p -e "SHOW DATABASES;"
# MySQL Exporter 메트릭 확인
curl http://localhost:9104/metrics | grep mysql_up
# 출력: mysql_up 1# speedcam-mq에 SSH 접속
gcloud compute ssh speedcam-mq --zone=asia-northeast3-a
# RabbitMQ 상태 확인
docker exec speedcam-rabbitmq rabbitmq-diagnostics status
# 플러그인 확인 (MQTT, Prometheus 활성화 확인)
docker exec speedcam-rabbitmq rabbitmq-plugins list
# 웹 UI 접속
# http://<speedcam-mq 외부 IP>:15672# speedcam-app에 SSH 접속
gcloud compute ssh speedcam-app --zone=asia-northeast3-a
# API 헬스체크 엔드포인트
curl http://localhost:8000/health/
# 기대 출력: {"status": "ok"}
# Django 마이그레이션 확인
docker exec speedcam-main python manage.py showmigrations
# Django 관리자 생성 (필요시)
docker exec -it speedcam-main python manage.py createsuperuser# speedcam-app에 SSH 접속
gcloud compute ssh speedcam-app --zone=asia-northeast3-a
# Traefik 대시보드 확인
curl http://localhost:8080/api/http/routers
curl http://localhost:8080/api/http/services
# 웹 브라우저에서
# http://<speedcam-app 외부 IP>:8080/dashboard/# Flower 웹 UI 접속
# http://<speedcam-app 외부 IP>:5555
# Workers 탭 확인:
# - ocr@speedcam-ocr (4 concurrency)
# - alert@speedcam-alert (100 concurrency)# speedcam-mon에 SSH 접속
gcloud compute ssh speedcam-mon --zone=asia-northeast3-a
# Prometheus 타겟 확인
curl http://localhost:9090/api/v1/targets | jq .
# 웹 브라우저에서
# http://<speedcam-mon 외부 IP>:9090
# Status → Targets → 모든 타겟 UP 확인# 웹 브라우저에서 접속
# http://<speedcam-mon 외부 IP>:3000
# 로그인: admin / <GRAFANA_PASSWORD>
# 데이터 소스 확인:
# Configuration → Data Sources
# - Prometheus (http://localhost:9090)
# - Loki (http://localhost:3100)
# - Jaeger (http://localhost:16686)로컬에서 실행:
#!/bin/bash
# health-check.sh
INSTANCES=(
"speedcam-db:10.178.0.11"
"speedcam-mq:10.178.0.12"
"speedcam-app:10.178.0.13"
"speedcam-ocr:10.178.0.14"
"speedcam-alert:10.178.0.15"
"speedcam-mon:10.178.0.20"
)
echo "========================================="
echo " SpeedCam 전체 헬스체크"
echo "========================================="
for instance in "${INSTANCES[@]}"; do
name="${instance%%:*}"
ip="${instance##*:}"
echo ""
echo "[$name] 컨테이너 상태 확인..."
gcloud compute ssh $name --zone=asia-northeast3-a --command="docker ps --format 'table {{.Names}}\t{{.Status}}'"
done
echo ""
echo "========================================="
echo " 완료"
echo "========================================="실행:
chmod +x health-check.sh
./health-check.sh# 1. 롤백할 이미지 태그 확인
gcloud artifacts docker images list ${ARTIFACT_REGISTRY}/speedcam-main --include-tags
# 2. 인스턴스에 SSH 접속 (예: speedcam-app)
gcloud compute ssh speedcam-app --zone=asia-northeast3-a
# 3. 환경 변수 수정 (이미지 태그 변경)
nano env/hosts.env
# export ARTIFACT_REGISTRY=asia-northeast3-docker.pkg.dev/<project-id>/speedcam:20260207-120000
# 4. Docker Compose 재시작
source env/hosts.env
docker compose -f compose/docker-compose.app.yml pull
docker compose -f compose/docker-compose.app.yml up -d
# 5. 로그 확인
docker logs speedcam-main# 역순으로 롤백: ALERT → OCR → APP → MON → MQ → DB
# 각 인스턴스에서:
docker compose -f compose/docker-compose.<service>.yml down
docker compose -f compose/docker-compose.<service>.yml up -d# MySQL 백업
gcloud compute ssh speedcam-db --zone=asia-northeast3-a
docker exec speedcam-mysql mysqldump -u sa -p --all-databases > /tmp/backup-$(date +%Y%m%d).sql
# 백업 파일 다운로드
gcloud compute scp speedcam-db:/tmp/backup-*.sql ~/backups/ --zone=asia-northeast3-abackend 레포지토리와 depoly 레포지토리의 모니터링 이미지 버전이 일치해야 합니다.
# backend 레포지토리에서 확인
cd <backend-repo-path>
grep 'image:' docker/monitoring/docker-compose.yml예시 출력:
prometheus: prom/prometheus:v2.51.2
grafana: grafana/grafana:10.4.2
loki: grafana/loki:2.9.6
promtail: grafana/promtail:2.9.6
jaeger: jaegertracing/all-in-one:1.57
otel-collector: otel/opentelemetry-collector-contrib:0.98.0
cadvisor: gcr.io/cadvisor/cadvisor:v0.49.1
mysqld-exporter: prom/mysqld-exporter:v0.15.1
celery-exporter: danihodovic/celery-exporter:0.10.3# depoly 레포지토리에서 확인
cd /path/to/depoly
grep 'image:' compose/docker-compose.mon.yml
grep 'image:' compose/docker-compose.db.yml
grep 'image:' compose/docker-compose.mq.yml
grep 'image:' compose/docker-compose.app.yml
grep 'image:' compose/docker-compose.ocr.yml
grep 'image:' compose/docker-compose.alert.yml버전이 다르면 depoly 레포지토리를 backend 기준으로 업데이트:
# depoly 레포지토리에서
nano compose/docker-compose.mon.yml
# 이미지 버전을 backend와 동일하게 수정
# 변경사항 커밋
git add compose/docker-compose.mon.yml
git commit -m "chore: sync monitoring image versions with backend"
git push origin main- backend 레포지토리 최신 커밋 확인
- depoly 레포지토리 최신 커밋 확인
- 모니터링 이미지 버전 동기화 확인
- backend 이미지 빌드 및 푸시 완료
- env 파일 모두 설정 완료 (hosts.env, backend.env, mysql.env, rabbitmq.env)
- credentials 디렉토리 생성 완료 (GCS, Firebase JSON)
- MySQL Exporter .my.cnf 생성 완료
- setup-env.sh 실행 완료 (Traefik, Prometheus, Promtail 설정 생성)
- config/mysql/init.sql 확인 (최신 스키마)
증상:
speedcam-mysql exited with code 1
해결:
# 로그 확인
docker logs speedcam-mysql
# 일반적인 원인:
# 1. 비밀번호 환경 변수 누락 → env/mysql.env 확인
# 2. init.sql 문법 오류 → config/mysql/init.sql 확인
# 3. 볼륨 권한 문제 → sudo chown -R 999:999 /var/lib/docker/volumes/mysql_data증상:
MQTT 포트 1883 연결 실패
해결:
# 컨테이너 재시작
docker restart speedcam-rabbitmq
# 플러그인 수동 활성화
docker exec speedcam-rabbitmq rabbitmq-plugins enable rabbitmq_mqtt rabbitmq_prometheus
# 확인
docker exec speedcam-rabbitmq rabbitmq-plugins list증상:
Error response from daemon: unauthorized: You don't have the needed permissions
해결:
# gcloud 재인증
gcloud auth login
gcloud auth configure-docker asia-northeast3-docker.pkg.dev
# 서비스 계정 키 사용 (선택사항)
gcloud auth activate-service-account --key-file=<service-account-key.json>증상:
curl http://localhost:8000/health/
{"detail": "Internal Server Error"}
해결:
# Django 로그 확인
docker logs speedcam-main
# 일반적인 원인:
# 1. MySQL 연결 실패 → backend.env의 DB_HOST 확인
# 2. 마이그레이션 미실행 → docker exec speedcam-main python manage.py migrate
# 3. Credentials 누락 → config/credentials/*.json 확인
# 4. RabbitMQ 연결 실패 → backend.env의 CELERY_BROKER_URL 확인증상:
Prometheus 웹 UI에서 타겟이 DOWN 상태
해결:
# Prometheus 설정 확인
cat config/monitoring/prometheus/prometheus.yml
# 타겟 인스턴스에서 Exporter 상태 확인
docker ps | grep exporter
docker logs speedcam-mysqld-exporter
docker logs speedcam-cadvisor
# 네트워크 연결 확인
curl http://<타겟 IP>:9104/metrics # mysqld-exporter
curl http://<타겟 IP>:8080/metrics # cadvisor증상:
Flower에서 Worker가 보이지 않음
해결:
# Worker 로그 확인
docker logs speedcam-ocr
docker logs speedcam-alert
# 일반적인 원인:
# 1. RabbitMQ 연결 실패 → backend.env의 CELERY_BROKER_URL 확인
# 2. Worker 컨테이너 종료 → docker ps 확인
# 3. Celery 설정 오류 → docker logs에서 traceback 확인
# Worker 재시작
docker restart speedcam-ocr
docker restart speedcam-alert증상:
도메인 접속 시 "Your connection is not private" 경고
해결:
# Traefik 로그 확인
docker logs speedcam-traefik
# 일반적인 원인:
# 1. DNS A 레코드 미설정 → 도메인이 speedcam-app 외부 IP를 가리키는지 확인
# 2. 80 포트 막힘 → 방화벽 규칙 확인 (Let's Encrypt HTTP-01 Challenge)
# 3. ACME 이메일 미설정 → config/traefik/traefik.yml 확인
# 인증서 수동 재발급
docker exec speedcam-traefik rm -rf /etc/traefik/certs/*
docker restart speedcam-traefik도메인을 사용하는 경우 (예: autonotify.store):
| 서브도메인 | 타입 | 값 | 설명 |
|---|---|---|---|
| api.autonotify.store | A | speedcam-app 외부 IP | Django API |
| flower.autonotify.store | A | speedcam-app 외부 IP | Celery 모니터링 |
| grafana.autonotify.store | A | speedcam-app 외부 IP | Grafana (Traefik으로 프록시) |
| rabbitmq.autonotify.store | A | speedcam-app 외부 IP | RabbitMQ 관리 (Traefik으로 프록시) |
| traefik.autonotify.store | A | speedcam-app 외부 IP | Traefik 대시보드 |
Traefik이 모든 서브도메인을 내부 서비스로 라우팅합니다.
이 가이드를 통해 6개의 GCE 인스턴스에 SpeedCam 프로젝트를 수동으로 배포할 수 있습니다. 배포 후 반드시 헬스체크를 수행하여 모든 서비스가 정상 작동하는지 확인하세요.
다음 단계:
- CI/CD 파이프라인 구축 (GitHub Actions)
- 자동 배포 스크립트 작성
- 모니터링 대시보드 커스터마이징
- 백업 자동화 (MySQL, 설정 파일)
문의:
- Backend:
- Deploy: