- 공유 링크 만들기
- X
- 이메일
- 기타 앱
- 공유 링크 만들기
- X
- 이메일
- 기타 앱
GitHub Actions로 Django + Docker 배포 자동화하기
안녕하세요! 오늘은 GitHub Actions를 사용하여 Django 애플리케이션을 Docker 컨테이너로 자동 배포하는 방법에 대해 알아보겠습니다.
1. 프로젝트 구조
project/
├── .github/
│ └── workflows/
│ └── deploy.yml
├── app/
│ ├── Dockerfile
│ ├── requirements.txt
│ └── manage.py
├── docker-compose.yml
└── .env.example
2. Docker 설정
2.1 Dockerfile
# Python 3.9 기반 이미지 사용
FROM python:3.9-slim
# 작업 디렉토리 설정
WORKDIR /app
# 시스템 패키지 설치
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*
# Python 의존성 설치
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 애플리케이션 코드 복사
COPY . .
# 환경 변수 설정
ENV PYTHONUNBUFFERED=1
ENV DJANGO_SETTINGS_MODULE=project.settings.production
# Gunicorn 실행
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "project.wsgi:application"]
2.2 docker-compose.yml
version: '3.8'
services:
web:
build: .
command: gunicorn project.wsgi:application --bind 0.0.0.0:8000
volumes:
- .:/app
env_file:
- .env
depends_on:
- db
ports:
- "8000:8000"
db:
image: postgres:13
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
volumes:
postgres_data:
3. GitHub Actions 워크플로우 설정
3.1 기본 워크플로우
# .github/workflows/deploy.yml
name: Deploy Django App
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
env:
DOCKER_IMAGE: your-docker-image
AWS_REGION: ap-northeast-2
ECR_REPOSITORY: your-repository
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:13
env:
POSTGRES_DB: test_db
POSTGRES_USER: test_user
POSTGRES_PASSWORD: test_password
ports:
- 5432:5432
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
env:
DATABASE_URL: postgres://test_user:test_password@localhost:5432/test_db
run: |
python manage.py test
build-and-push:
needs: test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Amazon ECR
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
docker tag $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG $ECR_REGISTRY/$ECR_REPOSITORY:latest
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
deploy:
needs: build-and-push
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Update ECS service
run: |
aws ecs update-service --cluster your-cluster --service your-service --force-new-deployment
4. 환경 변수 설정
4.1 .env.example
# Django 설정
DEBUG=False
SECRET_KEY=your-secret-key
ALLOWED_HOSTS=your-domain.com
# 데이터베이스 설정
POSTGRES_DB=yourdb
POSTGRES_USER=youruser
POSTGRES_PASSWORD=yourpassword
DATABASE_URL=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
# AWS 설정
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_STORAGE_BUCKET_NAME=your-bucket
5. 보안 설정
5.1 GitHub Secrets 설정
# GitHub 저장소의 Settings > Secrets에서 설정
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
DJANGO_SECRET_KEY=your-secret-key
5.2 IAM 역할 설정
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ecs:UpdateService",
"ecs:DescribeServices"
],
"Resource": "arn:aws:ecs:region:account-id:service/your-cluster/your-service"
}
]
}
6. 배포 후 작업
6.1 데이터베이스 마이그레이션
# deploy.yml에 추가
- name: Run database migrations
run: |
aws ecs run-task \
--cluster your-cluster \
--task-definition your-task-definition \
--network-configuration "awsvpcConfiguration={subnets=[subnet-12345678],securityGroups=[sg-12345678]}" \
--overrides '{"containerOverrides":[{"name":"web","command":["python","manage.py","migrate"]}]}'
6.2 정적 파일 수집
# deploy.yml에 추가
- name: Collect static files
run: |
aws ecs run-task \
--cluster your-cluster \
--task-definition your-task-definition \
--network-configuration "awsvpcConfiguration={subnets=[subnet-12345678],securityGroups=[sg-12345678]}" \
--overrides '{"containerOverrides":[{"name":"web","command":["python","manage.py","collectstatic","--noinput"]}]}'
7. 모니터링 및 알림
7.1 배포 상태 알림
# deploy.yml에 추가
- name: Notify deployment status
if: always()
run: |
if [ ${{ job.status }} == 'success' ]; then
echo "Deployment successful"
else
echo "Deployment failed"
fi
7.2 로그 확인
# deploy.yml에 추가
- name: Check deployment logs
run: |
aws logs get-log-events \
--log-group-name /ecs/your-service \
--log-stream-name ecs/your-service/$(aws ecs describe-services --cluster your-cluster --services your-service --query 'services[0].deployments[0].id' --output text)
결론
GitHub Actions를 사용하여 Django 애플리케이션을 Docker 컨테이너로 자동 배포하는 방법을 알아보았습니다. 이 설정을 통해 지속적인 통합과 배포를 자동화할 수 있습니다. 추가적인 질문이나 궁금한 점이 있으시면 댓글로 남겨주세요!
- 공유 링크 만들기
- X
- 이메일
- 기타 앱
댓글
댓글 쓰기