Docker

ian·2023년 6월 23일
3

Docker

도커는 컨테이너 기반의 오픈소스 가상화 플랫폼입니다.
하나의 서버에 여러개의 컨테이너를 실행하면 서로 영향을 미치지 않고 독립적으로 실행됩니다.

Docker 이미지

컨테이너 실행에 필요한 파일과 설정값등을 포함하고 있는 것으로 상태값을 가지지 않고 변하지 않습니다
컨테이너를 생성할 때 필요한 요소
이미지는 여러 개의 계층으로 된 바이너리 파일로 존재
컨테이너를 생성하고 실행할 때 읽기 전용으로 사용
[저장소 이름]/[이미지 이름]:[태그]의 형태로 구성

Docker 컨테이너

이미지로 컨테이너를 생성하면 이미지의 목적에 맞는 파일이 들어 있는 파일시스템과 격리된 시스템 자원 및 네트워크를 사용할 수 있는 독립된 공간이 생성되는데, 이것이 바로 도커 컨테이너입니다.
컨테이너는 이미지를 읽기 전용으로 사용
이미지에서 변경된 사항만 컨테이너 계층에 저장하기 때문에 이미지는 영향을 받지 않음
생성된 각 컨테이너는 각기 독립된 파일시스템을 제공받음

Docker 허브

도커 허브를 사용하여 이미지를 보관할 수 있습니다. 보관한 이미지를 활용하여 컨테이너를 실행합니다.

Docker 파일

Dockerfile

FROM python:3.10.6-slim

# Copy your Django project files
COPY ./ /app/

WORKDIR /app

# os-level installs
RUN apt-get update && \
    apt-get install -y \
    build-essential \
    python3-dev \
    python3-setuptools \
    libpq-dev \
    gcc \
    make \
    nginx

# venv & installs
RUN python3 -m venv /opt/venv && \
    /opt/venv/bin/python -m pip install pip --upgrade && \
    /opt/venv/bin/python -m pip install -r /app/requirements.txt

# purge unused
RUN apt-get remove -y --purge make gcc build-essential \
    && apt-get autoremove -y \
    && rm -rf /var/lib/apt/lists/*

RUN chmod +x ./entrypoint.sh
CMD ["./entrypoint.sh"]

entrypoint.sh

#!/bin/bash
APP_PORT=${PORT:-8000}

cd /app/

/opt/venv/bin/python manage.py collectstatic --noinput
/opt/venv/bin/gunicorn core.wsgi:application --bind "0.0.0.0:${APP_PORT}"
nginx -g "daemon off;"

Nginx

Nginx는 주로 웹 서버로 사용되지만, 리버스 프록시, 부하 분산, 캐싱, SSL 오프로딩, HTTP/2 지원 등 다양한 역할을 수행합니다. Nginx는 클라이언트의 요청을 받아 정적 파일 제공, 애플리케이션 서버로의 요청 전달, 부하 분산 등의 작업을 처리하여 웹 애플리케이션의 성능을 향상시키고 안정성을 확보합니다.

server : 가상 호스트 설정을 담고 있는 블록입니다.
upstream : 프록시 서버나 FastCGI 서버 등의 백엔드 서버를 가리킵니다.
location : 특정 URL 패턴에 대한 처리 방법을 설정하는 블록입니다.
리버스 프록시: 클라이언트와 웹 서버 사이에서 동작하여 클라이언트의 요청을 받아 웹 서버로 전달하고, 웹 서버의 응답을 클라이언트에게 전달하는 중개자 역할을 수행합니다.

nginx

nginx/Dockerfile

FROM nginx:1.19.0-alpine

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

nginx/default.conf

upstream <server_name> {
    server <server_name>:<port>;
}

server {
    listen 80;

    location / {
        proxy_pass http://<server_name>;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /static/ {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://<server_name>/static/;
    }

    location /media/ {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://<server_name>/media/;
    }
    
    location = /favicon.ico {
        access_log off;
        log_not_found off;
        return 204;
    }
}

docker-compose.yml

version: "3.8"
services:
  <server_name>:
    env_file:
      - .env
    build:
      context: .
      dockerfile: Dockerfile
    image: <image name>
    ports:
      - "<port>:<port>"
    networks:
      - <network name>

  nginx:
    build:
      context: .
      dockerfile: nginx/Dockerfile
    image: <image name>
    ports:
      - "80:80"
    depends_on:
      - <server_name>
    networks:
      - <network name>

networks:
  <network name>:

Dockerfile로만 build 시

docker build --no-cache --platform=linux/amd64 -f Dockerfile -t <repository>/<image name> .
docker build --no-cache --platform=linux/amd64 -f nginx/Dockerfile -t <repository>/<image name> .

docker-compose.yml 사용하여 dockerfile build 시

docker login
docker-compose build

tag 설정

docker tag <image name> <repository>/<image name>:<tag>

docker hub에 push

docker push <repository>/<image name>:<tag>

EC2 서버에서 docker image pull

sudo docker pull <repository>/<image name>:<tag>

Run container with .env file and Netwokrs

sudo docker network create <network name>
(If docker: Error response from daemon: network mynetwork not found)

sudo docker run -d --name <container name> --network <network name> -p <port>:<port> --env-file .env <repository>/<image name>:<tag>

Docker images

sudo docker images
sudo docker rmi image id ==> 이미지 삭제

Docker containers

sudo docker ps -a
sudo docker stop container id ==> 컨테이너 스톱
sudo docker rm container id ==> 컨테이너 삭제

profile
Backend Developer

0개의 댓글