docker 简介
docker是操作系统级别的虚拟化技术,竞争对手有VMWare和OpenStack等传统虚拟机,但优于它们。
docker提供了类似轻量级的「沙箱」的技术,它不进行硬件虚拟化,而是直接使用宿主的指令,但是它对进程做了封装隔离,隔离的进程独立于宿主和其他隔离的进程,因此被称为“容器”,Docker正是利用容器来运行和隔离应用。
一般,一个容器运行一个应用。
docker优势
随处运行、高资源利用率、快速扩展
- 高效的利用系统资源:操作系统级别的虚拟化技术,不需要硬件虚拟和运行完整操作系统等额外开销。
- 启动启动时间快:秒级、毫秒级
- 一致的运行环境:应用运行环境一致,即docker环境。
- 持续交付和部署:通过定制应用镜像,一次创建或配置,可以在任何地方正常运行。
- 轻松的迁移:因为一致的运行环境,所以应用方面迁移。
轻松维护和扩展:使用分层存储以及镜像技术,让应用重复部分具备可复用性,让基础镜像具备可扩展性。
docker vs 传统虚拟机
vm:使用Hypervisor进行硬件虚拟化,且多了一层guest OS —— 隔离出很多「子电脑」。
- docker:直接使用硬件资源,直接执行宿主系统的指令 —— 类似「沙箱」。

docker隔离性不如虚拟机
docker核心:Image、Container、Repository
Image是一个只读的模板文件,里面包括应用的运行环境文件等,它用于构建Container。
Container 像一个轻量级「沙箱」,用于运行和隔离应用。Container是Image的运行实例,它可以启动、开始、停止、删除。容器是可读写的,因为容器从镜像启动时,在镜像最上层创建了可写层。
Repository 是集中存放镜像文件的场所,类似maven,它也有Local Repository和Remote Repository。
补充:registry 是一个存储和内容交付系统,它存储Docker镜像和仓库,并维护它们的版本。
注意:容器有5种状态,没有运行 != 死亡。
docker安装
安装
在centos 7宿主下安装
方法一
# 安装依赖sudo yum install -y yum-utils device-mapper-persistent-data lvm2# 添加docker的yum源 (阿里云)sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# 安装最新社区版dockersudo yum -y install docker-ce docker-ce-cli containerd.io
方法二
# 脚本自动安装curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
在windows宿主下安装
参考
Docker Desktop 是 Docker 在 Windows 10 和 macOS 操作系统上的官方安装方式,这个方法依然属于先在虚拟机中安装 Linux 然后再安装 Docker 的方法。
Docker Desktop 官方下载地址: https://hub.docker.com/editions/community/docker-ce-desktop-windows
注意:此方法仅适用于 Windows 10 操作系统专业版、企业版、教育版和部分家庭版!
测试启动
# hello-world是docker官方的测试容器sudo docker run hello-world
docker run hello-world
Remote Repository 加速
https://registry.docker-cn.com Docker官方中国区 https://hub-mirror.c.163.com/ 网易云
Linux(系统版本可能有差异)
$ sudo vim /etc/docker/daemon.json# 写入以下内容到文件中{ "registry-mirrors": ["https://hub-mirror.c.163.com","https://registry.docker-cn.com"] }# 重启docker服务$ sudo systemctl daemon-reload$ sudo systemctl restart docker
Docker Desktop(Windows/Linux/MacOS)
Docker设置 —>Docker Engine : 添加registry-mirrors配置,重启服务。
检查镜像加速是否生效
$ docker info
. . .
. . .
Registry Mirrors:
https://hub-mirror.c.163.com/
https://registry.docker-cn.com/
. . .
. . .
把普通用户添加到docker组
docker需要root权限,为避免普通用户每次都使用sudo。
sudo usermod -aG docker 用户名
在windows下安装时,docker已经在wsl做了这件事了。通过cat /etc/group 可以看见类似docker:x:1001:xujia的一行。
镜像基本操作
—help
帮助
docker --helpdocker images --helpdocker ps --helpdocker rm --helpdocker run --help
docker images
列举镜像们
Usage: docker images [OPTIONS] [REPOSITORY[:TAG]]docker images -a 显示所有镜像,包括中间镜像
docker ps
列举容器们
Usage: docker ps [OPTIONS]docker ps -a 显示所有的容器,包括未运行的。
docker rm
移除容器们
Usage: docker rm [OPTIONS] CONTAINER [CONTAINER...]docker rm -f 5bfb05dae854 强制删除正在运行的指定容器
docker rmi
移除镜像们
docker rmi hello-world:latest 使用tag删除镜像docker rmi -f feb5d9fea6a5 使用image id删除镜像 -f 强制Usage: docker rmi [OPTIONS] IMAGE [IMAGE...]
一般先删容易再删镜像
docker pull
从registry中拉取镜像或仓库。
registry 是一个存储和内容交付系统,它存储Docker镜像和仓库,并维护它们的版本。
docker pull hello-world:latest 拉取hello-world镜像的最新版本Usage: docker pull [OPTIONS] NAME[:TAG|@DIGEST]Pull an image or a repository from a registryOptions:-a, --all-tags Download all tagged images in the repository--disable-content-trust Skip image verification (default true)--platform string Set platform if server is multi-platformcapable-q, --quiet Suppress verbose output
docker search
从Docker Hub中查找镜像
docker search hello-worldUsage: docker search [OPTIONS] TERMSearch the Docker Hub for imagesOptions:-f, --filter filter Filter output based on conditions provided--format string Pretty-print search using a Go template--limit int Max number of search results (default 25)--no-trunc Don't truncate output
docker image
管理镜像
Usage: docker image COMMANDCommands:build Build an image from a Dockerfilehistory Show the history of an imageimport Import the contents from a tarball to create a filesystem imageinspect Display detailed information on one or more imagesload Load an image from a tar archive or STDINls List imagesprune Remove unused imagespull Pull an image or a repository from a registrypush Push an image or a repository to a registryrm Remove one or more imagessave Save one or more images to a tar archive (streamed to STDOUT by default)tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE
强制清理临时镜像文件
docker image prune -f
容器基本操作
如果报错,如无法启动容器,可能是权限不够,导致文件挂载等异常。
解决办法是拿到管理员权限,删除容器,再次创建容器即可。
linux中需要root权限,windows需要管理员权限启动终端。
docker pull
拉取镜像
docker pull centos:7.5.1804
docker create
创建容器
docker create -i -t centos:7.5.1804 /bin/bash 创建一个交互式的容器,并指定/bin/bash作为伪终端Usage: docker create [OPTIONS] IMAGE [COMMAND] [ARG...]-i, --interactive Keep STDIN open even if not attached--ip string IPv4 address (e.g., 172.30.100.104)--ip6 string IPv6 address (e.g., 2001:db8::33)--ipc string IPC mode to use--isolation string Container isolation technology-t, --tty Allocate a pseudo-TTY--ulimit ulimit Ulimit options (default [])
docker start
启动容器
docker run 新建并启动容器
docker start 仅启动已有容器
docker start 5280cd917e11bb1b8997f322e6154c8c8eb894ff4b07656a2d9bd9f95b67a158docker start 5280c 启动容器,该容器id的前缀是5280cUsage: docker start [OPTIONS] CONTAINER [CONTAINER...]Start one or more stopped containersOptions:-a, --attach Attach STDOUT/STDERR and forward signals--detach-keys string Override the key sequence for detaching acontainer-i, --interactive Attach container's STDIN
docker ps
列举容器们
Usage: docker ps [OPTIONS]
docker ps -a 显示所有的容器,包括未运行的。
docker exec
在运行的容器中执行命令
docker exec -it aadf ls / 在运行的容器中执行“ls /”命令
docker exec -i -t aadf echo hello world 执行"echo hello world"命令
docker exec -it aadf /run.sh 执行"/run.sh"脚本
Usage: docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
Run a command in a running container
Options:
-d, --detach Detached mode: run command in the background
--detach-keys string Override the key sequence for detaching a
container
-e, --env list Set environment variables
--env-file list Read in a file of environment variables
-i, --interactive Keep STDIN open even if not attached
--privileged Give extended privileges to the command
-t, --tty Allocate a pseudo-TTY
-u, --user string Username or UID (format:
<name|uid>[:<group|gid>])
-w, --workdir string Working directory inside the container
进入容器 方式1 <—- 本质:执行/bin/bash命令
docker exec -it aabf53dbdddb /bin/bash
进入容器 方式2
docker run
在新建容器中执行命令。没有镜像就下载,没有容器就创建。
docker run -it centos:7.5.1804 /bin/bash
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Run a command in a new container
-i, --interactive Keep STDIN open even if not attached
-t, --tty Allocate a pseudo-TTY
-d, --detach Run container in background and print container ID
--rm Automatically remove the container
新建容器,并后台执行命令 <—- -itd
后台的用处:在容器配置好ssh服务后,ssh连接容器即可。
docker run -itd centos:7.5.1804 echo hello 后台执行"echo hello"命令
docker run -d -p 2222:22 centos:7.5.1804 后台开启容器,并配置端口映射
-p 2222:22
- 端口映射,访问宿主机器的2222端口,即可访问容器的22端口。
新建容器,用后即删 <—- --rm
docker run -it --rm centos:7.5.1804 echo hello
docker stop
停止容器们
docker stop aabf
Usage: docker stop [OPTIONS] CONTAINER [CONTAINER...]
Stop one or more running containers
Options:
-t, --time int Seconds to wait for stop before killing it (default 10)
docker export
导出容器的filesystem为tar文件。
docker export aab -o d:/aab.tar 导出容器的filesystem到指定路径
Usage: docker export [OPTIONS] CONTAINER
Export a container's filesystem as a tar archive
Options:
-o, --output string Write to a file, instead of STDOUT
docker import
导入tar文件的内容,以创建filesystem image
Usage: docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]
Import the contents from a tarball to create a filesystem image
Options:
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Set commit message for imported image
--platform string Set platform if server is multi-platform capable
docker container
管理容器
Usage: docker container COMMAND
Manage containers
Commands:
attach Attach local standard input, output, and error streams to a running container
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
exec Run a command in a running container
export Export a container's filesystem as a tar archive
inspect Display detailed information on one or more containers
kill Kill one or more running containers
logs Fetch the logs of a container
ls List containers
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
prune Remove all stopped containers
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
run Run a command in a new container
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
wait Block until one or more containers stop, then print their exit codes
docker container inspect
显示容器们的详细信息
docker container inspect aab 显示aab容器的详情
Usage: docker container inspect [OPTIONS] CONTAINER [CONTAINER...]
Display detailed information on one or more containers
Options:
-f, --format string Format the output using the given Go template
-s, --size Display total file sizes
docker top
显示运行中的容器的进程信息。
docker top aab 查看aab容器的进程信息
Usage: docker top CONTAINER [ps OPTIONS]
Display the running processes of a container
docker stats
显示指定容器的资源利用信息(默认实时)
docker stats aab 实时显示aab容器的资源利用信息
docker stats --no-stream aab 关闭实时显示,仅显示第一次的结果。
Usage: docker stats [OPTIONS] [CONTAINER...]
Display a live stream of container(s) resource usage statistics
Options:
-a, --all Show all containers (default shows just running)
--format string Pretty-print images using a Go template
--no-stream Disable streaming stats and only pull the first result
--no-trunc Do not truncate output
docker cp
拷贝files/folders,在一个container和local filesystem之间。
docker cp d:/test.txt aab:/text.txt 拷贝到指定容器路径
dokcer cp aab:/text.txt d:/test.txt 拷贝到指定本地路径
Usage: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
Copy files/folders between a container and the local filesystem
Use '-' as the source to read a tar archive from stdin
and extract it to a directory destination in a container.
Use '-' as the destination to stream a tar archive of a
container source to stdout.
Options:
-a, --archive Archive mode (copy all uid/gid information)
-L, --follow-link Always follow symbol link in SRC_PATH
镜像高级操作(重要)
docker commit
基于现有容器的变化,来创建一个新镜像。
语法类似git commit,就像是提交一个版本。
docker commit -m 'add new file : a.txt' -a 'atguigu' aab new_centos:1.0
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Create a new image from a container's changes
Options:
-a, --author string Author (e.g., "John Hannibal Smith
<hannibal@a-team.com>")
-c, --change list Apply Dockerfile instruction to the created image
-m, --message string Commit message
-p, --pause Pause container during commit (default true)
docker images 就能查询到上述提交的镜像,其名为new_centos:1.0。
docker bulid(常用)
Dockerfile是最常见的创建镜像的方式。它是一个文本文件,描述了基于某个父镜像创建新镜像的过程。
Dockerfile案例
使用Dockerfile创建一个基于centos:7.5.1804的java开发环境。
1、 宿主机的准备工作
见下,在宿主机的d:/MyDockerfile目录下有依赖文件(jdk-8u212-linux-x64.tar.gz)、Dockerfile文件(是空白文件,准备编写它)。
d:/MyDockerfile/jdk-8u212-linux-x64.tar.gz d:/MyDockerfile/Dockerfile
注意:d:/MyDockerfile仅仅是Dockerfile文件的工作目录,目录名称不固定,但是依赖文件们和Dockerfile文件都必须在这个工作目录下。
2、 编写Dockerfile文件
# centos:7.5.1804作为父镜像
FROM centos:7.5.1804
RUN mkdir -p /opt/software
RUN mkdir -p /opt/module
COPY jdk-8u212-linux-x64.tar.gz /opt/software
RUN tar -zxvf /opt/software/jdk-8u212-linux-x64.tar.gz -C /opt/module/
RUN rm -rf /opt/software/jdk-8u212-linux-x64.tar.gz
# 为镜像配置环境变量
ENV JAVA_HOME=/opt/module/jdk1.8.0_212
ENV PATH=$JAVA_HOME/bin:$PATH
说明: 每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。 第一条 FROM,指定使用哪个镜像源 RUN 指令告诉 docker 在镜像内执行命令,安装了什么。 COPY 是把文件copy到镜像中. 源文件必须是相对路径不能是绝对路径 ENV 在镜像中设置环境变量
3、 构建镜像
新的镜像名:centos_jdk8:1.0
docker build -t centos_jdk8:1.0 d:/MyDockerfile/
-t 即 tag,指明镜像名字和标签 注意:d:/MyDockerfile指明Dockerfile文件的根目录,支持绝对路径和相对路径,但是依赖文件们和Dockerfile文件都必须在这个根目录下。
4、测试镜像
docker images来查看上述创建的新镜像docker run -it centos_jdk8:1.0 /bin/bash来快速进入容器。docker scan centos_jdk8:1.0来测试镜像
为镜像支持SSH服务
基于已有的镜像,创建一个支持ssh的镜像
主要流程是:
- 更换yum源、安装sshd、生成ssh-key、更改root密码、开放22端口、容器启动时启动sshd
- 端口映射、运行容器
1、准备工作
在宿主机上创建d:/MyDockerfileSSH作为工作目录,并创建Dockerfile文件(空白文件)
d:/MyDockerfileSSH/Dockerfile
2、编写Dockerfile
# centos_jdk8:1.0是我本地的镜像,它被使用为父镜像。
FROM centos_jdk8:1.0
# LABEL 为生成的镜像添加元数据标签信息
# LABEL <key>=<value> <key>=<value> <key>=<value> ...
LABEL author="xujia"
LABEL version="1.0"
# 安装wget
RUN yum install -y wget #install wget lib
# 更换国内源(注意版本匹配,我的父镜像是centos7)
RUN wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
RUN sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo
RUN yum clean all
RUN yum makecache
RUN yum update -y
# 安装deltrpm <-- 否则可能会提示delt rpm问题。
RUN yum install -y deltarpm
# 安装sshd
RUN yum install -y openssh-server openssh-clients
RUN sed -i '/^HostKey/'d /etc/ssh/sshd_config
RUN echo 'HostKey /etc/ssh/ssh_host_rsa_key' >> /etc/ssh/sshd_config
# 生成ssh-key
RUN ssh-keygen -t rsa -b 2048 -f /etc/ssh/ssh_host_rsa_key
# 更改root密码
RUN echo 'root:000000' | chpasswd
# 开放 22 端口
EXPOSE 22
# 容器运行时启动sshd
RUN mkdir -p /opt
RUN echo '#!/bin/bash' >> /opt/run.sh
RUN echo '/usr/sbin/sshd -D' >> /opt/run.sh
RUN chmod +x /opt/run.sh
CMD ["/opt/run.sh"]
RUN指令:创建镜像时,运行指定命令。 CMD指令:启动容器时,运行指定命令 sed -i ‘/^HostKey/‘d /etc/ssh/sshd_config
- 在/etc/ssh/sshd_config文件中,删除匹配HostKey的行
3、docker build
新的镜像名:centos_jdk8_ssh:1.0
docker build -t centos_jdk8_ssh:1.0 d:/MyDockerfileSSH
4、后台运行容器(端口映射)、SSH远程连接
docker run -d -p 2222:22 centos_jdk8_ssh:1.0
ssh root@192.168.255.244 -p 2222
docker run -d -p 2222:22 centos_jdk8_ssh:1.0
- -p 2222:22 : 端口映射,访问宿主机器的2222端口,即可访问容器的22端口。
ssh root@192.168.255.244 -p 2222
- ssh 容器账户@宿主机ip -p 宿主机端口
端口映射与容器互联
默认情况下,容器内部能访问容器外部,但是容器外部无法通过网路来访问容器内的应用和服务。
端口映射之后,访问宿主机的指定端口就能访问容器的端口,也就能访问容器的应用。
端口映射案例
1、以tomcat:7和tomcat:8.5为例,创建容器,从外部访问。
docker pull tomcat:7
docker run -it -p 8888:8080 tomcat:7
-p 指定端口映射,-p 8888:8080 将容器的8080端口映射到宿主机的8888端口 -P 随机端口映射
查询端口映射的两种方式: docker port 容器id docker ps -a
通过宿主机从外部访问宿主ip:8888,即可访问到容器内部。
容器互相访问
端口映射不是docker互联连接的唯一方法,docker有一个连接系统。
容器命名
容器名会作为容器启动后的主机名,并配置host文件。
docker run -d --name hadoop102 centos_jdk8_ssh:1.0
删除容器(依据容器名)
docker rm -f hadoop102
自定义bridge网络
容器们连接同一个网桥来实现互联。
docker daemon 内嵌了一个DNS server,它能解析“容器名”,借助它来自定义bridge可以做到实现容器名互相通信。
docker network
docker network create --driver bridge mynet 创建一个名为mynet的brideg网络
Usage: docker network COMMAND
Manage networks
Commands:
connect Connect a container to a network
create Create a network
disconnect Disconnect a container from a network
inspect Display detailed information on one or more networks
ls List networks
prune Remove all unused networks
rm Remove one or more networks
网络列表
docker network ls
案例:容器互联
自定义bridge,并建立名为hadoop102和hadoop103的容器(如果存在的话先删除容器),让它们通过容器名相互通信。
1、自定义bridge,网络名 mynet
docker network create --driver bridge mynet
2、建立hadoop102、hadoop103容器,并加入到自定义bridge网路
docker rm -f hadoop102 hadoop103
docker run -d --name hadoop102 --network mynet centos_jdk8_ssh:1.0
docker run -d --name hadoop103 --network mynet centos_jdk8_ssh:1.0
测试容器之间ping docker exec -it hadoop102 ping hadoop103docker exec -it hadoop103 ping hadoop102
案例:容器与宿主机、windows互联
测试window、wsl(linux)、container的连通性。通常: 绿色线表示直接连通,容器间接与window连通,且是单向的。 
如何,容器和window相互连通呢?
linux和容器之间采用桥接模式,此时分配linux的可用ip给容器,linux和容器在同一个网段。另外,容器最好采用静态ip。
准备工作
创建好容器。
docker rm -f hadoop102 hadoop103
docker run -d --name hadoop102 centos_jdk8_ssh:1.0
docker run -d --name hadoop103 centos_jdk8_ssh:1.0
查询宿主机wsl(linux)网络配置 ifconfig
eth0: 192.168.255.244 255.255.240.0 gateway: 192.168.240.1
1、宿主机安装pipework、bridge-utils工具
sudo yum install -y bridge-utils
sudo yum install -y git
git clone https://github.com/jpetazzo/pipework.git
sudo mv pipework/pipework /usr/bin/
2、搭建宿主机的bridge网络
sudo brctl addbr br0; \
sudo ip link set dev br0 up; \
sudo ip addr del 192.168.255.244/20 dev eth0; \
sudo ip addr add 192.168.255.244/20 dev br0; \
sudo brctl addif br0 eth0; \
sudo ip route add default via 192.168.240.1 dev br0
添加网桥br0 启动网桥br0 删除eth0的ip,若是eth33则此处写eth33 给网桥分配ip(可使用eth0删掉的ip) 把eth0连接在br0网桥上 给br0网桥添加默认路由(网关)
注:放在一条语句执行,防止中间断网。如果失败,按需执行下面配置以恢复
删除br0网桥
sudo ip link set dev br0 down sudo brctl delbr br0
删除多余的网卡
sudo ifconfig 网卡名 down
添加eth0的ip、设置eth0的默认路由(网关)、并启用eth0
sudo ip addr add 192.168.255.244/20 dev eth0 sudo ip route add default via 192.168.240.1 dev eth0 sudo ip link set dev eth0 up

3、启动容器接入宿主机的bridge上
# 给容器配置ip和网关
sudo pipework br0 hadoop102 192.168.240.102/20@192.168.240.1
sudo pipework br0 hadoop103 192.168.240.103/20@192.168.240.1
总结:
docker.sh脚本
#!/bin/bash
# 启动容器
docker start hadoop102
docker start hadoop103
# 搭建网桥
sudo brctl addbr br0; \
sudo ip link set dev br0 up; \
sudo ip addr del 192.168.255.244/20 dev eth0; \
sudo ip addr add 192.168.255.244/20 dev br0; \
sudo brctl addif br0 eth0; \
sudo ip route add default via 192.168.240.1 dev br0
sleep 5
sudo pipework br0 hadoop102 192.168.240.102/20@192.168.240.1
sudo pipework br0 hadoop103 192.168.240.103/20@192.168.240.1
将hadoop102连接br0网桥,且指定它的ip和网关(网关同宿主机)。
ping: win10、wsl、容器 ?
路由表的说明
docker与宿主机的网路通信。
容器和宿主机的网络通信采用veth pair 技术,其特性可以保证无论哪一个 veth 接收到网络报文,都会将报文传输给另一方。
背景:win10装了wsl,wsl装了docker,容器1和容器2通过自定义bridge连接。docker network inspect bridge可查看bridge网络情况。
下面是我的ip情况
容器1:
ifconfig和route -n
- eth0: 172.18.0.2 255.255.0.0
- gateway: 172.18.0.1
容器2:
ifconfig和route -n
- eth0 172.18.0.3 255.255.0.0
- gateway: 172.18.0.1
docker bridge:
docker network inspect bridge
- Subnet”: “172.17.0.0/16”
- gateway: 172.17.0.1
wsl:
ifconfig
- eth0: 192.168.255.244 255.255.240.0
- gateway: 192.168.240.1
win10:
ipconfig
- 真实网卡:10.16.62.103 255.255.128.0
- gateway 10.16.0.1
- vEthernet (WSL): 192.168.240.1 255.255.240.0
技巧
docker rm -f $(docker ps -aq)
