[appendix]
= Docker 常用命令
详细的 Docker 使用指南，请参考 link:resources/files/docker_practice.pdf[《Docker - 从入门到实践》],以下仅列出一些常用命令。

== docker 服务启停
[source,bash]
----
# 启动 docker
service docker start

# 停止 docker
service docker stop

# 重新启动 docker
service docker restart
----

== 镜像加速器配置
国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。
Docker 官方和国内很多云服务商都提供了国内加速服务，例如:

* Docker 官方提供的中国 registry mirror
* 阿里云加速器
* DaoCloud 加速器

=== Windows 10 镜像加速器配置
对于使用 Windows 10 的用户,在系统右下角托盘 Docker 图标内右键菜单选择 Settings,
打开配置窗口后左侧导航菜单选择 Docker Daemon。
编辑窗口内的 JSON 串,填写加速器地址，例如:
[source,json]
----
{
	"registry-mirros" : [
		"https://registry.docker-cn.com"
	]
}
----

编辑完成,点击 Apply 保存后 Docker 服务会重新启动。

=== Mac OS X 镜像加速器配置
对于使用 Mac OS X 的用户,在任务栏点击 Docker for Mac 应用图标 --> Perferences... --> Daemon --> Registry mirrors。
在列表中填写加速器地址即可。修改完成后，点击 Apply & Restart 按钮，Docker 就会重新启动并应用配置的镜像地址了。

=== 检查加速器是否生效
配置加速器之后，如果拉取镜像仍然十分缓慢，请手动检查加速器配置是否生效，在命令行执行
[source,bash]
----
docker info

#如果从结果中看到如下内容，说明配置成功。
Registry Mirrors:
    https://registry.docker-cn.com/
----

== 镜像操作
=== 获取镜像
在 Docker Hub 上有大量的高质量的镜像可以使用,这里我们就说一下怎么获取这些镜像。

从 Docker 镜像仓库中获取镜像的命令是 docker pull, 其命令格式为:
[source,bash]
----
docker pull [选项] [Docker Registry 地址[:端口号]/] 仓库名[:标签]
----

具体的选项可以通过 docker pull --help 命令查看，这里我们说一下镜像名称的格式。

* Docker 镜像仓库地址: 地址的格式一般是 <域名/IP>[:端口号],默认地址是 Docker Hub
* 仓库名:仓库名的格式一般是<用户名>/<软件名>。对于 Docker Hub，如果不给出用户名，默认为 library，也就是官方镜像。

以下给出一些示例:
[source,bash]
----
docker pull ubuntu:16.04			#从官方仓库中获取 ubuntu 16.04 镜像
docker pull ibmcom/db2express-c		#从官方仓库中获取 ibm 公司提供的 db2express-c 最新版镜像
----

=== 列出镜像
[source,bash]
----
docker image ls
----

=== 删除镜像
[source,bash]
----
docker image rm 镜像ID
----

=== 镜像导出
[source,bash]
----
docker save -o 导出文件名.tar 需要导出的镜像名
----

以下给出一些示例:
[source,bash]
----
docker save -o mysql.tar mysql
docker save -o oracle11g.tar sath89/oracle-ee-11g
----

=== 镜像导入
[source,bash]
----
docker load --input 导出文件名.tar
----

以下给出一些示例:
[source,bash]
----
docker load --input mysql.tar
docker load --input oracle11g.tar
----

=== 镜像构建
[source,bash]
----
docker build [选项] <上下文路径/URL/>
----

以下给出一些示例:
[source,bash]
----
# 采用当前目录作为构建上下文
docker build -t nginx:v3 .
             ----------- -
             选项         上下文路径

# 从 Git 仓库 URL 构建              
docker build https://github.com/twang2218/gitlab-ce-zh.git#:11.1
             ---------------------------------------------  ----
             git repo(默认master 分支)                       构建目录
             
# 用给定的远程 tar 压缩包构建, 先下载解压再作为构建上下文
docker build http://server/content.tar.gz

# 用给定的本地 tar 压缩包构建(支持文件格式: gzip, bzip2, xz)
docker build - <content.tar.gz

# 从标准输入中读取 Dockerfile 进行构建,这种构建没有构建上下文，不能进行 COPY 之类的操作
docker build - < Dockerfile
# 或
cat Dockerfile | docker build -


----

== 容器操作
=== 运行容器
[source,bash]
----
docker run
	--name gitlab \	//<1>
	--restart always \	//<2>
	-d \				//<3>
    -p 10443:443 \		//<4>
    -p 1080:80 \
    -p 1022:22 \
    -v /path/to/your/host/dir/volume/gitlab_v10/config:/etc/gitlab:Z \		//<5>
    -v /path/to/your/host/dir/volume/gitlab_v10/logs:/var/log/gitlab:Z \
    -v /path/to/your/host/dir/volume/gitlab_v10/data:/var/opt/gitlab:Z \
    gitlab/gitlab-ce:latest		//<6>
----
<1> 容器名称
<2> 自动启动，即当 docker 启动后,容器就自动启动
<3> 容器在后台以守护状态运行
<4> 端口映射，格式: 本地主机端口:容器端口
<5> 数据卷映射, 格式: 本地主机目录或文件:容器目录或文件
<6> 镜像名称，格式: 仓库名[:标签]

=== 创建容器
创建容器有两种方法，可以创建并启动，也可以只创建不启动，在解决容器相关问题时，此模式比较有意义。
[source,bash]
----
# 创建容器，但不启动
docker create --name 容器名称 镜像名称

# 将容器的目录全部导出成 tar 文件
docker export 容器名称 > 导出文件名.tar

# 解压 tar 文件后，可以查看容器完整的文件系统
----

=== 列出容器
[source,bash]
----
docker container ls -a
----

=== 列出当前正在运行的容器
[source,bash]
----
docker ps
----

=== 启动容器
[source,bash]
----
docker container start 容器ID
----

=== 停止容器
[source,bash]
----
docker container stop 容器ID
----

=== 删除容器
[source,bash]
----
docker container rm 容器ID
----

=== 进入容器
[source,bash]
----
docker exec -it 容器ID bash
----

== 网络操作
=== 命令集
[source,bash]
----
# 关于 docker network 相关命令
docker network create
docker network connect
docker network ls
docker network rm
docker network disconnect
docker network inspect
----

=== 创建网桥
[source,bash]
----
# 创建名为 mynetwork 的网桥
docker network create --driver bridge --subnet 172.18.0.0/16 mynetwork
----

=== 查看网桥配置
[source,bash]
----
# 查看名为 mynetwork 网桥的配置
docker network inspect mynetwork
----

=== 固定容器 IP 地址
[source,bash]
----
# 在名为 mynetwork 网桥上固定 ip 地址启动容器
docker run -d --name hdp -v /opt/docker/volume/nginx:/usr/share/nginx/html --network=hadoop --ip=172.18.0.100 nginx
----

=== 将已有容器加入到网络
[source,bash]
----
# 将已存在的 nginx 容器加入到 hadoop 网络中
docker network conect hadoop nginx
----

=== 容器访问宿主机IP
docker 18.03 加入了一个 feature，在容器中可以通过 host.docker.internal 来访问主机。

== 数据卷操作
=== 创建卷
[source,bash]
----
docker volume create xxx    # xxx 卷名称
----

=== 显示卷信息
[source,bash]
----
docker volume inspect xxx   # xxx 卷名称

# 执行结果如下:
[
    {
        "CreatedAt": "2023-04-16T13:00:36Z",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/oracle/_data",   <1>
        "Name": "oracle",
        "Options": {},
        "Scope": "local"
    }
]
----
<1> 主机目录,如果是 mac OS 或 windows 下的 docker 时，通常是指虚拟机中的目录

=== 绑定卷到容器
[source,bash]
----
docker run -d --name oracle -v volume-name:container-dir container-registry.oracle.com/database/express:21.3.0-xe
                               ----------- -------------
                               卷名称       容器目录         <1>
----
<1> -v 参数既可以绑定卷到容器中，也可以绑定主机目录到容器中

=== 数据共享
如果要授权一个容器访问另一个容器的 Volume，我们可以使用 -volumes-from 参数来执行 docker run。
[source,bash]
----
# 多个 oracle 实例共享一个卷中的数据
docker run -d --name oracle2 --volumes-from oracle container-registry.oracle.com/database/express:21.3.0-xe
                                            ------ --------------------------------------------------------
                                            共享卷  镜像名
----

=== 数据容器
常见的使用场景是使用纯数据容器来持久化数据库、配置文件或者数据文件等。
[source,bash]
----
# 创建一个已经包含在 Dockerfile 里定义过 Volume 的 postgres 镜像，运行 echo 命令然后退出。
# 当我们运行 docker ps 命令时，echo 可以帮助我们识别某镜像的用途。
docker run --name dbdata postgres echo "Data-only container for postgres"
----

用 -volumes-from 命令来识别其它容器的 Volume
[source,bash]
----
# 运行另外一个 postgres 数据库容器，且采用上面的数据容器中的卷
docker run -d --volumes-from dbdata --name db1 postgres
----

使用数据容器的两个注意点:

. 不要运行数据容器，这纯粹是在浪费资源。
. 不要为了数据容器而使用“最小的镜像”，如 busybox 或 scratch，只使用数据库镜像本身就可以了。你已经拥有该镜像，所以并不需要占用额外的空间。

=== 卷备份
如果你在用数据容器，那做备份是相当容易的。
[source,bash]
----
$ docker run --rm --volumes-from dbdata -v $(pwd):/backup debian tar cvf /backup/backup.tar /var/lib/postgresql/data
             ----                ------    ------ ------- ------ ---------------------------------------------------
             1                   2         3              4      5
----
. --rm 表示容器在执行完毕后删除
. 挂接到已有的数据卷
. 挂接主机当前目录到容器的 /backup 目录
. 运行的镜像名
. 在启动的容器中执行 tar 命令，将 /var/lib/postgresql/data 目录压缩打包到 /backup/backup.tar 文件,





