深圳梁律师 發表於 2020-3-20 12:43:00

Docker 容器化部署 Python 应用

<p>Docker 是一个开源项目,为开发人员和系统管理员提供了一个开放平台,可以将应用程序构建、打包为一个轻量级容器,并在任何地方运行。Docker 会在软件容器中自动部署应用程序。</p>

<p>在本篇中,我将介绍如何 docker 化一个 Python Django 应用程序,然后使用一个 <code>docker-compose</code> 脚本将应用程序作为容器部署到 docker 环境。</p>
<h1 id="环境">环境</h1>
<h2 id="操作系统">操作系统</h2>
<pre><code class="language-shell"> dbnuo@localhost~sw_vers
ProductName:        Mac OS X
ProductVersion:        10.15.3
BuildVersion:        19D76

dbnuo@localhost~uname -v
Darwin Kernel Version 19.3.0: Thu Jan9 20:58:23 PST 2020; root:xnu-6153.81.5~1/RELEASE_X86_64
</code></pre>
<h2 id="docker-版本">Docker 版本</h2>
<pre><code class="language-shell"> dbnuo@localhost~docker -v
Docker version 19.03.8, build afacb8b
</code></pre>
<h2 id="docker-compose-版本">Docker Compose 版本</h2>
<pre><code class="language-shell"> dbnuo@localhost~docker-compose -v
docker-compose version 1.25.4, build 8d51620a
</code></pre>
<h1 id="目录结构">目录结构</h1>
<p>这里列出本次用到的相关文件和目录,以下会介绍每个文件目录的作用和内容。</p>
<pre><code>.
├── bash.alias
├── docker-compose.yml
├── .env
├── services
│&nbsp;&nbsp; └── python
│&nbsp;&nbsp; │&nbsp;&nbsp; ├── Dockerfile
│&nbsp;&nbsp; │&nbsp;&nbsp; └── requirements.txt
└── www
    └── python
</code></pre>
<ul>
<li><strong>bash.alias</strong>:用以记录本地终端的命令。</li>
<li><strong>docker-compose.yml</strong>:容器配置文件。</li>
<li><strong>.env</strong>:环境变量设置文件。</li>
<li><strong>services/python/Dockerfile</strong>:镜像构建文件。</li>
<li><strong>services/python/requirements.txt</strong>:依赖包管理文件。</li>
<li><strong>www/python</strong>:项目/代码存放目录。</li>
</ul>
<h1 id="构建部署">构建部署</h1>
<h2 id="设置环境变量">设置环境变量</h2>
<p>打开 <code>.env</code> 文件,添加以下内容:</p>
<pre><code class="language-env">#
# python
#
PYTHON_VERSION=3.8.2
PYTHON_PORT=9100
</code></pre>
<ul>
<li>
<p><strong>PYTHON_VERSION</strong>:用以设置 Python Tags,可以在 Docker Hub 上查看所有 Tags。</p>
</li>
<li>
<p><strong>PYTHON_PORT</strong>:本地映射容器端口的端口。</p>
</li>
</ul>
<h2 id="构建镜像">构建镜像</h2>
<p>打开 <code>services/python/Dockerfile</code> 文件,添加以下内容:</p>
<pre><code class="language-dockerfile">ARG PYTHON_VERSION
FROM python:${PYTHON_VERSION} AS python-base

ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONFAULTHANDLER 1

FROM python-base AS python-deps

WORKDIR /code

RUN apt-get update \
    &amp;&amp; apt-get -y install freetds-dev \
    &amp;&amp; apt-get -y install unixodbc-dev

COPY requirements.txt ./

RUN pip install -r requirements.txt -i https://pypi.douban.com/simple
</code></pre>
<p>我描述下每个部分:</p>
<ol>
<li>首先,指定要在其上构建镜像的 Python 镜像。这是由 Docker 组织提供的官方镜像,该 Python 镜像版本由环境变量 <code>PYTHON_VERSION</code> 设置。我们为该镜像命名 <code>python-base</code>,它将在下个阶段使用到:</li>
</ol>
<pre><code class="language-dockerfile">ARG PYTHON_VERSION
FROM python:${PYTHON_VERSION} AS python-base
</code></pre>
<ol start="2">
<li>接下来,设置环境变量以正确设置语言环境,阻止Python生成 <code>.pyc</code> 文件,并在 segfaults 上启用 Python 追溯:</li>
</ol>
<pre><code class="language-dockerfile">ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONFAULTHANDLER 1
</code></pre>
<ol start="3">
<li>最后,使用 <code>python-base</code> 镜像开始新的构建阶段。我们将在 <code>python-deps</code> 映像中安装所有 Python 依赖项:</li>
</ol>
<pre><code class="language-dockerfile">FROM python-base AS python-deps

WORKDIR /code

RUN apt-get update \
    &amp;&amp; apt-get -y install freetds-dev \
    &amp;&amp; apt-get -y install unixodbc-dev

COPY requirements.txt ./

RUN pip install -r requirements.txt -i https://pypi.douban.com/simple
</code></pre>
<h2 id="依赖包管理">依赖包管理</h2>
<p>打开 <code>services/python/requirements.txt</code> 文件,添加项目需要的依赖。示例:</p>
<pre><code>Django==3.0.4
djangorestframework==3.11.0
pyDes==2.0.1
PyMySQL==0.9.3
redis==3.4.1
requests==2.23.0
pyodbc==4.0.30
paramiko==2.7.1
psutil==5.7.0
</code></pre>
<h2 id="容器配置">容器配置</h2>
<p>打开 <code>docker-compose.yml</code> 文件,配置容器:</p>
<pre><code class="language-yaml">version: "3"
services:

python:
    build:
      context: ./services/python
      args:
      PYTHON_VERSION: ${PYTHON_VERSION}
    command: python3 /code/HelloWorld/manage.py runserver 0.0.0.0:8000
#    command:
#      - /bin/sh
#      - -c
#      - |
#      django-admin startproject HelloWorld
#      python3 /code/HelloWorld/manage.py runserver 0.0.0.0:8000
    container_name: python
    hostname: python
    volumes:
      - ${SOURCE_DIR}/python:/code:rw
    expose:
      - "8000"
    ports:
      - "${PYTHON_PORT}:8000"
    privileged: true
    restart: always
    networks:
      - default

networks:
default:
</code></pre>
<p>有关 Docker Compose 的详细介绍,大家可以查阅官方文档。</p>
<p>这里主要说明下 <code>command</code> ,这是配置在容器启动后执行的命令,类似 Dockerfile 的 <code>CMD</code>。</p>
<p>配置中又两个 <code>command</code>,其中一个注释了,二者只能使用一个。第一个是单条命令的配置方式,下面的是多条命令的配置方式。视个人情况修改其中命令和路径(初次测试,建议使用下面的 command ,会自动初始化一个 HelloWorld 项目并启动)。</p>
<h1 id="启动容器">启动容器</h1>
<p>在文件根目录下运行命令:</p>
<pre><code class="language-shell">docker-compose up -d
</code></pre>
<p>运行该命令会自动构建镜像并启动容器,执行完毕后:</p>
<p>查看镜像:</p>
<pre><code class="language-shell">docker images
</code></pre>
<pre><code>REPOSITORY                           TAG               IMAGE ID            CREATED             SIZE
dnmp_python                        latest            7218552b8814      17 hours ago      1.02GB
python                               3.8.2               f88b2f81f83a      3 weeks ago         933MB
</code></pre>
<p>查看容器:</p>
<pre><code class="language-shell">docker-compose ps -a
</code></pre>
<pre><code>    Name                   Command               State                  Ports
-------------------------------------------------------------------------------------------------
python          python3 /code/HelloWorld/m ...   Up      0.0.0.0:9100-&gt;8000/tcp
</code></pre>
<p><code>State</code> 状态为 Up 说明启动成功。</p>
<p>打开浏览器访问试一试:</p>
<p><img src="###qg1bzp-1-png###" alt="" loading="lazy"></p>
<p>运行成功。这里列几个常用的命令:</p>
<p><strong>启动容器</strong>:<code>docker-compose start python</code></p>
<p><strong>停止容器</strong>:<code>docker-compose stop python</code></p>
<p><strong>重启容器</strong>:<code>docker-compose restart python</code></p>
<p><strong>删除容器</strong>:<code>docker-compose &amp;&amp; docker-compose rm python</code></p>
<p><strong>查看日志</strong>:<code>docker logs python</code></p>
<h1 id="host-使用-python-命令">Host 使用 Python 命令</h1>
<p>终端命令都会记录在文件 <code>bash.alias</code> 中。</p>
<p>这里说下如何在本地使用 <code>python</code> 命令:</p>
<p>打开 <code>~/.bashrc</code> (如果是 zsh 客户端的使用 <code>~/.zshrc</code>)</p>
<p>添加以下代码至文件:</p>
<pre><code class="language-shell">python () {
    tty=
    tty -s &amp;&amp; tty=--tty
    docker run \
      $tty \
      --interactive \
      --rm \
      --volume $PWD:/code:rw \
      --workdir /code \
      dnmp_python python "$@"
}
</code></pre>
<p>刷新配置文件,使之生效:<code>source ~/.bashrc</code>(如果是 zsh 客户端的使用 <code>source ~/.zshrc</code>)</p>
<p>这时候在本地即可使用 <code>python</code> 命令了,试一下:</p>
<pre><code class="language-shell"> dbnuo@localhost~python -V
Python 3.8.2
</code></pre>
<p>完整的示例,可以查看我的 GitHub 项目: BNDong/dnmp</p><br><br>
来源:https://www.cnblogs.com/bndong/p/12530507.html
頁: [1]
查看完整版本: Docker 容器化部署 Python 应用