Skip to content

Commit

Permalink
feat: Apply deploy setting
Browse files Browse the repository at this point in the history
  • Loading branch information
Aqudi committed Dec 14, 2020
1 parent fadcddb commit cbf570e
Show file tree
Hide file tree
Showing 19 changed files with 383 additions and 69 deletions.
128 changes: 128 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,131 @@ mypy .
```

## Build & Deploy

### 사전 준비물

- AWS CLI2 설치
```shell
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
```
- ECS-CLI 설치
```shell
sudo curl -Lo /usr/local/bin/ecs-cli https://amazon-ecs-cli.s3.amazonaws.com/ecs-cli-linux-amd64-latest
sudo chmod +x /usr/local/bin/ecs-cli
```
- IAM 계정 생성 및 정책 연결
![IAM_정책](./docs/IAM_정책.png)

### ECS-CLI로 클러스터 생성

- 생성 후 만들어진 VPC, Subnets을 저장해둬야 합니다.
- key-pair를 먼저 생성하고 key-pair이름을 저장해둡니다.

```shell
# 환경변수 설정
AWS_DEFAULT_REGION=ap-northeast-2
CLUSTER_NAME=algo-cluster
CONFIG_NAME=algo-config
PROFILE_NAME=algo-profile
INSTANCE_SIZE=3

KEY_PAIR=algo-keypair

# 클러스터 및 프로필 설정
ecs-cli configure --cluster $CLUSTER_NAME --region $AWS_DEFAULT_REGION --default-launch-type EC2 --config-name $CONFIG_NAME
ecs-cli configure profile --access-key $AWS_ACCESS_KEY_ID --secret-key $AWS_SECRET_ACCESS_KEY --profile-name $PROFILE_NAME
ecs-cli configure profile default --profile-name $PROFILE_NAME

# user-data 생성 (ecs-cluster에 연결하는 역할)
echo "#!/bin/bash \necho ECS_CLUSTER=jts-cluster >> /etc/ecs/ecs.config" > user_data.sh

# 클러스터 생성
ecs-cli up \
--capability-iam \
--keypair $KEY_PAIR \
--size $INSTANCE_SIZE \
--launch-type EC2 \
--extra-user-data ./aws/user_data.sh
```

### Security Group 생성 및 80포트 오픈

```shell
VPC_ID=<Your VPC ID Here>
SG_NAME=algo-sg

# Security group 생성 및 GROUP_ID 저장
SG_GROUP_ID=$(aws ec2 create-security-group \
--group-name "$SG_NAME" \
--description "Security Group for ECS $CLUSTER_NAME" \
--vpc-id $VPC_ID |
jq -r ".GroupId")

aws ec2 authorize-security-group-ingress \
--group-id $SG_GROUP_ID \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0
```

### ECR 로그인 및 레포지토리 생성

```shell
# ECR 레포지토리 생성
aws ecr create-repository --repository-name django |
jq ".repository | .repositoryUri"

aws ecr create-repository --repository-name nginx |
jq ".repository | .repositoryUri"
```

### ECR 저장소 이미지 배포

```shell
# ECR, Docker 로그인
aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $(aws sts get-caller-identity --query Account --output text).dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/

docker-compose -f staging.yml -f production.yml build
docker-compose -f staging.yml -f production.yml push django nginx
```

### ECS Task IAM role 생성

```shell
# 빈 iam role 생성
aws iam create-role --role-name ecs-instance --assume-role-policy-document file://aws/assume-role.json

# 필요한 정책 추가
aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role --role-name ecs-instance

# 인스턴스 프로필 생성
aws iam create-instance-profile --instance-profile-name ecs-instance-profile

# 해당 프로필에 롤 추가
aws iam add-role-to-instance-profile --instance-profile-name ecs-instance-profile --role-name ecs-instance

# instasnce profiles 출력
aws iam list-instance-profiles
```

### 서비스 생성

```shell
CONFIG_NAME=algo-config
PROJECT_NAME=algo-service

ecs-cli compose \
--project-name $PROJECT_NAME \
--file staging.yml \
--file production.yml \
--ecs-params ./aws/ecs-params.yml \
service up \
--create-log-groups \
--cluster-config $CONFIG_NAME \
--container-name nginx \
--container-port 80 \
--target-group-arn arn:aws:elasticloadbalancing:ap-northeast-2:648240308375:targetgroup/ecs-algo-c-dasdf/45984f4d255050ad \
--launch-type EC2
```
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def update_site_forward(apps, schema_editor):
Site.objects.update_or_create(
id=settings.SITE_ID,
defaults={
"domain": "algosports.com",
"domain": "api.asports.kr",
"name": "algo_sports",
},
)
Expand Down
3 changes: 3 additions & 0 deletions algo_sports/games/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet

from algo_sports.games.filters import GameMatchFilter
from algo_sports.utils.permissions import IsAdminOrReadOnly

from .models import GameInfo, GameMatch, GameRoom, GameVersion, GameVersionType
Expand Down Expand Up @@ -176,6 +177,8 @@ class GameMatchViewSet(

action_serializer_classes = {}

filterset_class = GameMatchFilter

def get_queryset(self):
gamematche_ids = self.request.user.usercodes.values_list(
"gamematches", flat=True
Expand Down
12 changes: 12 additions & 0 deletions aws/assume-role.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
],
"Version": "2012-10-17"
}
14 changes: 14 additions & 0 deletions aws/ecs-params.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: 1
task_definition:
task_execution_role: ecs-instance
task_size:
mem_limit: 512
cpu_limit: 256
run_params:
network_configuration:
awsvpc_configuration:
subnets:
- "subnet-0a00bab6d3dec1b98"
- "subnet-024304174c7677aa4"
security_groups:
- "sg-02883320b4d5e11a9"
2 changes: 2 additions & 0 deletions aws/user_data.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#/bin/bash date -d
echo ECS_CLUSTER=jts-cluster >> /etc/ecs/ecs.config
12 changes: 12 additions & 0 deletions compose/production/nginx/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM nginx:1.19.5-alpine

RUN rm /etc/nginx/conf.d/default.conf

COPY nginx.conf /etc/nginx/nginx.conf
COPY server.conf /etc/nginx/conf.d

RUN mkdir /data \
&& mkdir /data/nginx \
&& mkdir /data/nginx/temp \
&& mkdir /data/nginx/cache
EXPOSE 80
44 changes: 44 additions & 0 deletions compose/production/nginx/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
user nginx;
worker_processes 2;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

# gzip 설정
gzip on;
gzip_proxied any;
gzip_types text/plain application/json;
gzip_min_length 1000;

# 용량이 큰 파일을 업로드 가능하도록 설정
client_max_body_size 10M;

server_tokens off;
fastcgi_hide_header X-Powered-By;
fastcgi_hide_header X-Pingback;
fastcgi_hide_header Link;
proxy_hide_header X-Powered-By;
proxy_hide_header X-Pingback;
proxy_hide_header X-Link;

# 캐시 저장소
proxy_cache_path /data/nginx/cache keys_zone=one:10m;

# 임시 파일 저장소
proxy_temp_path /data/nginx/temp;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;

sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
61 changes: 61 additions & 0 deletions compose/production/nginx/server.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
upstream algoweb {
ip_hash;
server django:5000;
}

server {
listen 80;
server_name api.asports.kr;

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

# .py 나 .log 파일들에 접근을 차단
location ~ /\. {
deny all;
}
location ~* ^.+\.(py|log)$ {
deny all;
}

set $bucket "algo-sports-bucket.s3.amazonaws.com";

# static 설정
location /static/ {
try_files $uri @s3;
# http://$bucket/static/;
}

# media 설정
location /media/ {
try_files $uri @s3;
# proxy_pass http://$bucket/media/;
}

location @s3 {
set $url_full '$1';

proxy_http_version 1.1;
proxy_set_header Host $bucket;
proxy_set_header Authorization '';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-server-side-encryption;
proxy_hide_header x-amz-server-side-encryption;
proxy_hide_header Set-Cookie;
proxy_ignore_headers Set-Cookie;
proxy_intercept_errors on;

resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 10s;
proxy_pass http://$bucket$url_full;
}

location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_pass http://algoweb;
}
}
12 changes: 6 additions & 6 deletions compose/production/traefik/traefik.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ certificatesResolvers:
storage: /etc/traefik/acme/acme.json
# https://docs.traefik.io/master/https/acme/#httpchallenge
httpChallenge:
entryPoint: web
entryPoint: web-secure

http:
routers:
web-router:
rule: "Host(`algosports.com`) || Host(`www.algosports.com`)"
rule: "Host(`asports.kr`) || Host(`www.asports.kr`)"

entryPoints:
- web
middlewares:
Expand All @@ -36,8 +36,8 @@ http:
service: django

web-secure-router:
rule: "Host(`algosports.com`) || Host(`www.algosports.com`)"
rule: "Host(`asports.kr`) || Host(`www.asports.kr`)"

entryPoints:
- web-secure
middlewares:
Expand All @@ -48,7 +48,7 @@ http:
certResolver: letsencrypt

flower-secure-router:
rule: "Host(`algosports.com`)"
rule: "Host(`asports.kr`)"
entryPoints:
- flower
service: flower
Expand Down
25 changes: 25 additions & 0 deletions config/settings/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,28 @@
"from algo_sports.games.tests.factories import *",
"from algo_sports.users.tests.factories import *",
]

# CORS
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True

CORS_ALLOW_METHODS = (
"DELETE",
"GET",
"OPTIONS",
"PATCH",
"POST",
"PUT",
)

CORS_ALLOW_HEADERS = (
"accept",
"accept-encoding",
"authorization",
"content-type",
"dnt",
"origin",
"user-agent",
"x-csrftoken",
"x-requested-with",
)
Loading

0 comments on commit cbf570e

Please sign in to comment.