image 文件
Docker 把应用程序及其依赖,打包在 image 文件里面。 只有通过这个文件,才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。
image 是二进制文件。实际开发中,一个 image 文件往往通过继承另一个 image 文件,加上一些个性化设置而生成。举例来说,你可以在 Ubuntu 的 image 基础上,往里面加入 Apache 服务器,形成你的 image
image 文件是通用的,一台机器的 image 文件拷贝到另一台机器,照样可以使用。一般来说,为了节省时间,我们应该尽量使用别人制作好的 image 文件,而不是自己制作。即使要定制,也应该基于别人的 image 文件进行加工,而不是从零开始制作
docker image pull library/hello-world
上面代码中,docker image pull是抓取 image 文件的命令。library/hello-world是 image 文件在仓库里面的位置,其中library是 image 文件所在的组,hello-world是 image 文件的名字
由于 Docker 官方提供的 image 文件,都放在library组里面,所以它的是默认组,可以省略。因此,上面的命令可以写成下面这样
docker image pull hello-world
// 列出本机的所有 image 文件。
docker image ls 或 docker images
// 删除 image 文件 (在容器中运行的镜像无法被删除,需先删除容器再删除镜像)
docker image rm [imageName] 或 docker rmi [imageName/IMAGE ID]
镜像的导入导出(不规范)
// 将本地镜像导出
docker save -o 导出的路径 镜像id
// 加载本地的镜像文件
docker load -i 镜像文件
修改镜像名称 docker tag 镜像id 新镜像名称:版本
现在,运行这个 image 文件
docker container run hello-world
如果运行成功,你会在屏幕上读到下面的输出
$ docker container run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
... ...
输出这段提示以后,hello world就会停止运行,容器自动终止。
有些容器不会自动终止,因为提供的是服务。比如,安装运行 Ubuntu 的 image,就可以在命令行体验 Ubuntu 系统
docker container run -it ubuntu bash
# 对于那些不会自动终止的容器,必须使用docker container kill 命令手动终止
docker container kill [containID]
容器文件
image 文件生成的容器实例,本身也是一个文件,称为容器文件。 也就是说,一旦容器生成,就会同时存在两个文件: image 文件和容器文件。而且关闭容器并不会删除容器文件,只是容器停止运行而已
# 列出本机正在运行的容器
docker container ls
# 列出本机所有容器,包括终止运行的容器
docker container ls --all
上面命令的输出结果之中,包括容器的 ID。很多地方都需要提供这个 ID,比如上一节终止容器运行的docker container kill命令。
终止运行的容器文件,依然会占据硬盘空间,可以使用docker container rm命令删除
docker container rm [containerID]
运行上面的命令之后,再使用docker container ls --all命令,就会发现被删除的容器文件已经消失了
容器的管理
-
运行容器
简单操作
docker run 镜像的标识镜像名称[:tag] -
常用参数
docker run -d -p 宿主机端口:容器端口 --name 容器名称 镜像的表示镜像名称[:tag]-d:代表后台运行容器-p 宿主机端口:容器端口: 为了映射当前linux的端口和容器的端口--name 容器名称: 指定容器的名称
-
查看正在运行的容器
docker ps [-qa]-a:查看全部的容器,包括没有运行的-q:只查看容器的标识
-
查看容器日志
docker logs -f 容器id-f:可以滚动查看日志的最后几行
-
进入到容器内部
docker exec -it 容器id bash -
删除容器(删除前,需要先停止容器运行)
// 启动容器 docker start 容器ID // 停止指定的容器 docker stop 容器ID // 停止全部容器 docker stop $(docker ps -qa) // 重启容器 docker restart 容器ID // 删除指定容器 docker rm 容器ID // 删除全部容器 docker rm $(docker ps -qa)
[常见的应用场景]
1.快速部署 2.隔离应用 3.提高开发效率 4.版本控制
docker数据卷
将宿主机的一个目录映射到容器的一个目录中,可以在宿主机中操作目录中的内容,容器内部映射的问价也会一起改变
1.创建数据卷
docker volume create 数据卷名称创建数据卷之后,默认会存放在一个目录下
/var/lib/docker/volumes/数据卷名称/_data2.查看数据卷的详细信息
docker volume inspect 数据卷名称
查看全部数据卷
docker volume ls删除数据卷
docker volume rm 数据卷名称应用数据卷
当你映射数据卷时,如果数据卷不存在Docker会帮你自动创建,会将容器内部自带的文件存储在默认的存放路径中
docker run -v 数据卷名称:容器内部的路径 镜像ID // 直接指定一个路径作为数据卷的存放位置。这个路径下是空的 (推荐) docker run -v 路径:容器内部的路径 镜像ID
docker命令
docker --version //查看版本
docker ps //查看正在运行的容器状态 -a 参数来查看所有的已经运行的容器(无论是否停止)
docker run //创建一个新的容器并运行一个命令
docker exec // 进入容器里面
-it // 提供交互式终端
-d //让镜像容器在后台去持续运行
--name //指定容器的名称
-p // 容器内部端口映射到主机的端口
-v // 挂载宿主机的文件目录到镜像里面去
-e //设置环境变量
例子
// 运行容器
docker run -it -d --name test ubuntu
// 进入容器
docker exec -it test /bin/bash
// 把本机的Downloads文件映射到ubuntu的home文件下
docker run -v ~/Downloads/:home -itd --name test1 ubuntu
Dockerfile
一般,Dockerfile 共包括四部分:
-
基础镜像信息
-
维护者信息
-
镜像操作指令
-
容器启动时执行指令
Dockerfile示例:
# nginx Dockerfiel # version 1.0 # Base images 基础镜像 FROM centos # MAINTAINER 维护者信息 MAINTAINER fall # ENV 设置环境变量 ENV PATH /usr/local/nginx/sbin:$PATH # ADD 文件放在当前目录下,拷过去自动解压 ADD nginx-1.8.0.tar.gz /usr/local/ ADD epel-release-latest-7.noarch.rpm /usr/local/ # 企业linux扩展包 # RUN 执行一下命令 RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all RUN useradd -s /sbin/nologin -M www # WORKDIR 设置工作目录 WORKDIR /uer/local/nginx-1.8.0 RUN ./configuer --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install RUN echo "daemo off;" >> /etc/nginx.conf # EXPOSE 映射端口暴露 EXPOSE 80 # CMD 运行以下命令 CMD ["nginx"]FROM node:10 LABEL maintainer=atiedan666666@163.com # 创建 app 目录 WORKDIR /app # 把 package.json,package-lock.json(npm@5+) 或 yarn.lock 复制到工作目录(相对路径) COPY ["package.json","*.lock","./"] # 打包 app 源码 # 特别注意:要指定工作目录中的文件名 COPY src ./src # 使用.dockerignore文件,上面两个COPY合并成一个 # COPY . . # 使用Yarn安装 app 依赖 # 如果你需要构建生产环境下的代码,请使用: # --prod参数 RUN yarn --prod --registry=https://registry.npm.taobao.org # 对外暴露端口 -p 4000:3000 EXPONSE 3000 CMD ["node", "src/index.js"]FROM:指定基础镜像,必须为第一个命令;
#格式: FROM <image> FROM <image>:<tag> FROM <image>@<digest> #示例: FROM mysql:5.6 # tag或digest是可选的,如果不使用这2个值,会使用latest版本的基础版本MAINTAINER:维护者信息
#格式: MAINTAINER <name> #示例: MAINTAINER jack li MAINTAINER jackgmail.com MAINTAINER jack li <jackgmail.com>RUN:构建镜像时执行的命令
# shell执行 #格式:RUN <command> # exec执行 #格式:RUN ["executable", "param1", "params2"] # 示例: RUN ["executable", "param1", "param2"] RUN apk update RUn ["/ect/exedile", "arg1", "arg2"] # RUN命令创建的中间镜像会被缓存,并在下次构件中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cacheADD:将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网路资源,类似wget
# 格式 ADD <src>... <dest> ADD ["<src>",... "<dest>"] 用于支持包含空格的路径 # 示例: ADD home* /mydir/ # 添加所有以“home“开头的文件 ADD hom?.txt /mydir/ # ?替代一个字符,如home.txt ADD test relativeDir/ # 添加”test“到”WORKDIR /relativeDir/ ADD test /absoluteDir/ # 添加“test”到/adsoluteDir/COPY:功能类似ADD,但是是不会自动解压文件,也不能访问网络资源CMD:构建容器后调用,也就是在容器启动时才进行调用
# 格式: CMD ["executable", "param1", "param2"] #执行可执行文件,优先 CMD ["param1", "param2"] # 设置ENTRYPOINT,则直接调用ENTRYPOINT添加参数 CMD command param1 param2 # 执行shell内部命令 # 示例: CMD echo "this is a test" | wc - CMD ["/usr/bin/wc", "--help"]ENTRYPOINT: 配置容器,使其可执行化。配合CMD可省区"application",只使用参数
# 格式: ENTRYPOINT ["executable", "param1", "param2"] # 可执行文件,优先 ENTRYPOINT command param1 param2 # shell内部命令 # 示例: FROM ubuntu ENTRYPOINT ["top", "-b"] CMD ["-c"] # 注:ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,而docker run命令中指定的任何参数都会被当作参数再次传递给ENTRYPOINT。Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置只执行最后的ENTRYPOINTLABEL: 用于为镜像添加元数据
# 格式: LABEL <key>=<value> <ke>=<value> <key>=<value> # 示例: LABEL version="1.0" description="web server" by="lionL"ENV:设置环境变量
# 格式: ENV <key> <value> # <key>之后所有内容均会被视为其value的组成部分,故一次只能设置一个变量 ENV <key>=<value>... #可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如过<key>中包含空格使用\进行转义,也可通过""来进行标示;另外,反斜线也可以用来续行 # 示例: ENV myName Jhon Doe ENV myDog Rex The Dog ENV myCat=tomEXPOSE:指定与外界交互的端口
# 格式: EXPOSE <port> [<port>....] # 示例: EXPOSE 80 443 EXPOSE 8080 EXPOSE 11211/tcp 11211/udp # 注:EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过该-p参数来发布EXPOSE导出的所有端口VOLUME: 用于指定持久化目录
# 格式: VOLUME ["/path/to/dir"] # 示例: VOLUME ["/data"] VOLUME ["/var/www", "/var/log/apache1", "var/log/apache2"] # 注:一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件类型,并具有以下功能: 1 卷可以容器间共享和重用 2 容器并不一定要和其他容器共享卷 3 修改卷后会立即生效 4 对卷的修改不会对镜像产生影响 5 卷会一直存在,直到没有任何容器在使用它WORKDIR:工作目录,类似于cd命令
# 格式: WORKDIR /path/to/workdir # 示例: WORKDIR /a #这时工作目录为/a WORKDIR b #这时工作目录为/a/b WORKDIR c #这时工作目录为 /a/b/c # 注:通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY等命令都会在该目录下执行。使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录USER:指定运行容器时的用户名或UID,后续的RUN也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或者两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户
# 格式: USER user USER user:group USER uid USER uid:gid USER user:gid USER uid:group # 示例: USER www # 注:使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户ARG: 用于指定传递给构建运行时的变量
# 格式: ARG <name>[=<default value>] # 示例: ARG site ARG build_user=wwwONBUILD: 用于设置镜像触发器
# 格式: ONBUILD [INSTRUCTION] # 示例: ONBUILD ADD . /app/src ONBUILD RUN /usr/loacl/bin/python-build --dir /app/src # 注:当构建的镜像被用作其他镜像的基础镜像,该镜像中的触发器将会被触发本地生成node应用
- 一个简单的Koa应用:
const Koa = require('koa'); const app = new Koa(); // response app.use(ctx => { ctx.body = 'Hello Koa!!'; }); app.listen(3000);打包镜像 使用
docker build打包:docker build -t ${your_name}/${image_name}:${tag} .docker build命令用于从Dockerfile构建镜像,可以在增加-f指向文件系统中任意位置的Dockerfiledocker build -f /path/to/a/Dockerfile这里的
your_name代表的是远程仓库中的用户名,或者仓库地址;image_name为镜像名称,tag是给镜像打的标签,用于版本控制。.代表当前目录例如:docker build -t zyq/node-demo:1.0 . # docker build -t 镜像名称[:tag]使用镜像
docker run -d --name nodedemo -p 4000:3000 zyq/node-demo:1.0
Docker-compose
通过 Docker-Compose 用户可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题
Compose 中有两个重要的概念:
- 服务(service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例
- 项目(project): 由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义
Docker Compose 是 Docker 的独立产品,因此需要安装 Docker 之后在单独安装 Docker Compose
#下载
sudo curl -L https://github.com/docker/compose/releases/download/1.20.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
#安装
chmod +x /usr/local/bin/docker-compose
#查看版本
docker-compose --version
使用
docker-compose.yml改写:
version: '3.8'
services:
mysql: # 服务的名称
restart: always # 代表只要Docker启动,那么这个容器就跟着一起启动
image: daocloud.io/library/mysql:5.7.4 # 指定镜像路径 #
container_name: test_mysql # 指定容器名称
ports:
- 8001:3306 # 指定端口映射
environment:
MYSQL_ROOT_PASSWORD: 123456 # 指定mysql的root用户登录密码
TZ: Asia/Shanghai # 指定时区
volumes:
- /opt/docker_mysql-tomcat/mysql_data:/var/lib/mysql # 映射数据卷
tomcat:
restart: always
image: daocloud.io/library/tomcat:8.5.15-jre8
container_name: tomcat
ports:
- 8080:8080
environment:
TZ: Asiz/Shanghai
volumes:
- home/tomcat_webapps:/usr/loacl/tomcat/webaps
- home/tomcat_logs:/usr/local/tomcat/logs
在此文件的当前目录下,使用docker-compose up -d来执行
关闭并删除容器docker-compose down
查看docker-compose维护的容器 docker-compose pse
查看日志 docker-compose logs -f
生命周期管理:
- 创建:run/up
- 启动/停止/删除/重启:start/stop/rm/restart
- 捡视/日志: logs/ps
docker-compose结合Dockerfile使用
version: '3.8'
services:
web-demo:
restart: always
build: # 构建自定义镜像
context: ../ # 指定Dockerfile文件所在路径
dockerfile: Dockerfile # 指定Dockerfile文件名称
image: demo:1.0
container_name: demo
ports:
8081:8080
environment:
TZ: Asia/Shanghai
Dockerfile
FROM daocloud.io/library/tomcat:8.5.15-jre8
COPY demo.war /usr/local/tomcat/webapps
应用
搭建本地mongo + mongo-express服务
# docker-compose.mongo.yml配置文件
version: '3.1'
services:
mongo:
image:mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INTIDB_ROOT_PASSWORD: 13456
mongo-express:
image: mongo-express
restart: always
ports:
- 8081:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWARD: 123456
执行:
# 执行 docker-compose.mongo.yml 如果不加 docker-compose -f 默认执行 docker-compose.mongo.yml
docker-compose -f docer-compose.mongo.yml up -d