Networks/aws

SK networks AI Camp - AWS & Docker 연결

코딩하는 Español되기 2024. 8. 14. 18:30

AWS Instance 생성

2024.08.13 - [Networks/aws] - SK networks AI Camp - VS Code 연동 및 Elastic IP 설정

 

SK networks AI Camp - VS Code 연동 및 Elastic IP 설정

1. VS extensions Dev Container 설치2. 왼쪽 아래에 remote window 클릭 -> connect host설치한 host로 누르기 But 연결 안 됨(이전에 Instance를 삭제하였기 때문)3. Instacne를 새로 만들어주기2024.08.12 - [Networks/aws] - SK n

joowon582.tistory.com


1. Docker File 생성 후 코드 복사 붙여 넣기

FROM python:3.12 AS python-build
RUN pip install mysqlclient

FROM python:3.12-slim
COPY --from=python-build /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
RUN apt-get update && apt-get install -y libmariadb3 nginx

# 파이썬 모듈 설치 
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

# Nginx
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf

# Django server
RUN mkdir /app
COPY . /app
WORKDIR /app

# 환경변수 적용 
ENV SECRET_KEY '본인 시크릿 키 사용' # 시크릿 키 : config/settings.py

COPY run.sh .
RUN chmod +x run.sh
CMD ["./run.sh"]

 

2. SECRET_KEY 설정

    ○ config/settings 에 SECRET_KEY를 Docker에 붙여 넣기

    ○ SECRET_KEY를 아래와 같이 수정

    ○ DEBUG = False로 변경

    ○ ALLOWED_HOSTS = ['*']로 수정

SECRET_KEY = os.getenv("SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False

ALLOWED_HOSTS = ['*']

 

3. STATIC_URL을 nginx로 보내기

    ○ STATIC_ROOT = "/static/" 추가하기

STATIC_ROOT = "/static/"
STATIC_URL = "static/"
STATIC_PATH = os.path.join(
    BASE_DIR, "static"
)  # concatena a pasta static a variavel instanciada base_dir que aponta para a raiz do projeto

STATICFILES_DIRS = (STATIC_PATH,)

 

4. nginx 폴더 생성

    ○ nginx/default.conf 파일 생성 및 코드 복붙

server {
    listen 80;
    server_name 0.0.0.0;

    root /app/static;

    location /static/ {
        alias /app/static/;
    }

    location / {
        proxy_set_header Host $host;
        proxy_pass http://0.0.0.0:8000;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }

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

}

5. requirements.txt 파일 자동 생성하기

    ○ 터미널

    ○ pip freeze : 설치된 모듈 확인(gunicorn, mysqlclient, django 존재해야 함)

    ○ pip freeze > requirements.txt : 업데이트하기

 

6. run.sh 파일 생성

    ○ 코드 복붙

#!/bin/sh

python manage.py makemigrations
python manage.py migrate --no-input
python manage.py collectstatic --no-input

gunicorn config.wsgi:application --bind 0.0.0.0:8000 &

unlink /etc/nginx/sites-enabled/default
nginx -g 'daemon off;'

7. Docker Image 연결

docker build --platform linux/amd64 -t 아이디/이미지명 .
docker images

8. nginx로 열기

docker run --name django-container -d -p 80:80 joowon582/django-image
# 확인
docker ps

 

9. 접속하기

    ○ 웹에서 localhost 쳐서 들어가기

10. 삭제

docker rm -f django-container
docker ps
docker login

11. Image 업로드

docker push 아이디/이미지명

 


Docker와 연결

1. 코드 입력으로 설치

sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common -y curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update

sudo apt-get install docker-ce docker-ce-cli containerd.io -y
sudo systemctl status docker

2. 권한 변경

sudo chmod 666 /var/run/docker.sock
docker ps

3. 불러오기 & rngus 

docker search 아이디
# 확인
django image
# 구현
docker run --name aws-django -d -p 80:80 아이디/django-image

Git에 연동

1.. gitignore 파일 생성

    ○. venv
    ○ __pycache__

2. git에 commit

    ○ commit 시 : init - django web server

    ○ README 추가

3. AWS 웹에서 ECR 검색

    ○ Elastic Container Service → Private registry → Repositories로 이동

    ○ 만들어진 이미지를 해당 image 명으로 설정한 곳으로 이동하기에 기억하기(django-web-service-ecr)

    ○ 바로 Create

4. Build 하기

    ○ CodeBuild 클릭

 

    ○ VS Code에서 buildspec.yml 파일 생성 및 코드 입력

        ● IMAGE_REPO_NAME : 이전에 입력한 이름 입력

        ● ESC_CONTAINER_NAME : 컨테이너 이름 설정해 주기

        ● env : 환경변수

           - variables: 아래가 변수 순서대로 컨테이너, 레파지토리, 태그, 지역

 

      ● phases : 실행 코드

            - pre_build : 빌드 전 작업(로그인, ID/PW 가져오기)

 

            - build : 빌드 작업

 

            - post_build : 빌드 후 작업(Push, 데이터를 넘겨주기)

 

        ● artifacts : 결과물(컨테이너 ID , IMAGE url가 있는 JSON)

version: 0.2
env:
  git-credential-helper: yes
  variables:
    # docker 파라미터 정의
    ECS_CONTAINER_NAME: AWS ECS CONTAINER NAME # aws ecs에 등록이 되어 있는 container name
    IMAGE_REPO_NAME: AWS ECR NAME # aws ecr에 등록이 되어 있는 name
    IMAGE_TAG: latest
    AWS_DEFAULT_REGION: ap-northeast-2

phases:
  pre_build:
    commands:
      # Docker push를 할 ECR에 로그인 필요
      # https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html
      # https://stackoverflow.com/questions/77488134/codebuild-error-exit-status-127-file-name-too-long
      - echo Logging in to Amazon ECR...
      - aws --version
      - ECR_PASSWORD=$(aws ecr get-login-password --region $AWS_DEFAULT_REGION)
      - AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
      - echo -n ${ECR_PASSWORD} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com
      - REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG


  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      # Github Repository에 있는 Dockerfile의 위치에 맞춰 수정 
      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $REPOSITORY_URI

  post_build:
    commands:
      - echo package Source...
      - echo push the Docker image...
      - docker push $REPOSITORY_URI

      # Give your container name
      - printf '[{"name":"%s","imageUri":"%s"}]' $ECS_CONTAINER_NAME $REPOSITORY_URI > imagedefinitions.json
      - echo $ECS_CONTAINER_NAME
      - echo printing imagedefinitions.json
      - cat imagedefinitions.json

artifacts:
  files:
    - imagedefinitions.json

5. Github에 올리기(Source Control에서 사용)

 

6. Git과 연동해 주기(aws)

    ○ 아래 툴바에서 Connections 클릭

    ○ Github 누르고 이름 원하는 것 입력 후 Install a new app 하기

    ○ All Repository 선택 → PW 입력 → Github Apps에 키 생성됨 → Connect

    Github의 소스를 가져올 수 있도록 연동한 것

7. Code Build Project 생성

    ○ 이름 설정 → Source 선택(github) → Repository 선택

    ○ Environment → Role name 설정

    ○ Use a Buildspec 선택 → 아까 VSCode에서 생성했던 파일 이름 그대로

    ○ Create Build Project

    ○ ECR에 접근할 수 있는 권한이 없음(Push를 못함) 그래서 접근 권한을 추가해줘야 함

8. 권한 부여하기

    ○ IAM → Roles → 아까 생성한 Build Project 이름 검색 → Attach policies → EC2 ContainerRegistry 검색 

    ○ 3개 중 EC2 ContainerRegistryPowerUser만 추가(로그인, 업로드 권한이 부여됨)

    ○ add Permissions 클릭

 

9. Build 하기(Build → Start now) 

 

10. 결과 확인(빌드 결과를 적용한 것일 뿐;ECR → Repositories → 이미지 생성된 것을 확인)


 

Amazon Elastic Container Service : 도커 컨테이너를 이용해서 서비스를 띄우는 녀석(멋진 녀석)

1. ECS 접속 → Cluster 생성하기 클릭

2. 이름, Infrastructure(Fargate 서비스 사용) & Create

    ○ Clusters는 이름이 겹치니 오류가 발생함. 그래서 이름 다르게 해 주니 해결

3. Task definitions 이동

    ○ Create new task definition → 이름/Farget 선택

    ○ Container Name : VSCode에 있는 buildspec.yml의 ECS_CONTAINER_NAME

    ○ Image URI : ECR의 아까 생성했던 Repository의 URI

4. ECS → Clusters → 아래 Service 생성

    ○ Environment : Lanch type

    ○ 아까 생성한 task 선택(Task : 스펙, 이미지 컨테이너가 들어있음)

    ○ 즉 task를 선택 =  task 스펙의 컴퓨터로 컨테이너를 띄운다는 의미

    ○ 이름 설정 & Replica : 서비스에 컨테이너(컴퓨터) N개를 한 번에 만들 수 있음

    ○ 생성&Refresh = 배포가 완료된 것 = Django Service를 접속해서 볼 수 있는 것

5. 접속하기

    ○ Task에 Public IP를 복붙

    ○ Security group → Inbound Roles에서 80 포트 모두 추가


삭제하기(Cluster, Task, Service, namespace, RDS, Snapshots(있는 경우) 삭제)

1. Cluster → Tasks Stop → Service Delete(한 번 더하면 강제 종료됨)

2. Cluster 삭제

3. Task Deregister (* 중요 : 한 후 Inactive 상태로 들어가서 안에 있는 것도 삭제해야 함)

4. namespaces로 이동 → 링크로 이동 후 삭제

5. RDS 삭제(현재는 DB 연결을 안해서 안해도 된 것; 없음)

6. ECR 삭제

7. CodeBuild 삭제

8. Build history 삭제

9. Settings에 Connections 삭제