1118 TIL

looggi·2022년 11월 18일
1

스파르타 내배캠 AI-3

목록 보기
70/130

💣 타임어택

  • github에서 timeattack project를 clone 해주세요
    https://github.com/sparta-course/221118_timeattack.git
  • 프로젝트를 docker와 docker-compose를 활용해 배포해주세요
  • docker-compose.yml 및 설정 등은 linux/docker 강의자료에 있는 내용을 참고하되, 아래 순서로 배포를 진행하고 각각의 결과물을 저장한 후 제출해주세요

1. django의 runserver 명령어를 사용해 배포해주세요

사용 이미지 : python:3.10.8

# python 3.10.8버전 이미지를 사용해 빌드
FROM python:3.10.8

# .pyc 파일을 생성하지 않도록 설정
ENV PYTHONDONTWRITEBYTECODE 1

# 파이썬 로그가 버퍼링 없이 즉각적으로 출력하도록 설정
ENV PYTHONUNBUFFERED 1

# /app/ 디렉토리를 생성
RUN mkdir /app/

# /app/ 경로를 작업 디렉토리로 설정
WORKDIR /app/

# requirments.txt를 작업 디렉토리(/app/) 경로로 복사
COPY ./django/requirements.txt .

# 프로젝트 실행에 필요한 패키지들을 설치
RUN pip install --no-cache-dir -r requirements.txt
  • vi docker-compose.yml
version: '3.8'

services:
  backend:
    container_name: backend
    build: ./backend/
    entrypoint: sh -c "python manage.py collectstatic --no-input && python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
    ports:
      - '80:8000'
    volumes:
      - ./backend/django/:/app/
      - /etc/localtime:/etc/localtime:ro
    restart: always
  • sudo docker compose up (-d 옵션이 없으면 foreground로 실행돼서 바로 실행화면이 나오고 -d옵션이 있으면 background(demon)로 실행돼서 sudo docker compose logs -f로 확인)
  • sudo docker compose up -d --build
    ➜ Dockerfile에서 빌드할 이미지 설정한 걸 반영해야하므로 build가 있어야함

👉 정답

hello world!!

연결된 데이터베이스 : django.db.backends.sqlite3
접속 경로 : 54.180.106.117
프로젝트 실행 명령어 : python manage.py runserver 0.0.0.0:8000

➜ db는 sqlite3, 실행은 runserver

2. postgresql을 연동한 후 배포해주세요

사용 이미지 : postgres:14.5

  • 위에서 사용했던 Dockerfile, docker-compose.yml 파일 수정
  • docker-compose.yml에 postgresql 사용을 위한 코드 추가
    ➜ volumes, services/postgres 컨테이너 추가, backend 컨테이너에 postgresql 연결을 위한 코드 추가
version: '3.8'

volumes:
  postgres: {}

services:
  postgres:
    container_name: postgres
    image: postgres:14.5
    volumes:
      - postgres:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=P@ssw0rd
      - POSTGRES_DB=django
    restart: always

  backend:
    container_name: backend
    build: ./backend/
    entrypoint: sh -c "python manage.py collectstatic --no-input && python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
    volumes:
      - ./backend/django/:/app/
      - /etc/localtime:/etc/localtime:ro
    ports:
      - '80:8000'
    environment: # django에서 사용할 설정들을 지정해줍니다.
      - DEBUG=1
      - POSTGRES_DB=django
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=P@ssw0rd
      - POSTGRES_HOST=postgres
      - POSTGRES_PORT=5432
    depends_on:
      - postgres
    restart: always
  • Dockerfile 내부에 RUN pip install psycopg2 가 추가되었으므로 sudo docker compose up -d --build
FROM python:3.10.8

ENV PYTHONDONTWRITEBYTECODE 1

ENV PYTHONUNBUFFERED 1

RUN mkdir /app/

WORKDIR /app/

COPY ./django/requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

#postgresql을 사용하기 위한 패키지를 설치합니다.
RUN pip install psycopg2

👉 정답

hello world!!

연결된 데이터베이스 : django.db.backends.postgresql
접속 경로 : 54.180.106.117
프로젝트 실행 명령어 : python manage.py runserver 0.0.0.0:8000

➜ db는 postgresql, 실행은 runserver

3. nginx를 연동한 후 배포해주세요

사용 이미지 : nginx:1.23.2

  • docker-compose.yml에 nginx 사용을 위한 코드 추가
    ➜ volumes, services/nginx 컨테이너 추가, backend 컨테이너에 nginx 연결을 위한 코드 추가
    ➜ nginx에서 포트 포워딩을 하고있기 때문에 backend/ports 80:8000 삭제
version: '3.8'

volumes:
  postgres: {}
  django_media: {}
  django_static: {}

services:
  postgres:
    container_name: postgres
    image: postgres:14.5
    volumes:
      - postgres:/var/lib/postgresql/data/
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=P@ssw0rd
      - POSTGRES_DB=django
    restart: always

  backend:
    container_name: backend
    build: ./backend/
    entrypoint: sh -c "python manage.py collectstatic --no-input && python manage.py migrate && python manage.py runserver 0.0.0.0:8000"
    volumes:
      - ./backend/django/:/app/
      - /etc/localtime:/etc/localtime:ro
      - django_media:/app/media/ # nginx에서 media를 사용할 수 있도록 volume을 지정해줍니다.
      - django_static:/app/static/ # nginx에서 static을 사용할 수 있도록 volume을 지정해줍니다.
    environment: # django에서 사용할 설정들을 지정해줍니다.
      - DEBUG=1
      - POSTGRES_DB=django
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=P@ssw0rd
      - POSTGRES_HOST=postgres
      - POSTGRES_PORT=5432
    depends_on:
      - postgres
    restart: always

  nginx:
    container_name : nginx
    image: nginx:1.23.2
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - django_media:/media/ # django의 media를 사용할 수 있도록 volume을 지정해줍니다.
      - django_static:/static/ # django의 static 사용할 수 있도록 volume을 지정해줍니다.
    depends_on:
      - backend
    restart: always
  • Dockerfile 변경사함 없음 ➜ --build 옵션 x ❓
  • nginx 폴더는 docker-compose.yml 파일과 같은 디렉토리에 있음
path : /home/ubuntu/
├── backend
│   ├── Dockerfile
│   └── django # project directory
├── docker-compose.yml
└── nginx
    └── default.conf
  • nginx/default.conf 작성
server {
  listen 80;
  server_name _; # 모든 도메인 혹은 ip로 들어오는 요청에 대해 처리해 줍니다.

  location / { # nginx로 요청이 들어왔을 때
    proxy_pass http://backend:8000/; # backend 컨테이의 8000번 포트로 전달합니다.
  }

  location /static/ { # 브라우저에서 /static/ 경로로 요청이 들어왔을 때
    alias /static/; # /static/ 경로에 있는 파일들을 보여줍니다.
  }

  location /media/ { # 브라우저에서 /media/ 경로로 요청이 들어왔을 때
    alias /media/; # /media/ 경로에 있는 파일들을 보여줍니다.
  }
}

👉 정답

hello world!!

연결된 데이터베이스 : django.db.backends.postgresql
접속 경로 : backend:8000
프로젝트 실행 명령어 : python manage.py runserver 0.0.0.0:8000

➜ 접속 경로 변경된 것 확인

❌ 오류

Error response from daemon: driver failed programming external connectivity on endpoint nginx (84fbfa6a02009fb408299cada3725cee54ef7fe6c1e634919afe22c1ea5619ed): Bind for 0.0.0.0:80 failed: port is already allocated

➜ docker-compose.vml에서 backend container의 포트포워딩 부분을 지워주면 해결됨

4. gunicorn을 사용하여 배포해주세요

👉 내 답

정말 말 그대로 gunicorn만 사용함

  • docker-compose.yml
version: '3.8'

services:
  backend:
    container_name: backend
    build: ./backend/
    # drf_project.wsgi는 프로젝트 경로에 맞게 지정해야 합니다.
    entrypoint: sh -c "python manage.py collectstatic --no-input && python manage.py migrate && gunicorn timeattack.wsgi --workers=5 -b 0.0.0.0:8000"
    ports:
      - 80:8000
    volumes:
      - ./backend/django/:/app/
      - /etc/localtime:/etc/localtime:ro # host의 timezone 설정을 컨테이너에 적용합니다.
      # ro 은 읽기 전용(read only) 속성으로 볼륨을 설정하는 것을 의미합니다.
    restart: always

👉 정답

  • Dockerfile RUN pip install unicorn 추가
  • docker-compose.yml backend/entrypoint python manage.py runserver ➜ gunicorn timeattack.wsgi --workers=5 -b 로 변경
    +Dockerfile에 변경사항이 있으므로 --build 옵션을 추가해서 컨테이너 생성

hello world!!

연결된 데이터베이스 : django.db.backends.postgresql
접속 경로 : backend:8000
프로젝트 실행 명령어 : python /usr/local/bin/gunicorn >timeattack.wsgi --workers=5 -b 0.0.0.0:8000

➜ 실행 gunicorn 으로 변경된 것 확인

🤨 Dockerfile vs docker-compose.yml

◽ Dockerfile

  • 컨테이너 생성시 이미지 설정에 사용됨
  • sudo docker compose up 에서 build 옵션 추가 여부를 결정 ❓
  • 예시
  FROM python:3.9.15

  # .pyc 파일을 생성하지 않도록 설정합니다.
   ENV PYTHONDONTWRITEBYTECODE 1

  # 파이썬 로그가 버퍼링 없이 즉각적으로 출력하도록 설정합니다.
   ENV PYTHONUNBUFFERED 1

  # /app/ 디렉토리를 생성합니다.
   RUN mkdir /app/

  # /app/ 경로를 작업 디렉토리로 설정합니다.
   WORKDIR /app/

  # main.py 파일을 /app/ 경로로 복사합니다.
   COPY ./main.py /app/

◽ docker-compose.yml

  • sudo docker compose up -d 입력시 실행됨
  • 명령어는 파일이 있는 경로에서 입력해야함⭐
  • entrypoint 설정은 .yml파일이 더 우선적으로 실행됨
  • 예시
 version: '3.8' # docker-compose.yml에 사용될 문법 버전을 정의합니다.

  services:
    example: # 서비스 이름을 지정합니다. 서비스 이름은 컨테이너끼리 통신할 때 사용됩니다.
      container_name: example # 컨테이너 이름을 지정합니다.
      image: 'httpd:latest' # 컨테이너를 생성할 때 사용될 이미지를 지정합니다.
      ports: # 포트포워딩을 설정해줍니다.
       - 80:80 # 외부에서 80 포트로 접속했을 때 컨테이너의 80 포트로 연결해줍니다.
      restart: always # 컨테이너가 종료됐을 때 다시 실행시켜 줍니다.

🤨 정리

  • 컨테이너가 생성된 후 서비스가 실행됨
    포스트 컨테이너 생성-장고컨테이너 생성-장고서비스실행-포스트서비스실행
    ➜ 포스트 서비스가 먼저 실행되어야하는데 장고서비스가 먼저 실행돼서 오류나다가 포스트 서비스가 실행되니까 장고 서비스가 정상적으로 실행되면서 서버에 연결됨

  • sudo docker system prune
    ➜ remove all stopped containers, not used networks, dangling images, dangling build cache

  • runserver 0.0.0:8000 장고가 8000번 포트로 열린단 뜻

❓ 물음표

❓dockerfile이랑 docker-compose.yml 위치가 같으면 안되나? 그냥 설정해줄때만 경로 잘 입력해주면 상관없음? 왔다갔다하기 너무귀찮음 근데 파일 위치도 암묵적으로 컨벤션이 있을 것 같긴함... 으ㅡ... ❌
➜ 딱히 컨벤션이 있는 건 아님 둘 다 경로만 잘 입력해주면 어디에 있든 상관없음!
딴사람 깃허브에 기웃기웃하면서 구조를 좀 찾아보고 참고해서 써보고 맞는 걸 찾으면 됨

❓최초로 dockerfile작성시 build옵션을 따로 주지 않아도 빌드 되는거 맞지? ⭕
해당경로의 도커파일(도커컴포즈 파일에 입력되어있는 도커파일 경로)로 이미지가 빌드된 적이 있는지 없는지

❓도커파일 수정여부에 따라서 -이미지가 바뀌니까- 빌드옵션 추가여부가 달라지는 거 맞아? ⭕
➜ 도커파일 수정사항 반영하려면 --build해야함/ 추가로 도커파일에서 수정사항들 빼고 원래 있던 부분들은 이미 빌드한 적이 있다면 캐시로 남아있어서 수정된 부분만 새로 실행됨
➜ docker-compose.yml/backend/build에 build: ./backend/ 요렇게 도커파일 위치가 적혀있음 그걸로 이미지를 빌드하라구!!!!!!!!!!!!!!
❓nginx연동할 때 backend에서 포트포워딩 설정을 해줄필요가 없는건지 하면 안되는건지? 나는 그거지워서 오류해결했는뎅 ⭕
➜ 똑같은 포트로 설정하면 에러남
backend는 80:8000 / nginx는 80:80
앞에 부분(80)이 똑같으면 안됨
똑같은 포트로 들어왔을 때 서로 다른 쪽으로 가라고(포워딩) 하는 거라 애가 힘들다

profile
looooggi

0개의 댓글