Data Navigator

[Django] docker-compose 로 django와 mysql 연결하기 본문

Python

[Django] docker-compose 로 django와 mysql 연결하기

코딩하고분석하는돌스 2023. 9. 14. 13:30

 

 

django로 만든 프로젝트를 docker-compose로 세팅하면서 mysql DB를 연결하는 방법

 

 

mysqlclient가 속도면에서 빠르기 때문에 권장되고 있지만 2023년 9월 14일 기준으로 docker에서 pip install시 에러가 발생해 pymysql로 진행함.

 

1. pymysql 설치

pip install pymysql

 

2. django project의 settings.py 수정

  • import pymysql 추가
  •  
import os
from pathlib import Path
import pymysql


# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
  • pymysql.install_as_MySQLdb() 을 database 설정하는 부분에 추가
pymysql.install_as_MySQLdb()

DATABASES = {
    'default': {
        'ENGINE': os.environ.get("SQL_ENGINE", 'django.db.backends.mysql'),
        'NAME': os.environ.get('SQL_DATABASE', os.path.join(BASE_DIR, '<db이름>')),
        'USER': os.environ.get('SQL_USER', '<mysql ID>'),
        'PASSWORD': os.environ.get('SQL_PASSWORD', '<password>'),
        'HOST': os.environ.get('SQL_HOST', 'localhost'),
        'PORT': os.environ.get('SQL_PORT', '3306'),
    }
}

 

3. docker-compose.yml 파일 수정

 gunicorn과 nginx도 같이 연결되어 있는 docker-compose.yml 파일임

version: '3'

services:
  nginx:
    build: ./nginx
    volumes:
      - static_volume:/usr/src/app/_static
      - media_volume:/usr/src/app/_media
    ports:
      - 80:80
    depends_on:
      - web

  web:
    build: .
    command: gunicorn <프로젝트명>.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - static_volume:/usr/src/app/_static
      - media_volume:/usr/src/app/_media
      - ./:/usr/src/app/
    expose:
      - 8000
    env_file:
      - ./.env.prod

    depends_on:
      - db

  db:
    image: mysql:8.0
    container_name: mysqldb   # 데이터베이스 이름
    restart: always
    environment:
      TZ: Asia/Seoul
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
    volumes:
      - mysql_data:/var/lib/mysql  # volume 경로는 왼쪽 그대로 유지
    
    env_file:
      - ./.env.prod.db

volumes:
  mysql_data:
  static_volume:
  media_volume:

 

4. .env.prod 파일과 .env.prod.db 파일 수정

docker-compose.yml 파일이 있는 곳에 .env.prod와 .env.prod.db 파일을 만들고 내용 수정

 

  • .env.prod 파일 수정
# SQL관련 부분의 = 앞 뒤는 반드시 공백 없이 작성

DEBUG = 0
SECRET_KEY = 'settings.py에 있는 SECRET_KEY'
DJANGO_ALLOWED_HOSTS = localhost 127.0.0.1 [::1]

SQL_ENGINE=django.db.backends.mysql
SQL_DATABASE=my_blog_site   # db 이름 
SQL_USER=<user_id> # db user 이름 
SQL_PASSWORD=<password>  # 패스워드
SQL_HOST=db
SQL_PORT=3306
  • .env.prod.db 파일 수정
# db 데이터 베이스 이름과 id, password 설정

MYSQL_DATABASE=my_blog_site    # DB이름
MYSQL_USER=<user_id>  # db user id
MYSQL_PASSWORD=<password>   # db user password

 

5. docker-compose build

(venv) C:\bigdata\github\my_port2>docker-compose build
[+] Building 3.0s (12/12)                                                                                       docker:default
[+] Building 5.6s (21/21) FINISHED                                                                              docker:default
 => [web internal] load build definition from Dockerfile                                                                  0.1s
 => => transferring dockerfile: 368B                                                                                      0.0s
 => [web internal] load .dockerignore                                                                                     0.1s
 => => transferring context: 2B                                                                                           0.0s
 => [web internal] load metadata for docker.io/library/python:3.8-slim-buster                                             2.6s
 => [web auth] library/python:pull token for registry-1.docker.io                                                         0.0s
 => [web 1/6] FROM docker.io/library/python:3.8-slim-buster@sha256:8799b0564103a9f36cfb8a8e1c562e11a9a6f2e3bb214e2adc239  0.0s
 => [web internal] load build context                                                                                     0.1s
 => => transferring context: 19.48kB                                                                                      0.1s
 => CACHED [web 2/6] WORKDIR /usr/src/app                                                                                 0.0s 
 => CACHED [web 3/6] COPY . /usr/src/app/                                                                                 0.0s 
 => CACHED [web 4/6] RUN pip install --upgrade pip                                                                        0.0s 
 => CACHED [web 5/6] RUN pip install -r requirements.txt                                                                  0.0s 
 => CACHED [web 6/6] RUN pip install pymysql                                                                              0.0s 
 => [web] exporting to image                                                                                              0.0s 
 => => exporting layers                                                                                                   0.0s 
 => => writing image sha256:608e81fa5430124b0707639c3e77a0731346d7fdf5da79c6930595c5a91adde7                              0.0s 
 => => naming to docker.io/library/my_port2-web                                                                           0.0s 
 => [nginx internal] load build definition from Dockerfile                                                                0.0s 
 => => transferring dockerfile: 128B                                                                                      0.0s 
 => [nginx internal] load .dockerignore                                                                                   0.0s 
 => => transferring context: 2B                                                                                           0.0s 
 => [nginx internal] load metadata for docker.io/library/nginx:latest                                                     2.0s 
 => [nginx auth] library/nginx:pull token for registry-1.docker.io                                                        0.0s 
 => [nginx 1/3] FROM docker.io/library/nginx:latest@sha256:6926dd802f40e5e7257fded83e0d8030039642e4e10c4a98a6478e9c6fe06  0.0s 
 => [nginx internal] load build context                                                                                   0.0s 
 => => transferring context: 32B                                                                                          0.0s 
 => CACHED [nginx 2/3] RUN rm /etc/nginx/conf.d/default.conf                                                              0.0s 
 => CACHED [nginx 3/3] COPY nginx.conf /etc/nginx/conf.d                                                                  0.0s 
 => [nginx] exporting to image                                                                                            0.0s 
 => => exporting layers                                                                                                   0.0s 
 => => writing image sha256:53a7934b2258c0fdd18ec9189e376247092b20c7899758db34770c2b780b747d                              0.0s 
 => => naming to docker.io/library/my_port2-nginx                                                                         0.0s 

(venv) C:\bigdata\github\my_port2>

 

6. docker-compose up -d

(venv) C:\bigdata\github\my_port2>docker-compose up -d
[+] Running 4/4
 ✔ Network my_port2_default    Created                                                                                    0.1s 
 ✔ Container mysqldb           Started                                                                                    0.9s 
 ✔ Container my_port2-web-1    Started                                                                                    1.3s 
 ✔ Container my_port2-nginx-1  Started                                                                                    1.7s 

(venv) C:\bigdata\github\my_port2>

 

7. docker container ls 로 컨테이너 3개가 잘 떠 있는지 확인

(venv) C:\bigdata\github\my_port2>docker container ls
CONTAINER ID   IMAGE            COMMAND                   CREATED              STATUS              PORTS                 NAMES
91f1caf9c35e   my_port2-nginx   "/docker-entrypoint.…"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp    my_port2-nginx-1
aaf848850644   my_port2-web     "gunicorn do_it_djan…"   About a minute ago   Up About a minute   8000/tcp              my_port2-web-1
516871aa1e14   mysql:8.0        "docker-entrypoint.s…"   About a minute ago   Up About a minute   3306/tcp, 33060/tcp   mysqldb
(venv) C:\bigdata\github\my_port2>

 

8. docker-compose exec web python manage.py migrate 로 DB 마이그레이션

(venv) C:\bigdata\github\my_port2>docker-compose exec web python manage.py migrate
System check identified some issues:

WARNINGS:
account.EmailAddress: (models.W036) MySQL does not support unique constraints with conditions.
        HINT: A constraint won't be created. Silence this warning if you don't care about it.
Operations to perform:
  Apply all migrations: account, admin, auth, blog, contenttypes, sessions, sites, socialaccount
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying account.0001_initial... OK
  Applying account.0002_email_max_length... OK
  Applying account.0003_alter_emailaddress_create_unique_verified_email... OK
  Applying account.0004_alter_emailaddress_drop_unique_email... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying blog.0001_initial... OK
  Applying sessions.0001_initial... OK
  Applying sites.0001_initial... OK
  Applying sites.0002_alter_domain_unique... OK
  Applying socialaccount.0001_initial... OK
  Applying socialaccount.0002_token_max_lengths... OK
  Applying socialaccount.0003_extra_data_default_dict... OK
  Applying socialaccount.0004_app_provider_id_settings... OK

(venv) C:\bigdata\github\my_port2>

위와 같이 db가 만들어지면 ok

 

9. docker-compose exec web python manage.py createsuperuser로 관리자 계정 생성

(venv) C:\bigdata\github\my_port2>docker-compose exec web python manage.py createsuperuser
Username (leave blank to use 'root'): <관리자 id>
Email address: <관리자 email>
Password:  <관리자 password>
Password (again): <관리자 password 확인>
Superuser created successfully.

(venv) C:\bigdata\github\my_port2>

 

10. localhost/admin 에 접속해 관리자 계정으로 로그인 후 site 세팅하면 끝