๋น ๋ฅด๊ฒ ๋ฐฐํฌํ๊ณ ๋น ๋ฅด๊ฒ ์์ํ ์ ์๋ ํ๋ก์ ํธ
Production ๋ฐฐํฌ์ ๊ด๋ จ๋ ํ์ผ์ ๋ฐฐ์นํด ๋๋ ํด๋์ด๋ค.
- gunicorn
- nginx
- docker
- docker-compose
- ecs-config
ํ ์คํธ ๋ฐ Django ์คํ๊ณผ ๊ด๋ จ๋ ํ์ผ์ ๋ฐฐ์นํด ๋๋ ํด๋์ด๋ค.
- pipenv
- pytest
- flake8
- pylint
- isort
Django APP ์ ์คํํ๋๋ฐ ํ์ํ ์ฑ๊ณผ ์ค์ ์ ๋ ํด๋์ด๋ค.
- django-secrets
- Django Secret ์ค์๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- Secret์ ๋ก์ปฌ์์ ๊ด๋ฆฌํ ํ์๊ฐ ์ ํ ์๋ค!
- Custom User Model
- S3
- Sentry
- pytest
- flake8
- pylint
- isort
- black
์๋ ๋ด์ฉ์ ๋ชจ๋ ์ฑ์ฐ๊ณ ์ผ๋ฐ ํ
์คํธ
๋ก ๋ถ์ฌ๋ฃ์ด ์ฌ์ฉํ๋ค.
{
"django-base": {
"base": {},
"dev": {
"DJANGO_SECRET_KEY": "<CUSTOM_SECRET>"
},
"production": {
"DJANGO_SECRET_KEY": "<CUSTOM_SECRET>",
"ALLOWED_HOSTS": [
"*"
],
"DATABASE_ENGINE": "<DATABASE_ENGINE>",
"DATABASE_URL": "<DATABASE_URL>",
"DATABASE_NAME": "<DATABASE_NAME>",
"DATABASE_USER": "<DATABASE_USER>",
"DATABASE_PASSWORD": "<DATABASE_PASSWORD>",
"DATABASE_PORT": "<DATABASE_PORT>",
"DJANGO_AWS_ACCESS_KEY_ID": "<DJANGO_AWS_ACCESS_KEY_ID>",
"DJANGO_AWS_SECRET_ACCESS_KEY": "<DJANGO_AWS_SECRET_ACCESS_KEY>",
"DJANGO_AWS_STORAGE_BUCKET_NAME": "<DJANGO_AWS_STORAGE_BUCKET_NAME>",
"SENTRY_DSN": "<SENTRY_DSN>"
}
}
}
1-4-1. Secrets์ ์ฌ์ฉํ๊ธฐ ์ํ ์ฌ์ฉ์
์ฌ์ฉ์๋ฅผ ๋ง๋ค ๋ SecretsManagerReadWrite
๊ถํ์ ์ฃผ๊ณ ๋ง๋ ๋ค.
[<SECRET_MANAGER_NAME>]
aws_access_key_id=<SECRET_MANAGER_ACCESS_KEY>
aws_secret_access_key=<SECRET_MANAGER_SECRET_ACCESS_KEY>
1-4-2. S3๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ์ฌ์ฉ์
์ฌ์ฉ์๋ฅผ ๋ง๋ค ๋ AmazonS3FullAccess
๊ถํ์ ์ฃผ๊ณ ๋ง๋ ๋ค.
์ฌ๊ธฐ์ ๋์จ KEY๋ค์ Secrets-Manager์ ์ฑ์ ๋ฃ๋๋ค.
- django-secrets-manager ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด Secret name๊ณผ
.aws/credentials
์ ๋ฑ๋กํ profile label์ ๋ฑ๋กํด์ฃผ์ด์ผํ๋ค.
# ENVIRON
# ------------------------------------------------------------------------------
# https://github.com/LeeHanYeong/django-aws-secrets-manager
AWS_SECRETS_MANAGER_SECRETS_NAME = "<SECRET_MANAGER_NAME>"
AWS_SECRETS_MANAGER_PROFILE = "<SECRET_MANAGER_CREDENTIALS_PROFILE>"
- django-secrets-manager์์ ์ฌ์ฉํ Environment๋ฅผ ์ค์ ํด์ค๋ค. (ํ์ฌ ํ๋ก์ ํธ์์๋ dev, production์ ์ฌ์ฉํจ)
# ENVIRON
# ------------------------------------------------------------------------------
# https://github.com/LeeHanYeong/django-aws-secrets-manager
AWS_SECRETS_MANAGER_SECRETS_SECTION = "<SECRETS_DEV_SECTION>"
- Sample
AWS_SECRETS_MANAGER_SECRETS_SECTION = "django-base:dev"
- django-secrets-manager์์ ์ฌ์ฉํ Environment๋ฅผ ์ค์ ํด์ค๋ค. (ํ์ฌ ํ๋ก์ ํธ์์๋ dev, production์ ์ฌ์ฉํจ)
# ENVIRON
# ------------------------------------------------------------------------------
# https://github.com/LeeHanYeong/django-aws-secrets-manager
AWS_SECRETS_MANAGER_SECRETS_SECTION = "<SECRETS_PRODUCTION_SECTION>"
- Sample
AWS_SECRETS_MANAGER_SECRETS_SECTION = "django-base:production"
์ฌ๊ธฐ๊น์ง ์์ผ๋ฉด Django๊ฐ ์คํ๋๋์ง ํ์ธํด๋ณด๊ธฐ์ํด sources/
๋ก ์ด๋ํด์ ์ฝ๋๊ฐ ์ ๋์ํ๋์ง tox๋ฅผ ์คํํด๋ณธ๋ค.
์ด๋ฒ์๋ sources/app
์ผ๋ก ๋ค์ด์์ ./manage.py runserver
๋ฅผ ์คํํด๋ณธ๋ค.
์ด๋ฒ์๋ ์๋ ๋ช
๋ น์ผ๋ก production ํ๊ฒฝ์ผ๋ก ๋ฐ๊ฟ์ค ํ ./manage.py runserver
๋ฅผ ์คํํด๋ณธ๋ค.
export DJANGO_SETTINGS_MODULE=config.settings.production
Dockerfile,
nginx/Dockerfile` ๋ ํ์ผ์ build ๋ฐ Push ํ ์๋ ๋ด์ฉ์ ์์ฑํ๋ค.
services:
...
nginx:
...
image: <niginx/Dockerfile์ ๋ณธ์ธ์ด ์ฌ์ฉํ DockerImage์ ์ด๋ฆ์ ์ ๋๋ค.>
web:
...
image: <๋ณธ์ธ์ด ์ฌ์ฉํ DockerImage์ ์ด๋ฆ์ ์ ๋๋ค.>
services:
...
nginx:
...
logging:
...
options:
awslogs-group: <web๊ณผ ๊ฐ์ ๊ทธ๋ฃน์ ์ง์ ํ๊ฑฐ๋ ์์ ๋กญ๊ฒ ์ง์ ํด๋ ์ข๋ค.>
...
awslogs-stream-prefix: <๋ณธ์ธ์ด nginx๋ฅผ ์์์ฐจ๋ฆด ์ ์์๋งํ Prefix๋ฅผ ์ง์ ํ๋ค.>
web:
...
logging:
...
options:
awslogs-group: <nginx์ ๊ฐ์ ๊ทธ๋ฃน์ ์ง์ ํ๊ฑฐ๋ ์์ ๋กญ๊ฒ ์ง์ ํด๋ ์ข๋ค.>
...
awslogs-stream-prefix: <๋ณธ์ธ์ด web์์ ์์์ฐจ๋ฆด ์ ์์๋งํ Prefix๋ฅผ ์ง์ ํ๋ค.>
nginx, gunicorn์ด ์ค์ ๋์ด ์์ง ์๊ณ ์ง์ Docker์ ๋ค์ด๊ฐ์ runserver๋ก ํ์ธํ ์ ์๋ค.
docker run -it -v $HOME/.aws/credentials:/root/.aws/credentials <DOCKER_FILE_NAME> /bin/bash
์ค์ ์๋น์คํ๊ฒฝ๊ณผ ๋์ผํ๊ฒ ์คํํ ์ ์๋ค.
docker-compose up
docker-compose.prod.yml ์ aws logging ์ค์ ์ ๋ถ์ฌ์ ์คํํด์ค ์ ์๋ค.
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up
- ecsTaskExecutionRole ์์ฑ
- arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy ์ Attach
# ํด๋ฌ์คํฐ ์์ฑ
ecs-cli configure --cluster <Cluster ์ด๋ฆ> --default-launch-type EC2 --region ap-northeast-2
- IAMFullAccess
- AmazonECS_FullAccess
- AmazonSSMFullAccess
# ๋ฐฐํฌ!
ecs-cli compose --file docker-compose.yml --file docker-compose.prod.yml --project-name <Task ์ด๋ฆ> up
- ๋ฐฐํฌ ์ต์ข ๋ชฉ์ ์ง์ ๋๋ฌํ๋ค. ๋ธ๋ก๊ทธ ํฌ์คํ ํ์