docker 笔记(基于ubuntu19.10)
安装
$ sudo apt install docker.io
docker 容器使用
-
安装 docker 之后,需要使用 root 权限才能使用 docker 命令,这显然不利于系统的安全性,可以将普通用户添加到 docker 组,之后普通用户才有权限使用 docker 命令:
$ sudo usermod -aG docker [user] # [] 中的user为普通用户名
-
查看所有的容器(包括已经停止的)
$ docker ps -a
-
停止一个容器
$ docker stop <容器 ID/NAME>
-
启动已停止的容器
$ docker start <容器 ID/NAME>
-
进入容器
docker run 使用 -d 参数时,容器启动会进入后台。此时想要进入容器,可通过以下命令:
$ docker exec -it <容器ID/NAME> /bin/bash
-
查看指定 (ID 或者名字)容器的某个确定端口映射到宿主机的端口号
$ docker port <容器ID/NAME>
-
查看 Docker 的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
$ docker inspect <容器ID/NAME>
-
查询最后一次创建的容器:
$ docker ps -l
docker 镜像使用
-
列出本地主机上的镜像
$ docker images
-
查找镜像
$ docker search <镜像名>
-
拉取镜像
$ docker pull <镜像名:tag>
镜像名后不加 tag 的话,会默认拉取 latest ,即最新的镜像。
-
删除镜像
$ docker rmi <镜像名>
Dockerfile
-
FROM 指令
-
RUN 指令
用于执行后面的命令行命令,有以下两种格式:
-
shell 格式
RUN <命令行命令> # <命令行>等同于在终端中的shell命令
-
exec 格式
RUN ["可执行文件", "参数1", "参数2"] # 例如: # RUN ["./test.py", "dev", "offline"] 等价于RUN ./test.py dev offline
Dockerfile 的指令每执行一次都会在 docker 上新建一层
-
-
构建镜像
在 Dockerfile 文件的存放目录下,执行构建动作。
$ docker build -t nginx:test .
上述指令最后一个
.
表示上下文路径,若未说明最后一个参数,则默认上下文路径就是 Dockerfile 所在的位置。 -
COPY 指令
从上下文目录中复制文件或目录到容器中的指定路径。
格式:
COPY [--chown=<user>:<group>] <源路径1>...<目标路径> COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"] # [--chown=<user>:<group>]:可选参数,用户改变复制到容器内文件的拥有者和属组。 # <目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
-
ADD 指令
ADD 指令和 COPY 的使用格式一致(同样需求下,官方推荐使用 COPY)。功能也类似,不同之处如下:
-
CMD 指令
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
- CMD 在 docker run 时运行
- RUN 在 docker build
注意:如果 Dockerfile 中存在多个 CMD 指令,仅最后一个生效。
格式:
CMD <shell 命令> CMD ["<可执行文件或命令>", "<param1>", "param2",...] # 推荐使用 CMD ["<param1>", "param2",...] # 该写法是为 ENTRYPOINT 指令指定的程序提供默认参数
-
ENTRYPOINT 指令
类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。
注意:如果 Dockerfile 中存在多个 ENTRYPOINT 指令,仅最后一个生效。
格式:
ENTRYPOINT ["<executeable>", "<param1>", "<param2>",...]
可以搭配 CMD 命令使用:一般是变参才会使用 CMD ,这里的 CMD 等于是在给 ENTRYPOINT 传参
-
ENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。
格式:
ENV <key> <value> ENV <key1>=<value1> <key2>=<value2>...
eg:
ENV NODE_VERSION 7.2.0 RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" # $NODE_VERSION引用环境变量
-
ARG
构建参数,与 ENV 作用一致。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
构建命令 docker build 中可以用 --build-arg <参数名>=<值> 来覆盖。
-
VOLUME
定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。
作用:
- 避免重要的数据因容器重启而丢失;
- 避免容器不断变大。
格式:
VOLUME ["<路径1>", "<路径2>"...] VOLUME <路径>
在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。
-
EXPOSE
声明端口。
作用:
- 帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
- 在运行时使用随机端口映射时,也就是
docker run -P
时,会自动随机映射 EXPOSE 的端口。
格式:
EXPOSE <端口1> [<端口2>...]
-
WORKDIR
指定工作目录(必须提前创建好)。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。
格式:
WORKDIR <工作目录路径>
-
USER
用于指定执行后续命令的用户和用户组,这边只是切换后续命令执行的用户(用户和用户组必须提前已经存在)。
格式:
USER <用户名>[:<用户组>]
-
HEALTHCHECK
用于指定某个程序或者指令来监控 docker 容器服务的运行状态。
-
ONBUILD
用于延迟构建命令的执行。
以开源项目 Halo 为例,以下是其 Dockerfile 文件:
FROM adoptopenjdk/openjdk8-openj9
VOLUME /tmp
ARG JAR_FILE=build/libs/halo.jar
ARG PORT=8090
ARG TIME_ZONE=Asia/Shanghai
ENV TZ=${TIME_ZONE}
ENV JAVA_OPTS="-Xms256m -Xmx256m"
COPY ${JAR_FILE} halo.jar
EXPOSE ${PORT}
ENTRYPOINT java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -server -jar halo.jar
Docker Compose
安装:
$ sudo apt install docker-compose
Compose 使用的3个步骤:
- 使用 Dockerfile 定义应用程序的环境;
- 使用 docker-compose.yml 定义构成程序的服务,这样它们可以在隔离环境中一起运行;
- 最后,执行
docker-compose up
命令来启动并运行整个应用程序。
以下是菜鸟教程的一个例子(链接):
-
创建测试目录和测试脚本:
$ mkdir composetest $ cd composetest $ touch app.py
app.py 文件中添加以下内容:
import time import redis from flask import Flask app = Flask(__name__) cache = redis.Redis(host='redis', port=6379) def get_hit_count(): retries = 5 while True: try: return cache.incr('hits') except redis.exceptions.ConnectionError as exc: if retries == 0: raise exc retries -= 1 time.sleep(0.5) @app.route("/") def hello(): count = get_hit_count() return "Hello World! I have been seen {} times.\n".format(count)
之后创建
requirements.txt
文件$ touch requirements.txt
内容如下:
flask redis
-
创建 Dockerfile 文件
$ touch Dockerfile
内容如下:
FROM python:3.7-alpine WORKDIR /code ENV FLASK_APP app.py ENV FLASK_RUN_HOST 0.0.0.0 RUN apk add --no-cache gcc musl-dev linux-headers COPY requirements.txt requirements.txt RUN pip install -r requirements.txt COPY . . CMD ["flask", "run"]
-
创建 docker-compose.yml 文件
$ touch docker-compose.yml
内容如下:
version: '3' services: web: build: . ports: - "5000:5000" redis: image: "redis:alpine"
该 Compose 文件定义了两个服务:Web 和 redis
- web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口 5000。此示例服务使用 Flask Web 服务器的默认端口 5000 。
- redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像。
-
使用 Compose 命令构建和运行应用
$ docker-compose up $ docker-compose up -d # 后台执行