基於 Docker 的 Django 容器化部署之一:定製屬於自己的 docker 鏡像

本文章爲原創內容,只發佈於本博客和 我的私人博客,轉載請註明,謝謝


項目源碼,歡迎 Fork 和 Star | 本人 Django 博客預覽


基於 Docker 的 Django 容器化部署教程分爲三部分,當前所在的是第一部分

項目部署一直都是很繁瑣的事情,由於開發環境和上線服務器的環境不同,所以各種依賴軟件包的安裝、迭代更新的部署、各種命令的執行都是問題,由此容器化進行項目上線就是一個很好的解決辦法。

本次使用的是 Docker,屬於 Linux 容器 的一種封裝,提供簡單易用的容器使用接口。docker 將應用程序與該程序的依賴打包到一個文件裏面,運行這個文件,就會生成一個輕量級、可移植的虛擬容器,然後發佈到任何流行的 Linux 或 Windows 機器上,程序在這個虛擬容器裏面運行就像在真實的物理機上面運行一樣。這種容器技術,可以爲我們提供一個隔離的運行環境,並且只提供我們所需要的內容。

瞭解 docker 及 docker-compose

Docker

Docker 的整個生命週期由三部分組成:鏡像(image)+ 容器(container)+ 倉庫(repository)

Docker 可以生成多個鏡像,每個鏡像,可以創建多個容器。可以理解成:每一個容器都是一個獨立的虛擬操作系統,互不影響,而鏡像就是這個操作系統的安裝包。想要生成一個容器,就要用安裝包(鏡像)生成一次,這就是 Docker 的核心概念。發佈到倉庫(比如 DockerHub)時,是以鏡像爲單位。

  • 鏡像,是一個只讀的模板,一個獨立的文件系統,包括運行容器所需的數據,可以用來創建新的容器。鏡像可以包含一個完整的 Linux 操作環境,裏面僅安裝了 Python 或者其他用戶需要的程序。
  • 容器,是由鏡像實例化而來,容器是基於鏡像創建的,即容器中的進程依賴於鏡像中的文件,類似虛擬機,裏面可以運行特定的應用,並且容器與容器是相互隔離的。這有點像面向對象的概念:鏡像就是類,容器是類實例化之後的對象。

  • 倉庫,與 GitGithub 類似,Docker 使用的默認倉庫是由官方維護的 Docker hub 公共倉庫,此倉庫是用來包含鏡像的位置,同時其還提供了一個註冊服務器(register)來保存多個倉庫,每個倉庫又可以包含多個具備不同 tag 的鏡像,而倉庫支持的操作如上傳、拉取等動作類似於 Git

docker-compose

Docker Composedocker 提供的一個命令行工具,用來定義和運行由多個容器組成的應用。使用 compose,我們可以通過 YAML 文件聲明式的定義應用程序的各個服務,並由單個命令完成應用的創建和啓動。簡單來說,就是用來編排多個容器,將啓動容器的命令統一寫到 docker-compose.yml 文件中,一次啓動全部啓動。

安裝 docker 及 docker-compose

基於 Dockerfile 構建鏡像

打包鏡像,就要用到一個文本文件,這個文本默認名稱就是 Dockerfile.

鏡像構建的過程中有一個非常重要的概念就是分層構建,前一層是後一層的基礎。每一層構建完就不會再發生改變,後一層上的任何改變只發生在自己這一層。比如,刪除前一層文件的操作,實際不是真的刪除前一層的文件,而是僅在當前層標記爲該文件已刪除。在最終容器運行的時候,雖然不會看到這個文件,但是實際上該文件會一直跟隨鏡像。

先來看一下我的目錄結構,這樣子編排是因爲後面要使用 docker-compose

.
├── django
├── docker-compose.yml
└── nginx

在項目的根目錄下新建一個 Dockerfile 文件,無後綴,寫入下面內容

# 從倉庫拉取 python 官方的 image,:3.7就是標籤,代表是 3.7 版本的 python 鏡像
FROM python:3.7

# 作者信息
LABEL "author"="HONGWEI"
LABEL "blog"="https://www.zhwei.cn/"
LABEL "E-mail"="[email protected]"

# 設置 python 環境變量
ENV PYTHONUNBUFFERED 1

# 構建參數
## 定義存放本機中的 django 項目的目錄
ARG work_dir=/opt/hw-blog

# 在鏡像中創建目錄並設置項目運行的工作目錄
RUN mkdir -p ${work_dir}
WORKDIR ${work_dir}

# 將 django 的源碼複製到容器的工作目錄,其中requirements.txt在裏面
ADD ./django ${work_dir}

# 安裝依賴包
RUN pip install -r requirements.txt

構建鏡像

docker build -t hw-website .

構建完之後查看一下docker images

REPOSITORY                 TAG                 IMAGE ID            CREATED              SIZE
hw-website                 latest              4ff*****1cae        About a minute ago   1.06GB

定製屬於自己的 docker 鏡像

當你以上面的方式進行打包鏡像的時候你會發現鏡像的體積很大,並且裏面有好多包是我們不需要的

  • Centos 的 Python 3.7 的鏡像 900M+,包含python2
  • Ubuntu 的 Python 3.7 的鏡像 800M+,
  • Python:3.7-alpine 鏡像 90M+,但好多東西沒有,需要自己構建

所以我們就要進行自己定製,裏面只有我需要的

Dockerfile


# 從倉庫拉取 帶有 python 3.7 的 Alpine Linux 環境
FROM python:3.7-alpine

# 作者信息
LABEL "author"="HONGWEI"
LABEL "blog"="https://www.zhwei.cn/"
LABEL "E-mail"="[email protected]"

# 構建參數,工作目錄
ARG work_dir=/opt/hw-blog

RUN mkdir -p ${work_dir}
WORKDIR ${work_dir}

# 將當前目錄複製到容器的工作目錄
ADD ./django ${work_dir}

# 安裝alpine依賴, system update\ mysqlclient\ system lib\ Pillow\ bash
RUN apk update \
    && apk add --virtual mysqlclient-build gcc python3-dev musl-dev \
    && apk add --no-cache mariadb-dev \
    && apk add --virtual system-build linux-headers libffi-dev \
    && apk add --no-cache jpeg-dev zlib-dev freetype-dev lcms2-dev openjpeg-dev tiff-dev tk-dev tcl-dev \
    && apk add --no-cache bash bash-doc bash-completion \
    && pip install pip -U \
    && pip install -r ${work_dir}/requirements.txt 

# 在Alpine上,pip將從源代碼構建需要依賴包來install,如mysqlclient需要gcc和musl-dev,因此需要將apk del *-build推遲到安裝Python模塊之後
RUN apk del mysqlclient-build \
    && apk del system-build 


構建鏡像

docker build -t hw-website .

構建完之後查看一下docker images,效果立杆見影

REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
hw-website                 latest              14a*****6c5a        12 minutes ago      549MB

依賴包說明:

  • python:3.7-alpinealpine 是一個 Linux 系統發行版,主打小巧、輕量、安全。我們程序運行需要 Python 環境,因此使用這個小巧但包含完整 Python 環境的基礎鏡像來構建我們的應用鏡像。
  • mysqlclient:我使用的是mysql數據庫。編譯所需的庫文件在pypi上可以查到 mysqlclient依賴庫
  • Pillow:使用 django 處理圖片時,會使用到 Pillow 這個 Python 庫。Pillow依賴庫

所以至於你需要的其他庫的依賴,需要去搜索一下

小技巧

  • 添加alpine apk源

參考 Alpine Linux package managementalpine-mirrors/mirrors.yaml

# 添加alpine apk源
RUN echo "http://mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories;
RUN echo "http://mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories;
RUN echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/latest-stable/main/" >> /etc/apk/repositories;
RUN echo "https://mirrors.tuna.tsinghua.edu.cn/alpine/latest-stable/community/" >> /etc/apk/repositories;
RUN echo "http://dl-cdn.alpinelinux.org/alpine/latest-stable/community/" >> /etc/apk/repositories;
RUN echo "http://dl-2.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories;
RUN echo "http://dl-3.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories;
RUN echo "http://dl-4.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories;
RUN echo "http://dl-5.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories

  • 添加豆瓣pip
# 構建參數,pip源
ARG pip_url=https://pypi.douban.com/simple
ARG pip_host=pypi.douban.com

# 更新 pip 到最新
RUN pip install pip -U -i ${pip_url}

# 將本地的文件拷貝到容器鏡像
COPY requirements.txt /requirements.txt

# pip 安裝依賴文件
RUN pip install -r requirements.txt -i ${pip_url} --trusted-host ${pip_host}

好了,問題來了


鏡像我都構建完了,怎麼用呢?

請看下一篇 基於 Docker 的 Django 容器化部署之二:docker-compose 部署 Django 項目

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章