1. 들어가기 전
도커 세팅은 언제 해야하는가. .많은 개발자들이 고민하는 문제일 것이다.
내가 몇 안되지만.. 주변에 자문을 구해본 결과 !! 대다수가 맨 처음에 다 세팅해두는게 편하다고 대답했다
그래서 내가 지금 그러고 있는데 결과는 굉장히 만족!! 세팅에는 굉장히 삽질했지만 그래도 만족한다.
서버 킬때 python run server 하던걸 그냥 docker-compose up 해주면 된다!
갱장히 편리~.~
본인 컴퓨터 : 맥 M1 칩
따라서 m1칩은 arm 베이스 이미지만 세팅이 되기때문에 몇개를 커스터마이징 해서 사용하였다.
아래 자세히 설명할 예정
2. 도커 세팅하기
2-1. 디렉토리 나누기
우선 나는 디렉토리를 나누어서 각각 도커 파일을 두었다.
프로젝트 이름이 kuku 라고 하면
Kuku-backend
- django
- app
- kuku <- 이거때문에 삽질 개많이했다..;; 프로젝트 이름이 여기에 들어감.,. 나도 왠지모름..
- Dockerfile
- requirements.txt
- mysql
- ngnix
- Dockerfile
- ngnix.conf
- project.conf
- docker-compose.yaml
2-2 Dockerfile 작성하기
- Django Dockerfile
여기서 Expose 등은 docker-compose.yaml파일에서 해주기 때문에 여기서는 하지 않는다.
(같은 이유로 CMD 명령어로 python runserver도 안한다.)
# Dockerfile
# Django 최상위 루트에서 작성
FROM python:3.8
# 컨테이너 내에서 코드가 실행될 경로 설정
WORKDIR /app
# requirements.txt에 명시된 필요한 packages 설치
COPY ./django/requirements.txt requirements.txt
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
# Project를 /usr/src/app으로 복사
COPY . .
- 예상 질문 ) 왜 그냥 도커허브에서 장고 이미지를 받지 않았나요?
- 대답 ) 위에도 말했듯이 m1 칩이라 arm베이스로 만들어야되는데,
그게 없어서 그냥 requirements 에 장고를 넣고 직접 설치해줬습니다!
#requirements.txt
Django==3.1.4
pymysql
Pillow
jsonify
requests
cryptography
gunicorn==20.0.4
djangorestframework
django-filter
asgiref
pytz
sqlparse
drf_yasg
- Ngnix Dockerfile
FROM nginx:1.15.8
RUN rm /etc/nginx/nginx.conf
COPY nginx.conf /etc/nginx/
RUN rm /etc/nginx/conf.d/default.conf
COPY project.conf /etc/nginx/conf.d/
- 엔지닉스는 평화롭게 도커 허브에서 공식 엔지닉스 가져왔당
2-3 ngnix 포트 연결하기
- 막간 설명 ) ngnix는 간단히 말해서 외부의 포트와 내부의 포트를 연결한다고 생각하면 된다.
그냥 더 간단하게 말하면 포트끼리 이어주는 역할이다.
- ngnix.conf
#ngnix.conf
#Define the user that will own and run the Nginx server
user nginx;
# Define the number of worker processes; recommended value is the number of
# cores that are being used by your server
worker_processes 1;
# Define the location on the file system of the error log, plus the minimum
# severity to log messages for
error_log /var/log/nginx/error.log warn;
# Define the file that will store the process ID of the main NGINX process
pid /var/run/nginx.pid;
# events block defines the parameters that affect connection processing.
events {
# Define the maximum number of simultaneous connections that can be opened by a worker process
worker_connections 1024;
}
# http block defines the parameters for how NGINX should handle HTTP web traffic
http {
# Include the file defining the list of file types that are supported by NGINX
include /etc/nginx/mime.types;
# Define the default file type that is returned to the user
default_type text/html;
# Define the format of log messages.
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# Define the location of the log of access attempts to NGINX
access_log /var/log/nginx/access.log main;
# Define the parameters to optimize the delivery of static content
sendfile on;
tcp_nopush on;
tcp_nodelay on;
# Define the timeout value for keep-alive connections with the client
keepalive_timeout 65;
# Define the usage of the gzip compression algorithm to reduce the amount of data to transmit
#gzip on;
# Include additional parameters for virtual host(s)/server(s)
include /etc/nginx/conf.d/*.conf;
}
- project.conf
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://django_app:8000;
# Do not change this
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static/ {
alias /app/venti/static/;
}
}
- 이게 완전 중요하다.
- listen 80 : ngnix 서버가 80의 변화를 체크함
외부 포트 (ex : 8084) 가 ngnix로 정보를 주면 80으로 연결되어 변화를 감지한다.
- location / proxy_pass http://django_app:8000;
80이 변하면 그걸 포트 8000으로 넘긴다.
여기서 django_app은 내가 docker_compose.yaml에서 선언한 장고 이름!!!!!
이것도 삽질 개많이했다.. 이 글을 보시는 분은 제발 삽질하지 마시길 ㅋㅋㅋㅋ
- location /static/
CSS 등 static file을 ngnix에 올려주는 애들이다.
자신의 static 파일의 위치를 찾은 다음 alias 로 연결 해준다.
이후 docker_compose.yaml 파일에 volumn에 올려야 한다.
2-4. 대망의 docker-compose.yaml파일 작성하기
version: '3.8'
services:
nginx:
container_name: nginx
build: ./nginx
ports:
- "8084:80"
volumes:
- ./django/venti/nginx:/etc/nginx.conf.d
- ./django/app:/app
- ./django/venti/static:/static
depends_on:
- django_app
mysql:
image: mariadb:latest
container_name: mysql
expose:
- "3306"
environment:
MYSQL_DATABASE: 디비이름
MYSQL_USER: root
MYSQL_PASSWORD: 디비비번
MYSQL_ROOT_PASSWORD: 디비비번
volumes:
- ../db/data:/var/lib/mysql
- ../db/data/conf.d:/etc/mysql/conf.d
django_app:
container_name: django_app
build:
context: .
dockerfile: ./django/Dockerfile
command: gunicorn kuku.wsgi:application --bind 0.0.0.0:8000
expose:
- "8000"
depends_on:
- mysql
links:
- mysql:mysql
restart: always
volumes:
- ./django/app:/app
env_file:
- ./django/env.dev
networks:
app-tier:
driver: bridge
- version은 도커 버전이다.
- services 안에 적힌 애들이 내가 도커에 올리고 싶은 애들이다.
나는 ngnix mysql django 3개를 올렸다.
여기서 django_app이 아까 위의 ngnix 프록시 설정을 해주었던 그 이름이다!
- ngnix
- ngnix 의 ports : 외부 포트, ngnix의 포트
: 다른 곳에서는 같은 포트 번호도 쓰던데 나는 자꾸 충돌나서 포트 번호를 바꿨다. (로컬에서 해서 그런가?
근데 포트 번호를 바꾸니 잘 된다.
- ngnix 의 volumes
필요한 파일들이라고 생각하면 된다.
: 앞에 적힌게 현재 내 파일에서의 위치이고 : 뒤에 적힌게 도커가 올라갔을때 파일위치가 된다고 한다.
static파일도 잊지말고 추가해주자 !
- ngnix 의 depends_on
ngnix가 실행되면 장고 앱이 실행되어야 하므로 장고 앱을 넣어준다.
- django_app
- django 의 command :
아까 내가 장고 도커파일을 선언할때 expose 를 도커 컴포즈 얌파일에서 한다고 했는데 그게 이 부분이다.
장고는 파이썬 기반이라 웹 서버가 이해하지 못하기때문에 WSGI 서버인 gunicorn 을 이용해서 ngnix 와 django를 연결해야된다.
따라서 다음과 같이 bind 명령어를 사용하여 연결한다.
command: gunicorn kuku.wsgi:application --bind 0.0.0.0:8000
이 명령어는 kuku(프로젝트 이름 : 아까 볼드 쳐둔 그거) 를 위스기 서버랑 연결해서 8000 번에 띄운다는 소리이다.
- restart : always
핫 리로드라고도 불리는데 그냥 변경사항이 생겼을때마다 리스타트를 해라 이런거다
변경사항 생길때마다 리로드가 되는거 같기는 한데 나는 안되면 괜히 반영안된 탓해서 도커 끄고 다시 킨다 ㅋㅋㅋ
잘못된 습관
- links
장고 안에 db와 연결할 때 mysql과 연결하는 것은 도커 파일의 mysql 과 연결한다는 뜻이다.
이렇게 장고 안의 db와 연결하는 secret.json파일의 host 를 mysql로 해두면 연결이 된다.
{
"DB_SETTINGS": {
"default" : {
"ENGINE": "django.db.backends.mysql",
"NAME": "디비이름",
"USER": "root",
"PASSWORD": "비번",
"HOST": "mysql",
"PORT": "3306"
}
}
}
- mysql
mysql:
image: mariadb:latest
mysql이라면서 웬 마리아디비? 라고 생각하는 사람이 있을 것이다.
아까도 말했듯이 내가 m1칩인데 mysql디비는 arm 형식이 아니어서 mariadb이미지를 사용했다.
mysql처럼 이용하면 된다.
- mysql의 expose
mysql을 띄울 포트 번호를 지정해주면 된다.
이렇게 하면 도커 세팅이 끝난다.
뭔가 빠진거 같긴한데..? 생각하면 채워놓겠다^^*
3. 도커 구동하기
이미지 빌드하기
docker-compose build
컨테이너 올리기
docker-compose up
빌드하고 올리기
docker-compose up --build
아까 나는 ngnix를 8084포트와 연결해놨으므로
http://localhost:8084
로 접속하면 된다.
- 끝 -
질문 있으시면 댓글 달아주시면 아는 선에서 대답해드릴게여