基本命令
概念
- image 镜像, 可用于生成容器,或者作为其他镜像的源
- container 容器,镜像的实例
run
启动一个容器运行镜像
docker run -d -p 80:80 docker/someservice
运行最后名字的服务
docker run -dp 3001:3001 -w /usr/local/app blog-server npm run dev
运行node程序
基本选项:
- -d 后台运行(detached)
- -p 端口号映射
- -w 指定工作目录
- -i 交互方式运行(非后台)
- –name 给容器命名
exec
用于在容器中执行某些命令
用法:docker exec -it <container-id> <command>
比如对一个启动的mongo容器,运行docker exec -it 8c26c40cc3e9 mongo
进行连接
基本选项:
- -d 后台运行
- -i 交互方式运行
- -t 启动一个虚拟终端(tty)
- -e 指定环境变量,如:
-e USERNAME=myname \ -e PASSWORD=123456
- -w 指定工作目录
查看日志
docker logs -f <id>
查看某个进程的logs,加上 -f 可以持续监听日志
docker exec -it <container-id> bash
也可以用
停止服务
docker ps
找到container实例的iddocker stop <id>
停止containerdocker rm <id>
删除container; rmi可以删除镜像
查找镜像
docker search <some-program>
查找
镜像名称如node:12-alpine
后面部分是它的tag,基于alpine开发的(一个微型的linux,提供基础功能,大小在5MB左右)
Dockerfile
该文件用来描述一个镜像,运行它可以得到一个镜像
- FROM 源镜像地址
- WORKDIR 工作目录
- COPY 复制目录
- RUN 运行一些命令
- CMD 启动某些程序
- ENV 环境变量
- EXPOSE 暴露的端口号
如:
FROM node:12-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
创建镜像:docker build -t myimage .
最后一个点号表示在当前目录寻找 DOCKERFILE
远程
docker push <username>/<imagename>
推到远程 dockerhub
Play With Docker 站点可以直接访问并使用 dockerhub镜像
卷
创建卷可以将本地文件映射到docker进程
docker volume create <volume-name>
创建卷
docker run -dp 27107:27107 -v <volume-name>:<root-in-docker-program> mongo
链接卷
docker volume inspect <volume-name>
查看卷
也可以更方便地进行直接链接
docker run -dp 3000:3000 -w "$(pwd):/app" node:12-alpine sh -c "yarn install && yarn run dev"
网络
网络用于连接多个不同的容器
创建网络 docker network create my-network
创建mongodb容器,使用创建的网络
docker run -dp 27017:27017 \
--network mongo-net --network-alias mynet \
-v ~/Documents/db/mongo:/data/db \
-e MONGO_INITDB_ROOT_USERNAME=myname \
-e MONGO_INITDB_ROOT_PASSWORD=mypass \
mongo
使用mongodb创建的服务, 注意第六行指定了网络名称
docker run -dp 3001:3001 --name backend-service --network mongo-net \
-w /app \
-v "$(pwd):/app" \
-e MONGO_USR=myname \
-e MONGO_PWD=mypass \
-e MONGO_HOST=mynet \
-e MONGO_DB=myblog \
node:12-alpine \
sh -c "npm install && npm run dev"
Docker-Compose
如果像上面那样一步步地做,比较慢而且容易出错,所以出现了Docker-Compose
用于创建多节点任务。
配置文件: docker-compose.yml
version: "3.7"
services:
app:
image: node:12-alpine
command: sh -c "npm install && npm run dev"
ports:
- 3001:3001
volumes:
- ./:/app
environment:
MONGO_USR: myname
MONGO_PWD: mypass
MONGO_HOST: mon
MONGO_DB: myblog
working_dir: /app
mon:
image: mongo
ports:
- 27017:27017
volumes:
- ~/Documents/db/mongo:/data/db
enviroment:
MONGO_INITDB_ROOT_USERNAME:myname
MONGO_INITDB_ROOT_PASSWORD:mypass
docker不能保证服务启动的先后顺序,需要程序里自行判断
Dockerfile
虽然dockerhub上有用很多功能全面的镜像,但更多的时候我们还是希望能够根据实际场景定制属于自己的镜像,这就需要用到DOCKERFILE
这个文件,它用于创建描述一个镜像,在终端运行docker build <somedir>
命令后,将在文件夹中搜寻DOCKERFILE
文件,并制作一个全新的镜像,本文对DOCKERFILE
的常见选项和用法作一些记录和说明。
FROM
标识源镜像,如果源镜像是Linux推荐使用Alpine作为源镜像,因为其体积较小(5MB)
LABEL
可以用于存储一些镜像的元信息,如description, author, version
等,如:
LABEL maintainer="mumu@qq.com"\
version="1.1.1"\
description="another image"\
"multi.number1"="2df3Gft99"\
"multi.ra1"="234445451"
也可以定义成多条LABEL
语句,但在DOCKERFILE中的每条语句都会生成一个新镜像,把LABEL写在一起可以加快生成镜像。
WORKDIR
设置基准目录地址,COPY, RUN
等命令的根目录,在一个DOCKERFILE中可以使用多次此指令。在运行run
生成容器时可以附加-w
或--workdir
选项来重置它。
USER
设置用户/用户组,如USER root
ADD
COPY
用于复制内容到docker工作目录,常用操作如COPY . /mydir/
,能使用COPY的地方尽量不用 ADD,如果要下载或者解压一些文件,推荐RUN wget
之类的操作,而不是使用ADD添加。
RUN
执行一些命令并生成一个新的镜像,常用于安装一些软件包。
RUN命令,以及之后的CMD和ENTRYPOINT都有两种调用格式,其中shell格式的使用方式类似shell命令,如RUN apt-get install python3
, 另一种cmd格式的调用方式使用json格式的数组:RUN ["apt-get", "install", "python3"]
, 两种方式存在一些差异,如:
ENV name Jone
ENTRYPOINT echo "Hello, $name"
如果运行docker run -it <image>
则打印Hello, Jone
如果使用cmd格式:
ENV name Jone
ENTRYPOINT ["/bin/echo", "Hello, $name"]
则打印的是Hello, $name
, 只有把第二句换成ENTRYPOINT ["/bin/bash", "-c" "echo Hello, $name"]
才能得到预期结果。
使用RUN命令安装软件包:
RUN apt-get update && apt-get install -y npm git
注意这里将update和install放在一层来做,保证安装到最新的软件包。
CMD
设置镜像启动时默认的命令或参数,如果随后docker容器启动时赋予了命令参数,则此处设置的参数不会起作用。如果Dockerfile有多条CMD指令,那么除了最后一条CMD指令外,其余的都将被忽略。
CMD的使用方式也有上文提到的shell格式和cmd格式,但还有一种额外的用法CMD [param1, param2]
其中param1不是可执行程序,这为稍后提到的ENTRYPOINT中的命令提供了额外的参数。
ENTRYPOINT
指定了可执行程序的入口,启动容器即会执行,跟CMD不同的是它指定的命令不会被外界传参取消。ENTRYPOINT的使用也有shell格式和cmd格式,但是两种格式差别较大。
cmd格式经常和CMD命令一起使用,如:
ENTRYPOINT ["/bin/echo", "Hello"]
CMD ["world"]
使用docker run -it <image>
打印Hello world
,执行docker run it <image> Jone
打印Hello jone
使用shell格式,则会忽略掉一切CMD和外部传参。
ENV
设置环境变量ENV abc=123
类似于RUN export abc=123
但是前者无法被unset
取消。
可以在docker run
时传递-e
参数来设置环境变量。
EXPOSE
声明运行容器后暴露的端口,可以使用TCP(默认)/UDP协议,如:EXPOSE 3003
,一个DOCKERFILE可以暴露多个端口,docker run -P
将使用镜像定义的所有端口。
VOLUMN
声明一个或若干个卷,如果docker run
没有指定-v
则宿主机中会创建一个匿名卷,如果run指定--rm
则匿名卷将在container执行结束后销毁。通常的用法还是指定-v
来使用卷。
ARG
制作镜像的参数,可以通过docker build --build-arg user=me
传入。
默认值:ARG user=hong; USER=${dog:-lin}
作用于:ARG的作用于其定义语句之后
传参的例子:
FROM ubuntu
ARG CONT_IMG_VER
ENV CONT_IMG_VER=${CONT_IMG_VER:-v1.0.0}
RUN echo $CONT_IMG_VER
使用须知
FROM, ADD, COPY, RUN
几个指令都会生成新的层(layer),其他指令生成中间容器(intermidiate container),可以通过合并RUN等命令来减小生成镜像的体积。