- 首页
- 正文
Dockfile创建自定义镜像及数据卷的应用
能够使用Dockfile创建自定义镜像及数据卷的应用,就已经可以搭建一些的简单的服务了,下面先说一下概念的东西,然后再举一些例子,在上一篇文章说过,镜像是容器的基础,每次执行 docker run 的时候都会指定哪个镜像作为容器运行的基础。但是从 Docker Hub 里下载的镜像不一定满足我们的需求,这里我们就可以以已经有的镜像为基础来构建新的镜像,构建新的镜像有两种方法:
可以使用 docker commit 来构建新的镜像( 不建议这样做 )
镜像是多层存储,每一层是在前一层的基础上进行的修改;而容器同样也是多层存储,是在以镜像为基础层,在其基础上加一层作为容器运行时的存储层,所以我们可以修改容器的里面的内容,然后利用 docker commit 命令构建一个新的镜像,下面是一个简单的例子:
进入到 ubuntu 容器的命令行
docker run --name vimserver -it ubuntu /bin/bash
安装 vim
apt-get update
apt-get install -y vim
构建新的镜像
可以利用 docker commit 命令在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像,格式如下:
docker commit [选项] <容器ID或容器名> [<仓库名>[:<标签>]]
在这个例子里,我们把安装了 vim 的容器保存为镜像,命令如下:
docker commit --author "admin@163.com" --message "添加了vim" vimserver dockertest/ubuntu_vim
注意:
dockertest 是已经注册仓库的用户名
可以使用 docker images
来查看是否已经生成了一个 dockertest/ubuntu_vim 的镜像
使用新的镜像
先清除之前已经运行的容器
docker stop $(docker ps -a -q)
docker container prune
再运行新的镜像
docker run --name vimserver -it dockertest/ubuntu_vim /bin/bash
在命令里运行 vim,看是不是已经成功了
慎用 docker commit
使用 docker commit 命令虽然可以比较直观的帮助理解镜像分层存储的概念,但是实际环境中并不会这样使用。使用 docker commit 意味着所有对镜像的操作都是黑箱操作,生成的镜像也被称为黑箱镜像,换句话说,就是除了制作镜像的人知道执行过什么命令、怎么生成的镜像,别人根本无从得知。而且,即使是这个制作镜像的人,过一段时间后也无法记清具体在操作的,所以最好是使用 Dockerfile 来构建新的镜像
使用 Dockerfile 来构建新的镜像
1. 使用 Dockerfile 文件来构建镜像,下面是一些常用指令:
FROM
这个指令主要是指定基础镜像,在 Dockerfile
中 FROM
是必备的指令,并且必须是 第一条指令
。
常用的基础镜像有:
- nginx
- redis
- mongo
- mysql
- httpd
- php
- tomcat
- python
- ruby
- ubuntu
- debian
- centos
- fedora
- alpine
RUN
RUN指令是用来执行命令行的,有两种写法:
RUN <命令>
RUN ["可执行命令", "参数1", "参数2"]
CMD
CMD跟RUN指令差不多,也有两种写法:
CMD <命令>
CMD ["可执行命令", "参数1", "参数2"]
COPY
COPY指令是用来复制文件的,有两个写法:
COPY <源路径>... <目标路径>
COPY ["<源路径1>",... "<目标路径>"]
ADD
ADD是用来添加文件的,其实跟COPY差不多的,但是在添加压缩文件时,需要添加文件的同时还能自动解压缩
的,就要用 ADD
指令,格式为:
- ADD <源路径>... <目标路径>
ENTRYPOINT
ENTRYPOINT指令指定容器启动程序及参数,格式为:
ENTRYPOINT <命令>
ENV
ENV用来设置环境变量,格式有两种:
ENV <变量名> <变量值>
ENV <变量名1>=<变量值1> <变量名2>=<变量值2>...
VOLUME
VOLUME 定义匿名卷,格式为:
- VOLUME ["<路径1>", "<路径2>"...]
- VOLUME <路径>
EXPOSE
格式为 EXPOSE <端口1> [<端口2>...]
EXPOSE 指令是声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务
要将 EXPOSE 和在运行时使用 -p <宿主端口>:<容器端口> 区分开来。-p,是映射宿主端口和容器端口,换句话说,就是将容器的对应端口服务公开给外界访问,而 EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会自动在宿主进行端口映射
WORKDIR
WORKDIR 指定工作目录,格式为 WORKDIR <工作目录路径>。
使用 WORKDIR 指令可以来指定工作目录(或者称为当前目录),以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。
USER
USER 指定当前用户,格式:USER <用户名>
2. 使用Dockerfile构建gunicorn运行flask
第一步
新建目录
cd /home
mkdir -p gunicorn_demo/flask_demo
第二步
在 gunicorn_demo 目录下建立 Dockerfile 文件,内容如下
FROM ubuntu
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
RUN apt-get update && apt-get -y install python-pip \
&& pip install flask \
&& pip install gunicorn
ADD gunicorn.py /gunicorn.py
EXPOSE 8000
ENTRYPOINT ["/usr/local/bin/gunicorn", "--config", "/gunicorn.py"]
CMD ["app:app"]
第三步
在 gunicorn_demo 目录下新建一个 gunicorn.py 文件,内容如下
bind = '0.0.0.0:8000'
chdir = '/flask_demo'
workers = 2
第四步
在 flask_demo 目录下新建 app.py 文件,内容如下
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run()
第四步
开始构建镜像
cd /home/gunicorn_demo
docker build -t="dockertest/ubuntu_gunicorn" .
这时用 docker images
命令可以的看到 dockertest/ubuntu_gunicorn
镜像了
测试镜像
可以使用下面命令运行镜像,把 本地的flask_demo目录
挂载到 容器的flask_demo目录
docker run --name webserver -v /home/gunicorn_demo/flask_demo:/flask_demo -p 8000:8000 -d docker1314/gunicorn_demo
在浏览器上运行 localhost:8000
,应该可以看到效果了
数据卷
数据卷的几个特性:
数据卷可以在容器之间共享和重用
对数据卷的修改会立马生效
对数据卷的更新,不会影响镜像
数据卷默认会一直存在,即使容器被删除
举例
使用 v 参数,把本地的目录挂载到容器的目录里
docker run -it --name -v /home/docker/test:/test webserver ubuntu /bin/bash
使用 mount 参数,把本地的目录挂载到容器的目录里
docker run -it --name webserver --mount type=bind,source=/home/docker/test,target=/test ubuntu /bin/bash
【上一篇】docker的基础知识及安装
【下一篇】Docker Compose的用法