title: docker-Dockerfile通用模板
date: 2022-04-22 09:38:19
tags: docker

docker-Dockerfile通用模板

写在前面
作为工程人员,每次都需要进行环境隔离。常见的环境隔离有conda管理环境,另一种就是docker。docker有个很好的特点就是,移植性很好,不会因为环境变量等原因出错。

image常用指令

拉取所需镜像

docker pull
下面的例子将从 Docker Hub 仓库下载一个 Ubuntu 12.04 操作系统的镜像。

拉取所需镜像
docker pull ubuntu:12.04

有时候官方仓库注册服务器下载较慢,可以从其他仓库下载。 从其它仓库下载时需要指定完整的仓库注册服务器地址。例如

docker pull dl.dockerpool.com:500/ubuntu:12.04
列出本地镜像

使用 docker images 显示本地已有的镜像。

docker images

REPOSITORY            TAG                               IMAGE ID       CREATED         SIZE
qoe_audio_service     v1.0.0                            3b1b4fcd171b   3 months ago    16.3GB
nvidia/cuda           11.1.1-cudnn8-devel-ubuntu18.04   cab9d5b66568   3 months ago    9.35GB
nvidia/cuda           11.2.0-cudnn8-devel-ubuntu20.04   066cd50b3e02   3 months ago    6.91GB
nvidia/cuda           10.1-cudnn7-devel-ubuntu16.04     1278371227f7   3 months ago    3.68GB
nvidia/cuda           9.0-cudnn7-devel-ubuntu16.04      b13c2165c94f   3 months ago    2.45GB
ufoym/deepo           latest                            148368bde324   3 months ago    19.5GB
qiniudora/dora-ship   v3                                dad729dae6d2   5 months ago    4.57GB
pytorch/pytorch       1.10.0-cuda11.3-cudnn8-devel      46961cbf2ac7   6 months ago    14.4GB
vistart/mmdetection   latest                            085dad9cd4b0   21 months ago   6.6GB

在列出的信息中,可以看到几个字段信息

  • 来自于那个仓库,比如nvidia
  • 镜像的标记,比如v1.0.0 latest
  • 镜像ID号(唯一)
  • 创建时间
  • 镜像大小

启动镜像

python docker run -it qoe_audio_service:v1.0.0 /bin/bash
如果不指定具体的标记,则默认使用 latest 标记信息。

修改已有的镜像

先用下载的镜像启动容器或者进入一个需要修改的容器,
python docker run -it qoe_audio_service:v1.0.0 /bin/bash or docker exec -it 14d22e06dded /bin/bash
修改容器
在容器中添加 json 和 gem 两个应用。

root@14d22e06dded:/# gem install json

当结束后,我们使用 exit 来退出,现在我们的容器已经被我们改变了,使用 docker commit 命令来提交更新后的副本。

docker commit -m 'add json' -a 'paul' 14d22e06dded vistart/mmdetection:v1.0.1

其中,-m来指定提交的说明信息;-a可以指定更新人的信息;后面是容器ID;最后指定目标镜像的仓库名和tag信息。创建成功会返回这个镜像的ID.后面正常docker run该镜像即可。

利用Dockerfile来创建镜像

首先创建一个Dockerfile,包含一些创建镜像的指令;使用docker build来创建新的镜像。
创建一个目录和一个Dockerfile,该目录包含你的代码和需要的文件。

.
├── client.py
├── Dockerfile
├── README.md
└── service

Dockerfile中每一条指令都创建镜像的一层,所以为了避免镜像过于复杂,占得内存过大,一般尽量减少层多行命令用&写一起。

# Dockerfile
FROM ubuntu:14.04
RUN apt-get -qq upddate
RUN apt-get install vim
docker file命令
FROOM 指定基础镜像,必须为第一个命令
格式:
    FROM <image>
示例:
    FROM python:3.6
注:
    tag是可选的,如果不选定tag,会使用latest版本的基础镜像
RUN 构建镜像时执行命令
#shell 执行
格式:
    RUN <command>
示例:
    RUN pip install easydict
注:
    RUN指令创建的中间镜像会被缓存,并会在下次构建时使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数
ADD

将文件添加到容器中,tar类型文件会自动解压,可以访问网络资源,如wget等

格式
    ADD <src> <dst>
示例:
    ADD ./Yolov5_DeepSort_Pytorch_ship /yolov5ship
COPY

功能类似ADD,但是不会自动解压文件,也不能访问网络资源

ENV

设置环境变量

格式:
    ENV <key><value> #<key>之后的所有内容俊辉被视为<value>的组成部分,因此,一次只能设置一个便令
示例:
    ENV WORKPATH="/workspace"
    ENV myName John
WORKDIR

工作目录,类似于cd命令,chdir()

格式:
    WORKDIR /path/to/workdir
示例:
    WORKDIR /a(这时工作目录为/a)
    WORKDIR b (这时从a切换到b了,/a/b)
注:
    通过WORKDIR设置工作目录后,Dockfile中其后面的命令RUN、CMD、ADD、COPY等命令都会在该目录下执行。
USER

指定容器运行时的用户名或UID

格式:
    USER user
示例:
    USER root
CMD

构建镜像后调用,也是在容器启动时才调用

格式
    CMD "python" "/yolov5ship/track_vv.py"
注意: 
    CMD不同于RUN, CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时才执行的命令

Dockerfile 模板

# base docker image
FROM anibali/pytorch:1.8.1-cuda11.1-ubuntu20.04

# Set up time zone.
ENV TZ=UTC
RUN sudo ln -snf /usr/share/zoneinfo/$TZ /etc/localtime

# Install system libraries required by OpenCV.
RUN sudo apt-get update \
 && sudo apt-get install -y libgl1-mesa-glx libgtk2.0-0 libsm6 libxext6 \
 && sudo rm -rf /var/lib/apt/lists/*

# 安装python程序运行程序的所有依赖
RUN python -m pip install --upgrade --no-cache-dir --ignore-installed -i https://mirrors.aliyun.com/pypi/simple \
    flask==0.12.2 \

RUN python -m pip install --upgrade --no-cache-dir --ignore-installed --no-deps -i https://mirrors.aliyun.com/pypi/simple timm==0.3.2 

USER root
ENV WORKPATH="/workspace"
ENV DEVICE="cuda:0"
ENV LC_ALL=C.UTF-8 \
    LANG=C.UTF-8 

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo 'Asia/Shanghai' > /etc/timezone

# 创建工作目录    
RUN sudo mkdir -p ${WORKPATH}

# 将当前路径的文件复制到容器内对应的目录下
COPY ./ ${WORKPATH}

# 切换到工作目录
WORKDIR ${WORKPATH}

# 进入服务代码所在的路径    
WORKDIR ${WORKPATH}/service
# 通过gunicorn启动服务
CMD gunicorn -c gunicorn.conf.py --log-config log.conf app:app