Django-Docker容器化部署:Django-Docker-MySQL部署

上一章咱們成功搭建了容器化的 Django 項目,用到的數據庫爲默認的 Sqlite。Sqlite 雖然簡單易用,可是線上部署時一般會選擇更高效、更可靠的數據庫,好比 MySQL。python

本章將在上一章的基礎上,修改並構建 Docker + Django + MySQL 的容器項目。mysql

Docker-compose

咱們在學習面向對象的編程語言時,會千方百計把功能獨立的模塊給獨立出來,方便複用和維護。git

容器也是同樣的。雖然理論上能夠把全部組件塞到同一個容器中去,但更好的作法是各模塊在單獨容器中,只要保持必要的通訊就能夠了。github

也就是說,本教程中如今須要兩個容器了:sql

  • 名稱叫 app 的 Django 容器
  • 名稱叫 db 的 MySQL 容器

因此如何構建 MySQL 鏡像?別擔憂,這麼經常使用的鏡像官方已經幫你構建好了,只須要把它從倉庫拉取到本地就能夠了。docker

修改上一章寫的 docker-compose.yml ,增長 MySQL 容器:shell

version: "3"
services:
  app:
    restart: always
    build: .
    command: bash -c "python3 manage.py migrate && python3 manage.py runserver 0.0.0.0:8000"
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db
  db:
    image: mysql:5.7
    volumes:
      - "./mysql:/var/lib/mysql"
    ports:
      - "3306:3306"
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=mypassword
      - MYSQL_DATABASE=django_app
複製代碼

app 容器的 command 指令作了修改,讓其在運行前先執行數據遷移;新增了配置 depends_on ,意思是此容器須要等待 db 容器啓動完畢纔可以啓動。數據庫

分析一下新添加的 db 容器:django

  • image :從倉庫拉取 MySQL 5.7 。最新版本爲 MySQL 8,不過很坑的是新版本修改了用戶登陸的驗證方法,致使很容易出現沒法經過身份驗證的問題。教程爲了簡單起見選用 5.7 版本。後期會在教程示例代碼中添加mysql-8分支並給出操做方法,有興趣的讀者能夠查看。
  • volumes :定義卷(這裏實際是掛載),上一章已經講過了,它實現了宿主機和容器目錄的映射。功能是將容器中的 MySQL 數據映射到宿主機。
  • ports :MySQL 默認通訊端口爲 3306 。
  • environment :定義容器的環境變量,設置了 MySQL 的 root 用戶的密碼、數據庫的名稱。

這裏爲何要用?就讓數據在容器中、保持隔離很差嗎?把數據保存在容器中,理論上確實是能夠的,但有一個致命的問題,即數據和容器的生命週期掛鉤了:萬一哪天手賤把容器給刪了,連同裏面的數據隨風而逝,你就是全公司那個刪庫跑路的傳奇人物了。要知道容器的生命週期可能會很是短暫,刪除指令也至關順滑(docker-compose down)。將數據映射到宿主機,容器即便被刪除掉,但數據仍是安全的躺在你的服務器中的。換句話說,容器內部很是適合運行無狀態的應用;涉及到如數據之類有狀態的東西,必定要謹慎思考。編程

Dockerfile

接下來修改 Dockerfile

FROM python:3.7
ENV PYTHONUNBUFFERED 1
 # 添加這兩行
RUN apt-get update
RUN apt-get install python3-dev default-libmysqlclient-dev -y

RUN mkdir /code
WORKDIR /code
RUN pip install pip -U
ADD requirements.txt /code/
RUN pip install -r requirements.txt
ADD . /code/
複製代碼

增長的兩行代碼在系統中安裝了 MySQL 的鏈接器,具體解釋見官方文檔

其餘配置

修改 requirements.txt ,增長 MySQL 驅動:

django==2.2
mysqlclient==1.3.14
複製代碼

而後還須要修改 django_app/settings.py ,將數據庫設置爲 MySQL:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'django_app',
        'USER': 'root',
        'PASSWORD': 'mypassword',
        'HOST': 'db',
        'PORT': '3306',
        'OPTIONS': {'charset': 'utf8mb4'},
    }
}
複製代碼

注意 HOST 填寫的是容器的名稱,即 db 。

這就能夠啦。接下來測試。

測試

測試以前,請先確認沒有其餘程序佔用了 3306 端口,好比宿主機安裝的 MySQL。

從新生成鏡像:

$ docker-compose build
複製代碼

生成並啓動容器:

$ docker-compose up

Creating network "django_app_default" with the default driver
Creating django_app_db_1 ... done
Creating django_app_app_1 ... done
Attaching to django_app_db_1, django_app_app_1
db_1   | 2019-10-06T12:24:57.183860Z 0 [Note] mysqld (mysqld 5.7.27) starting as process 1 ...

...

db_1   | 2019-10-06T12:24:58.120480Z 0 [Note] mysqld: ready for connections.
db_1   | Version: '5.7.27'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)

app_1  | Operations to perform:
app_1  |   Apply all migrations: admin, auth, contenttypes, sessions
app_1  | Running migrations:
app_1  |   Applying contenttypes.0001_initial... OK
...
app_1  |   Applying sessions.0001_initial... OK

app_1  | Watching for file changes with StatReloader
app_1  | Performing system checks...
app_1  | 
app_1  | System check identified no issues (0 silenced).
app_1  | October 06, 2019 - 12:24:58
app_1  | Django version 2.2, using settings 'django_app.settings'
app_1  | Starting development server at http://0.0.0.0:8000/
app_1  | Quit the server with CONTROL-C.
複製代碼

打開瀏覽器訪問 127.0.0.1:8000 ,又能看到 Django 小火箭啦。

**注意:**第一次啓動容器時可能會出現沒法鏈接 MySQL 的錯誤,這是因爲雖然 db 容器已經啓動,但初始化並未完成;從新啓動容器以後就能夠正常工做了。若屢次啓動都沒法正常工做,那就是別的緣由了,好好檢查吧。

總結

本章加入了 MySQL 容器,並實現了多容器協同工做。

下一章將實現正式部署的 Docker + Django + MySQL + Nginx + Gunicorn 項目。


相關文章
相關標籤/搜索