Dockerfile
定义
Dockerfile类似于我们学习过的脚本,将我们在上面学到的docker镜像,使用自动化的方式实现出来。
作用
- 找一个镜像: ubuntu
- 创建一个容器: docker run ubuntu
- 进入容器: docker exec -it 容器 命令
- 操作: 各种应用配置
- ...
- 构建新的镜像
Dockerfile 使用准则
记得网上有一个最佳实践,可以🔍搜索一下。
- 大:首字符必须大写
- 空:尽量将 Dockerfile 放在空目录中
- 单: 每个容器尽量只有一个功能
- 少: 执行的命令越少越好
Dockerfile 基础四指令
- 基础镜像信息: 从哪里来
- 维护者信息: 我是谁
- 镜像操作指令: 怎么干
- 容器启动时执行指令: 嗨 !!!
Dockerfile 使用命令
构建镜像命令格式:
docker build -t [镜像名]:[版本号] [Dockerfile所在目录]
构建样例:
docker build -t nginx:v0.2 /opt/dockerfile/nginx/
- -t: 指定构建之后的镜像信息
- /opt/dockerfile/nginx/ 代表 Dockerfile 的存放位置,如果是当前的目录,可以使用 . 表示。
快速入门
准备环境
创建 Dockerfile 专用目录:
创建秘钥认证:
准备软件源:
cp /etc/apt/source.list ./
注意:我们要清除 docker 相关的配置,只留下原始的软件源。 给出一份 source.list 如下:
# 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu/ xenial main main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu/ xenial-security main restricted universe multiverse
# 预发布软件源,不建议启用
# deb http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu/ xenial-proposed main restricted universe multiverse
定制文件
创建 Dockerfile 文件:
# 构建一个基于 ubuntu 的 ssh 定制镜像
# 基础镜像
FROM ubuntu
# 镜像作者
MAINTAINER ruiyang0715@gmail.com
# 执行命令
# 增加软件源
ADD sources.list /etc/apt/sources.list
#安装ssh服务
RUN apt-get update
RUN apt-get install -y openssh-server curl vim net-tools
RUN mkdir -p /var/run/sshd
RUN mkdir -p /root/.ssh
#取消pam限制
RUN sed -i "s/.*pam_loginuid.so/#&/" /etc/pam.d/sshd
RUN apt-get autoclean
RUN apt-get clean
RUN apt-get autoremove
# 复制配置文件到相应位置,并赋予脚本可执行权限
ADD authorized_keys /root/.ssh/authorized_keys
# 对外端口
EXPOSE 22
#启动ssh
ENTRYPOINT ["/usr/sbin/sshd","-D"]
这时候的文件夹如下:
构建镜像:
docker build -t ubuntu-ssh .
使用新镜像启动一个容器,查看效果:
查看端口:
ssh 查看效果:
基础命令详解
FROM
格式:
FROM <image>
FROM <image>:<tag>
解释:
FROM 是 Dockerfile里的第一条而且只能是除了首行注释之外的第一条指令。
MAINTAINER
格式:
MAINTAINER <name>
解释:
指定该 dockerfile 文件的维护者信息。类似我们在 docker commit 时候使用-a 参数指定的信息
RUN
格式:
RUN <command>
RUN["executable", "param1", "param2"]
解释: shell模式:类似于 /bin/bash-ccommand 举例: RUN echo hello exec 模式:类似于 RUN ["/bin/bash", "-c", "command"] 举例: RUN ["echo", "hello"]
EXPOSE
格式:
EXPOSE <port> [<port>...]
解释: 设置 Docker 容器对外暴露的端口号,Docker 为了安全,不会自动对外打开端口,如果需要外部提供访问,还需要启动容 器时增加-p 或者-P 参数对容器的端口进行分配。
ENTRYPOINT
格式:
ENTRYPOINT ["executable", "param1","param2"] (exec 模式)
ENTRYPOINT command param1 param2 (shell 模式)
解释: 每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。
文件编辑指令详解
ADD
格式:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"]
解释:
- 将指定的 文件复制到容器文件系统中的
- src 指的是宿主机,dest 指的是容器
- 如果源文件是个压缩文件,则 docker 会自动帮解压到指定的容器中(无论目标是文件还是目录,都会当成目录处理)
COPY
格式:
COPY <src>... <dest>
COPY ["<src>",... "<dest>"]
解释: 单纯复制文件场景,Docker 推荐使用 COPY
VOLUME
格式:
VOLUME ["/data"]
解释:
- VOLUME 指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点
- 通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。 举例: VOLUME ["/var/lib/tomcat7/webapps/"]
- 参考: segmentfault.com/q/101000000…
实践
首先在当前目录下面创建一个用于测试的压缩文件:
然后创建一个测试的单个文件 index.html
在 Dockerfile 中添加拷贝文件的命令:
# 构建一个基于 ubuntu 的 ssh 定制镜像
# 基础镜像
FROM ubuntu
# 镜像作者
MAINTAINER ruiyang0715@gmail.com
# 执行命令
# 增加软件源
ADD sources.list /etc/apt/sources.list
#安装ssh服务
RUN apt-get update
RUN apt-get install -y openssh-server curl vim net-tools
RUN mkdir -p /var/run/sshd
RUN mkdir -p /root/.ssh
#取消pam限制
RUN sed -i "s/.*pam_loginuid.so/#&/" /etc/pam.d/sshd
RUN apt-get autoclean
RUN apt-get clean
RUN apt-get autoremove
# 复制配置文件到相应位置,并赋予脚本可执行权限
ADD authorized_keys /root/.ssh/authorized_keys
# 增加文件
ADD ["sources.list","/etc/apt/sources.list"]
# 增加压缩文件
ADD ["hello.tar.gz", "/hello/"]
# 使用 COPY 增加一个文件
RUN mkdir -p /var/www/html
COPY index.html /var/www/html/
# 在容器中创建一个挂载点
VOLUME ['/data/']
# 对外端口
EXPOSE 22
#启动ssh
ENTRYPOINT ["/usr/sbin/sshd","-D"]
环境指令详解
ENV 环境设置指令
格式:
ENV <key> <value>
ENV <key>=<value> ...
解释: 设置环境变量,可以在 RUN 之前使用,然后 RUN 命令时调用,容器启动时这些环境变量都会被指定。
WORKDIR
格式:
WORKDIR /path/to/workdir (shell 模式)
解释: 切换目录,为后续的 RUN、CMD、ENTRYPOINT 指令配置工作目录。 相当于 cd 可以多次切换(相当于 cd 命令),也可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径
举例:
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
则最终路径为 /a/b/c。
ENV 实践
在上一个Dockerfile的基础上,在 RUN 下面加一个ENV 如下:
ENV NAME=furuiyang
Dockerfile:
# 基础镜像
FROM ubuntu
# 镜像作者
MAINTAINER ruiyang0715@gmail.com
# 增加软件源
ADD sources.list /etc/apt/sources.list
# 安装ssh服务
RUN apt-get update
RUN apt-get install -y openssh-server curl vim net-tools
RUN mkdir -p /var/run/sshd
RUN mkdir -p /root/.ssh
# 取消pam限制
RUN sed -i "s/.*pam_loginuid.so/#&/" /etc/pam.d/sshd
RUN apt-get autoclean
RUN apt-get clean
RUN apt-get autoremove
# 设置环境变量
ENV NAME=furuiyang
# 复制配置文件到相应位置,并赋予脚本可执行权限
ADD authorized_keys /root/.ssh/authorized_keys
# 增加文件
ADD ["sources.list","/etc/apt/sources.list"]
# 对外端口
EXPOSE 22
# 启动ssh
ENTRYPOINT ["/usr/sbin/sshd","-D"]
重新生成镜像,开启容器运行:
docker build -t ubuntu-ssh .
docker run -d -p 10086:22 ubuntu-ssh
ssh 172.18.222.137 -p 10086
进入使用 env 命令查看环境变量是否被设置上。
(这里有个问题就是我ssh进入就没有但是exec进入才可看到被设置的 NAME 环境变量)
Dockerfile 的构建过程
- 从基础镜像 1 运行一个容器 A
- 遇到一条 Dockerfile 指令,就对容器 A 进行一次修改
- 执行完一条命令,提交生成一个新镜像 2
- 再基于新的镜像 2 运行一个容器 B
- 遇到一条 Dockerfile 的指令,都对容器进行一次修改操作
- 执行完一条指令,提交生成一个新镜像 3
- ...
构建过程中的镜像介绍
构建过程中,创建了很多镜像,这些中间镜像,我们可以直接使用来启动容器,通过查看容器效果,从侧面能看到我们每次构建的效果。提供了镜像调试的能力
我们可以通过docker history <镜像名> 来查看整个构建过程所产生的镜像
查看 ubuntu-ssh 的整个构建过程中创建的镜像:
使用中间镜像来启动容器:
docker run -d -p 10087:22 0ca50222ff8c
拓展: 执行的步骤越多越好呢?还是越少越好?
构建缓存
我们的第一次构建会很慢,但是之后的构建都会变快,因为利用到了构建的缓存。
不使用构建缓存的两种做法: 全部不用缓存:
docker build --no-cache -t [镜像名]:[镜像版本] [Dockerfile位置]
部分使用缓存:在 Dockerfile 中使用
# 创建构建刷新时间
ENV REFRESH_DATE 2019-08-30
只要构建的时间不变,那么就用缓存,时间一旦改变,就不用缓存了。
查看构建过程的历史:
docker history [镜像名]
清理构建缓存:
docker system prune
docker system prune --volumes
使用 Dockfile 构建 Django 环境 (FIXME)
技术关键点:
- docker环境部署:
- 使用docker镜像启动一个容器即可
- django环境部署
- django软件的依赖环境
- django软件的基本环境配置
- django项目部署
- django框架的下载
- 项目文件配置
- 启动django项目
- 测试
- 宿主机测试
流程:
docker 环境配置
- 获取 docker 镜像,这里就使用前面创建的 ubuntu-ssh 镜像
docker run -d -p 10086:22 --name django ubuntu-ssh
- 进入容器: (可以使用 ssh ip -p 10086 的形式进入) 因为 MacOs开启了连接保护,所以我使用 exec 进入
docker 环境部署
# mkdir /data/{server,softs} -p
# cd data/softs
# scp root@192.168.8.14:/data/softs/Django-2.1.2.tar.gz ./
注: scp 适用于 ssh 连接方式。若使用 exec 模式,可以在启动容器的时候 使用 -v 将项目文件挂载进来。 (TODO)
安装基本的依赖软件:
apt-get install python3-pip python-dev build-essential -y
安装 Django 软件:
cd /data/softs
tar xf Django-2.1.2.tar.gz cd Django-2.1.2
python3 setup.py install
Django 项目部署
略
项目启动
设置访问主机:
# vim itcast/settings.py
...
ALLOWED_HOSTS = ['*']
启动项目:
python3 manage.py runserver 172.17.0.2:8000
注意: 要提前使用 ifconfig 来检查一下当前容器的 ip,以方便接下来的测试。
测试
在宿主机, 查看容器的ip地址
docker inspect django
浏览器、或curl查看效果:
172.17.0.2:8000/hello/
这一章节需要后续修改完善,实际的部署不完全是这样的,只是一个部署的初级版本。