Docker基本用法

爱吃猪头爱吃肉

中文网

安装

  • 下载Docker依赖组件
1
yum -y install yum-utils device-mapper-persistent-data lvm2
  • 设置阿里云镜像
1
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  • 安装Docker服务
1
yum -y install docker-ce
  • 安装成功后,启动Docker并设置开机自启
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 启动Docker
systemctl start docker

# 设置开机自启动
systemctl enable docker

# 重启
systemctl restart docker

# 查看状态
systemctl status docker

# 停止
systemctl stop docker

# 测试安装成功
docker versions

相关概念

1. 镜像 Image

软件服务镜像 如nginx镜像、node镜像

1
2
# 查看所有镜像
docker images

2. 拉去镜像

docker hub

1
docker pull 镜像NAME

常用命令

Docker镜像库

1. 搜索镜像

1
docker search 镜像名称

img

2. 拉取镜像

1
docker pull 镜像NAME

img

3. 删除镜像

1
docker rmi 镜像名

img

4. 镜像列表

1
docker images 或者 docker image ls

img

Docker 容器操作

1. 查看容器列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
docker ps -a|f|q
Usage: docker ps [OPTIONS]

List containers

Options:
-a, --all 显示所有容器(默认显示正在运行)
-f, --filter filter 根据提供的条件过滤输出
--format string 使用Go模板的漂亮打印容器
--help 打印使用
-n, --last int 显示最后创建的n个容器(包括所有状态)(默认值为-1)
-l, --latest 显示最新创建的容器(包括所有状态)
--no-trunc 不要截断输出
-q, --quiet 仅显示数字ID
-s, --size 显示总文件大小

1.1 -a 显示所有容器

img

1.2 -f,–filter 过滤

img

1.3 -q 只显示id

img

2. 删除容器

docker rm -f [容器名]

img

删除所有容器

1
docker rm -f $(docker ps -aq)

3. 运行容器

运行容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Usage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Run a command in a new container

Options:

-d, --detach 在后台运行容器并打印container ID
-i, --interactive 保持STDIN打开,即使未连接
-p, --publish list 将容器的端口发布到主机(默认值[])
-P, --publish-all 将所有公开端口发布到随机端口
--restart string 容器退出时应用的重新启动策略(默认为“否”)
--name string 为容器指定一个名称
-t, --tty 分配一个伪TTY
-v, 可以用于文件映射

# 通常使用 -itd

3.1 -dit后台运行,打开STDIN并分配一个伪TTY

可以简写为-d

1
2
3
4
5
6
7
[root@base ~]# docker run -dit nginx
056121918e5bdf3072cf9dc0e5533569d86e4a8d0c4faf0526be9a431711ba1c
[root@base ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
056121918e5b nginx "/docker-entrypoin..." 20 seconds ago Up 18 seconds 80/tcp unruffled_chandrasekhar
609b039cc1e6 nginx "/docker-entrypoin..." 21 hours ago Exited (0) 21 hours ago nginx
88958f0f4fc8 centos-7 "/bin/bash" 2 weeks ago Exited (137) 2 weeks ago centos7

3.2 –name 指定名称

1
2
3
4
5
6
7
8
[root@base ~]# docker run -dit --name nginx_named nginx
8925665a0958b70246993cecfa24e3580c114ecfd5fa2a15eb8cbc754d765b1a
[root@base ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8925665a0958 nginx "/docker-entrypoin..." 2 seconds ago Up 2 seconds 80/tcp nginx_named
056121918e5b nginx "/docker-entrypoin..." 6 minutes ago Up 6 minutes 80/tcp unruffled_chandrasekhar
609b039cc1e6 nginx "/docker-entrypoin..." 21 hours ago Exited (0) 21 hours ago nginx
88958f0f4fc8 centos-7 "/bin/bash" 2 weeks ago Exited (137) 2 weeks ago centos7

3.3 -p 指定端口/ -P 随机端口

-p 指定端口 并映射到设备 (设备端口: docker容器端口)

img

img

开启nginx服务

1
docker run -dit -p 80:80 nginx

img

停止nginx 服务

1
docker stop [CONTAINER ID] 

img

注意

开启docker时遇到错误

  1. 开启时命名冲突
1
/usr/bin/docker-current: Error response from daemon: Conflict. The container name "/nginx" is already in use by container 57c46cdab3d06b4c96144613620c9017d7a5ad90edd7a530c3e6ed8d9280980c. You have to remove (or rename) that container to be able to reuse that name..

4. 暂停、恢复容器

docker pause 容器名称|id 暂停

docker unpause 容器名称|id 恢复

5. 杀死容器

docker kill 容器名称|id 杀死容器 (类似于杀死端口)

6. 查看容器日志

1
docker logs 容器名称|id
  • -t 加时间戳
  • -f 打印最新日志
  • –tail 查看多少条

7. 进入容器

1
docker exec -it 容器名称 bash

img

  • nginx 配置文件

/etc/nginx/nginx.conf

img

  1. 执行vim nginx.conf 发现

img

  1. 需要安装vim
1
2
3
4
# 1. 先更新包管理
apt-get update
# 2. 安装vim
apt-get install vim

img

  1. 安装完毕可以通过vim 修改nginx.conf
  2. 通过docker restart 容器名 重启nginx

img

8. 容器与系统文件操作 cp

  • 拷贝操作 容器 -> 系统
1
docker cp 容器id:容器中的文件路径 系统路径
  • 拷贝操作 系统 -> 容器
1
docker cp 系统路径 容器id:容器中的文件路径

9. 查看容器内操作

9.1 查看运行进程

1
docker top 容器name|id

img

9.2 查看容器详情

1
docker inspect 容器name|id

img

9.3 容器数据卷 -v

实现容器中的数据 与 系统中的数据进行映射

1. 设置绝对路径设置

注意 : 使用数据卷只能在容器首次启动时设置

1
2
3
4
5
6
7
docker run -p xxxx:xxxx -d --name -v 系统目录:容器目录 容器名称 镜像名称
// 首次启动时 通过设置-v 完成数据卷配置
1. 通过绝对路径方式设置
-v 系统目录:容器目录

// 可以设置容器目录是只读的,不会因为系统目录的修改而修改
-v 系统目录:容器目录:ro

注意: 这种方式会将该容器路径下的内容自动清空 (内容以系统目录/文件 为主)

2. 设置别名方式设置

1
docker run -p xxxx:xxxx -d --name -v ``aaaa``:容器目录 容器名称 镜像名称
  1. aaaa 表示docker数据卷的别名,如果别名如果存在则自动使用,不存在则创建
    img
  2. 使用别名的方式会保留容器目录中的内容

3. 查看数据卷

  1. 查看所有数据卷
1
docker volume ls 
  1. 查看数据卷详情
1
docker inspect 数据卷别名
  1. 删除数据卷
1
docker volume rm 数据卷别名
  1. 创建别名数据卷
1
docker volume create 数据卷别名

10. 容器打包

1 将容器打包成镜像

1
docker commit -m "描述信息" -a "作者信息" 容器名称|id 打包名称:版本

img

2. 镜像的备份与恢复

备份

1
docker save 镜像名:版本 -o 名称.tar

载入(回复)

1
docker load 镜像名 -i 名称.tar

配置Mysql

  1. 拉去mysql镜像
1
docker pull mysql

img

  1. 运行容器
    img

需要指定mysql root权限的默认密码

-v 的容器路径 可通过查看dockerhub 的镜像描述查看

img

1
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=qwertyuiop123 -v /root/mysqlData:/var/lib/mysql --name mysql_1 mysql
  1. 容器跟随docker的启动而自动启动
1
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=qwertyuiop123 --restart=always -v /root/mysqlData:/var/lib/mysql --name mysql_1 mysql
  1. 备份data数据

导出sql文件

注意:使用数据卷备份数据 是将数据库底层文件系统进行的备份

利用mysql官方命令 mysqldump直接远程工具备份sql

  • 导出所有database

    1
    docker exec mysql容器id或name sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/backups/database.sql 
  • 导出指定database

    1
    docker exec mysql容器id或name sh -c 'exec mysqldump --databases 数据库名 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/backups/database.sql 
  • 导出表 但不要数据

    1
    docker exec mysql容器id或name sh -c 'exec mysqldump --no-data --databases 数据库名 -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/backups/database.sql 

配置Redis

  1. 安装
1
docker pull redis

img

  1. 运行redis
1
docker run --name redis_1 -d --restart=always -p 6379:6379 redis 
  1. 持久化操作
    1. rdb持久化: 快照redis服务器将某一时刻数据以快照文件形式写入到磁盘
    2. aof持久化:redis服务器将所有redis客户端的写操作以命令方式记录到日志文件中 √
  2. 注意:只要开启了持久化,将持久化文件生成容器中/data/目录中
1
docker run --name redis_1 -d --restart=always -p 6379:6379 -v /root/redisData:/data redis redis-server --appendonly yes
  1. 修改redis.conf

    1. 找到指定版本的redis.conf, 修改appendonly yes
    2. 将conf放入服务器的文件目录
      img
  2. 开启容器以配置文件启动

    1
    docker run --name redis_1 -d --restart=always -p 6379:6379 -v /root/config/redisConf:/data/ redis redis-server /data/redis.conf 

配置nginx

  1. 安装
1
docker pull nginx
  1. 运行nginx
1
docker run --name nginx_1 -d --restart=always -p 80:80 nginx
  1. 修改配置文件

    1. 进入nginx容器
      docker exec -it nginx启动id bash
    2. 搜索nginx
      find / -name nginx

      可以找到index.html 与 nginx.conf等信息

      img
    3. 修改配置文件
      1
      docker run --name nginx_1 -d --restart=always -v /root/config/nginx.conf:/etc/nginx/nginx.conf -p 80:80 nginx

    启动会报错,提示没有nginx.conf, 因此需要手动创建或copy一份

    img
    删除当前nginx容器 重新执行上述命令
    img

    1. 作为服务器修改文件目录

      Nginx 服务目录 /usr/share/nginx/html

      1
      docker run --name nginx_1 -d --restart=always -v /root/web:/usr/share/nginx/html -p 80:80 nginx

综上可知

1
docker run --name nginx_1 -d --restart=always -v /root/config/nginx.conf:/etc/nginx/nginx.conf -v /root/web:/usr/share/nginx/html -p 80:80 nginx

* 容器间的通信

通过网络进行

img

1
docker network

img

1
2
3
4
docker network create -d bridge 网络名称

# 将其他容器放入该网桥中
docker network connect 网桥名称 容器名称

注意:

需要将容器放入同一网络下,可以自行创建

Dockerfile

表示镜像的描述文件,可以根据这个Dockerfile 构建出定制的镜像

  1. 在指定位置创建Dockerfile配置文件

  2. 通过Dockerfile构建镜像

    1
    docker build -t 镜像名:版本 . (指定Dockerfile文件所在位置)

Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# dockerfile

FROM node:16-alpine3.15

WORKDIR /home/app/

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 8080

ENTRYPOINT ["npm", "run"]

CMD ["serve"]

上述脚本是上一章的 Dockerfile 的例子,接下来我们将对每一行命令进行讲解:

FROM

为这次构建流程指定基础镜像,同时必须是第一条指令,因为后续所有的操作都必须基于基础镜像之上,每一行运行系统的命令都必须是基础镜像中所含有的,所以当基础镜像中不包含 Node 环境的话,后续的命令也无法正常使用 Node 相关的 API,除非你在后续调用 Node API 之前已经安装过。

同时镜像名称的规则之前也提过,为 <imageName>:<tag>,当未填写 tag 的时候,默认为需要拉取式最新的 tag 版本。

WORKDIR

此命令是设置当前工作目录,如果目录不存在,则会直接创建,设置完毕之后,所有操作的路径都将处于当前指定路径之下。

1
2
WORKDIR /app
WORKDIR data

运行镜像产生的容器后

1
2
3
docker exec -it 镜像容器id bash

# 此时默认进入的就是 /app/data目录

img

COPY

顾名思义,这是一个复制的命令,但是 COPY 只能复制宿主机本地的文件。

ADD

COPY 的功能类似但 ADD 的功能更加强大,具备跨服务器复制内容的能力,类似于 Linux 命令中的 scp,如果将来源换成 url 的话,那么又会变成 wegt 的命令,整体可操作性更高

此外在执行 <**源文件**> 为 tar 压缩文件的话,压缩格式为 gzip, bzip2 以及 xz 的情况下,会自动复制并解压到 <**目标路径**>,由于解压可能会导致缓存失效,所以仅仅是复制文件的需求,建议使用 COPY

img

此时就可以将服务器中aa.txt 放到WORKDIR指定的文件中
下载tomcat并完成解压、删除、改名等操作

EXPOSE

声明当前容器要访问的网络端口,但是仅仅是声明要暴露的端口,启动的时候并不会直接能访问到,需要在启动容器的时候添加 -p 参数来挂载宿主端口。 主要用于声明,便于更好的查看 无实际作用

RUN

在构建镜像过程中执行的命令,需要执行的命令格式如下:

1
2
3
4
5
6
7
RUN <command>
RUN ["executable", "param"]

# 安装vim
RUN yum install -y vim
# 或
RUN ["yum","install","-y","vim"]

第一种格式是直接执行 shell 命令,第二种则是启动文件(或者全局命令模式,例如 npm) + 传入参数的格式,如果 shell 命令不太容易满足功能的时候,可以使用第二种,直接写好处理的脚本,加传入参数即可。

CMD

在容器启动时候执行的命令,执行命令的语法如下:

1
2
3
4
5
6
1. CMD command param
2. CMD ["executable", "param"]

# 比如
CMD node ./index.js
CMD ['node', './index.js']

启动命令与 RUN 也是类似的,分别是直接执行 shell 与执行可执行命令或文件

CMD语法可以存在多个,但只有最后一个会被执行

ENV

可以在Dockerfile中配置变量名

1
2
ENV BASE_PATH=/app/data
WORKDIR $BASE_PATH

img

VOLUME

容器数据卷,用于数据保存和持久化,用于提示用户映射容器哪些目录,与EXPOSE一样,无实际作用

1
2
ENV BASE_PATH=/app/data
VOLUME $BASE_PATH

ENTRYPOINT

ENTRYPOINT 是指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有其他传入值作为该命令的参数,单独使用时与 CMD 脚本使用方式一致,执行命令脚本如下:

1
2
3
4
5
ENTRYPOINT ["executable", "param1", "param2"]

# 比如
ENTRYPOINT node ./index.js
ENTRYPOINT ['node', './index.js']

当与 CMD 命令混合使用时,CMD 的功能就不再是直接运行脚本,而是将 CMD 的内容作为参数传给 ENTRYPOINT,所以在上述示例的 dockerfole 中大家会发现两种混合的写法:ENTRYPOINT 的参数是 NPM RUN,而 CMD 的参数是 serve

当出现多次 ENTRYPOINT 脚本时,最后一条会覆盖上述所有的脚本,即只有最后一条才会真实生效,同时可以在启动容器的时候使用 --entrypoint 参数来覆盖。

虽然 ENTRYPOINTCMD 两者都是有可以当作容器启动命令来看待,但是还是有不少的区别,这块的内容展开说说会有比较多的篇幅,最开始我们对 Docker 的学习还是先从熟悉命令与使用方式入手,比较深入或者难懂的内容后期会放在加餐里面进行详细的拓展。

CMD & ENTRYPOINT

  1. 都是指定容器启动时的命令默认执行的命令

  2. CMD指令可以存在多个,但只有最后一个会被执行

  3. 区别

    1. CMD命令如果在运行容器时进行覆盖: docker run 镜像:版本号 覆盖自定义的命令·1
    1
    2
    3
    4
    5
    # Dockerfile
    CMD ["ls", "/apps"]

    # 执行覆盖操作
    docker run 镜像:版本号 ls /
    1. ENTRYPOINT 命令如果覆盖

      docker run –entrypoint=命令名 镜像:版本号 命令参数

      1
      2
      3
      4
      5
      # Dockerfile
      ENTRYPOINT ["ls", "/apps"]

      # 执行覆盖操作
      docker run --entrypoint=ls 镜像:版本号 /
    2. 联合使用,修改参数 不修改指令

    1
    2
    3
    4
    5
    6
    7
    8
    # Dockerfile
    ENTRYPOINT ["ls"]
    CMD ["/apps"]

    # 执行操作
    docker run 镜像:版本号 /

    # 必须使用string[] 方式传递

编写Node dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
FROM node:16.15.0

RUN git clone https://gitee.com/mirschao/webserver-vue.git

WORKDIR /root/node/

RUN npm install

RUN npm run build

EXPOSE 8080

VOLUME /root/node/

ENTRYPOINT ["npm"]

CMD ["start"]

dockerignore

除了 Dockerfile 之外,正常使用中我们还可能接触到 .dockerignore 文件,一般存放在 docker 构建上下文的根目录(也就是项目根目录),用来排除不需要上传到 docker 服务端的文件或目录,它存在的价值有:

  • 构建镜像时能避免不需要的大文件上传到服务端,从而拖慢构建的速度、网络带宽的消耗;
  • 可以避免构建镜像时将一些敏感文件及其他不需要的文件打包到镜像中,从而提高镜像的安全性;

.dockerignore 的使用规则基本上与 .gitignore 保持一致就不过多讲解了,常规项目可以直接使用如下规则:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# compiled output
/dist
/node_modules

# Logs
logs
*.log
npm-debug.log*
pnpm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# OS
.DS_Store

# Tests
/coverage
/.nyc_output

# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

# cache
.yalc
yalc.lock

添加以上配置之后,后续执行 COPYADD 处理本地文件移动的时候就会根据以上规则忽略对应的文件了。

Docker compose

官方提供的针对项目容器进行快速编排的工具,可以将项目中使用的容器进行聚合并进行顺序启动

Compose 可以通过docker-compose.yml 模板文件(YAML 格式) 来定义一组相关联的容器为一个项目

Compose中有两个重要盖面

  • 服务(service):一个应用的容器,实际可以包含若干运行相同镜像的容器实例。
  • 项目(project):由一组关联的应用容器组成一个完整业务单元,在docker-compose.yml中定义

安装

1
yum install docker-compose-plugin

img

查看是否安装成功

img

使用

  1. 创建项目目录 mkdir ./osiris_web
  2. 创建docker-compose.yml文件
  3. 编写docker-compose.yml文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# docker版本
version "3.8"
# 服务
service:
mysqldb: # mysql服务器
images: mysql:8.0.0 # 镜像
container_name: mysql_1 # 类似于 --name
ports: # 服务器port:容器port 类似与-p,可存在多个
- "3306:3306"
volumes: # 操作数据卷, 系统中的文件目录必须要存在
- /root/mysqlData:/var/lib/mysql
environment: # 环境变量 -e操作
- "MYSQL_ROOT_PASSWORD=root"
networks: # 运行服务网络 --network 网址名称
- project
depends_on: # 其他依赖项
- redis
redis:
images: redis:6.2.7
container_name: redis
ports:
- "6379:6379"
networks:
- project
volumes:
mysqlData: # 在文件中声明数据卷的别名
networks:
project: # 声明网桥

运行

开启

1
docker compose up # 开启执行

暂停

1
docker compose down  # 将开启时的缓存全部清除

模板语法

1. Build

用于构建 如docker build -t xxxx,通过docker-compose在启动容器前根据dockerfile构建镜像,然后根据构建的镜像启动容器

1
2
3
4
5
6
7
version "3.8"
services:
apps:
#build: ./ # 指定Dockerfile的上下文目录
build:
context: ./ # 指定Dockerfile的上下文目录
dockerfile: "dockerfile" # 指定Dockerfile名

2. Command

覆盖容器启动后默认执行的命令

1
2
3
4
5
6
7
version "3.8"
services:
webs:
build:
context: ./ # 指定Dockerfile的上下文目录
dockerfile: "dockerfile" # 指定Dockerfile名
command: ["start"]

3. depends_on

解决容器的依赖、启动先后的问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
version "3.8"
services:
mysql:
images: mysql:8.0.0
ports:
- "3306:3306"
redis:
images: redis:6.2.7
ports:
- "6379:6379"
depends_on:
- mysql

# 此时先启动mysql,再启动redis,可存在多个

4. env_file 与 environment

  • environment:用来给容器启动指定环境变量相当于docker run -e
  • env_file: 用来给容器启动指定环境变量文件,类似于dotenv
1
2
3
4
5
#env_file: ./.env
env_file:
- ./common.env
- ./apps/web.env
- /opt/runtime_opts.env

5. restart

1
2
3
4
restart: "no"
restart: always
restart: on-failure
restart: unless-stopped

Docker compose 命令

  • build 构建(重新构建)项目中的服务容器
  • config 检测compose文件的错误
  • up 启动服务
  • down 停止容器
  • exec 进入某个容器
  • images 列出项目中所包含的镜像
  • logs 查看服务容器的日志
  • kill 发送 SIGKILL 信号来强制停止服务容器
  • port 查看某个容器端口所映射的公共端口
  • ps 列出项目中目前的所有容器
  • restart 重启项目中的服务
  • rm 删除所有停止状态的服务容器
  • run 在指定服务上运行一个命令
  • scale 设置指定服务运行的容器个数
  • stop 停止处于运行状态的容器
  • start 启动被stop的服务容器
  • top 查看各个服务容器内运行的进程
  • pause 暂停一个服务容器
  • unpause 恢复处于暂停状态中的服务

img

img

  • 标题: Docker基本用法
  • 作者: 爱吃猪头爱吃肉
  • 创建于: 2023-05-06 20:53:30
  • 更新于: 2023-05-06 21:28:17
  • 链接: https://zsasjy.github.io/2023/05/06/Docker基本用法/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
推荐文章
webpack常用配置汇总 webpack常用配置汇总 前端工程化校验配置 前端工程化校验配置 浏览器架构 浏览器架构 搭建react开发环境 搭建react开发环境 git常见指令 git常见指令 less使用指南 less使用指南
 评论