贡献者: addis
curl -fsSL https://get.docker.com | sudo sh
sudo docker run hello-world
containerd.io
, docker-ce-cli
, docker-ce
, 用 dpkg -i xxx.deb
安装即可
docker --version
检查版本
sudo docker run hello-world
测试最简单的 image(镜像)。
docker
命令前面都默认需要 sudo
,以下省略。如果不加,会有错误 Cannot connect to the Docker daemon...
。也可以通过用户组来设置不需要 sudo 的 user,例如 sudo usermod -aG docker 用户名
(见文档)。
singularity
而不是 docker
。前者不需要 sudo
权限。docker
倒出的 tar.gz
文件可以直接上传到超算上,然后用 singularity
导入。
docker images
可以检查本地所被 tag 的镜像。加上 -a
选项也显示所有没有 tag 的镜像(有时候似乎也被成为 layer)。这些没名字的镜像可能是用 Dockerfile 生成镜像时的中间步骤。
docker ps
可以检查本地所有容器信息。
docker container ls
也可以,但区别是什么?
docker pull hub用户名/repo名:TAG
其中 hub用户名/
对于一些官方镜像可以忽略,例如 docker pull ubuntu:22.04
中,ubuntu
是 repo,22.04
是 TAG。docker pull hello-world
中,tag 也忽略了,使用默认的 tag latest
docker run [选项] 镜像 [命令]
从镜像创建容器并运行。反复使用会创建多个容器。如果不设置 [命令]
,则运行 image 的默认命令。
镜像
是指 用户/repo名:TAG
或者镜像 ID(用 docker images
查看),下同。
docker run -it 镜像 bash
会创建容器并进入其命令行。-i
表示 interactive,-t
表示 tty 即远程命令行(不加的话也能用但是没有 bash prompt)。退出该命令行后,容器停止运行。需要用下文的 docker start
启动,再 docker exec -it 容器 bash
。
docker run -i 镜像 某个命令
可以创建容器,执行某个命令,并把 stdin,stdout,stderr 等转接到当前 shell。运行完成或出错后,容器停止。
docker run -itd 镜像 bash
,其中 -d
表示 detached 即后台运行。然后再 docker exec -it 容器 bash
进入命令行,退出后容器仍在后台运行不会自动停止,需要手动用下文的 docker stop 容器
。
docker run ... --name 容器名 ...
可以指定容器的名字,如果不指定则会随机生成一个(用 ps
查看)。下文的 容器
都是指容器名或者容器 ID(用 ps
查看)。
docker exec [选项] 容器 命令
让某个运行中容器执行命令,选项 -it
可以交互式执行,例如 docker exec -it 容器 bash
。如果该镜像的默认 user 不是 root,那么在 -it
后面加上 -u 0
选项可以以 root 的身份 login。
sudo docker...
命令的人都可以自由访问本地的任何容器
docker stop 容器
停止容器
docker start 容器
开始容器,默认后台运行(注意区分 start
和 run
)。用 docker start -i 容器
可以转发 stdout(和 stdin?)到当前 shell。
start
时执行的命令,只能先 commit
,再用不同的命令 run
一次。
docker rm [-f] 容器
删除容器
docker image rm [-f] 镜像
删除镜像。如果该镜像有容器就要 -f
。如果该镜像有基于它的子镜像,-f
也没用。
docker image prune
用于移除没有被使用的镜像,具体呢?
docker system prune -a
会移除所有停止的容器,所有没有关联容器的镜像,所有 build cache。运行后会给出确认提示。
docker commit 容器 [repo名][:tag名]
会将容器 commit,如果不指定 [repo名]
或 [tag名]
那么二者都会是 <none>
(和 Dockerfile 中间步骤产生的那些镜像一样)。如果不指定 tag名
则 tag 默认为 latest
。如果 repo名:tag名
和已经存在则会覆盖,之前镜像会变为 <none>:<none>
。
commit
多次也会产生多个镜像。
sudo docker login
用于登录 docker hub
docker save -o image.tar 镜像
可以把镜像保存为文件。
docker load -i image.tar
或者 docker load < image.tar
可以恢复保存的镜像文件。也可以用 image.tar.gz
。
docker save 镜像 | gzip > image.tar.gz
docker rename 旧容器名字 新容器名字
docker cp 容器:/容器内某路径/ 本地某路径
docker cp 本地某路径 容器:/容器内某路径/
docker save -o 备份文件.tar 镜像
/var/lib/docker/
sudo service docker stop
sudo rm -rf /var/lib/docker
注意这会删掉所有镜像! 但不这么做好像 daemon 不能正常启动。
sudo vim /etc/docker/daemon.json
设置镜像的默认保存路径以及容器根目录大小
{
"data-root": "/path/to/your/docker",
"storage-driver": "devicemapper",
"storage-opts": ["dm.basesize=30G"]
}
sudo service docker start
即可。
sudo docker run -it ubuntu:20.04 bash
然后 df -h
看看根目录是否有 30G。
FROM ubuntu:22.04
RUN apt -y update
RUN apt -y upgrade
RUN apt install -y git
RUN echo "hello world!" > hello.txt
CMD ["cat", "hello.txt"]
docker build -t 容器名:tag名 路径
使用指定路径下的 Dockerfile
创建 image 并命名。
Sending build context to Docker daemon 2.048kB
Step 1/6 : FROM ubuntu:22.04
---> a8780b506fa4 【这是 ubuntu:22.04 的镜像ID】
Step 2/6 : RUN apt -y update
---> Running in 269b63b22f4a 【运行 apt update 的临时容器ID】
... 【apt的命令行输出】
Removing intermediate container 269b63b22f4a 【commit并删除临时容器】
---> ad6eefc640eb 【commit后的镜像ID】
Step 3/6 : RUN apt -y upgrade
... 【临时容器,apt的命令行输出,commit并删除临时容器】
---> 4810e6e9e606
Step 4/6 : RUN apt install -y git
...
---> 2504439881ff
Step 5/6 : RUN echo "hello world!" > hello.txt
...
---> de0680a0f43a
Step 6/6 : CMD ["cat", "hello.txt"]
...
---> 2dc75e84a18a
Successfully built 2dc75e84a18a
Successfully tagged docker_test:Dockerfile
docker images -a
查看,所有镜像。Dockerfile 中 2-6 步结束后各生成一个镜像,但只有最后一步的镜像有 repo 和 tag。
REPOSITORY TAG IMAGE ID CREATED SIZE
docker_test Dockerfile 2dc75e84a18a 49 seconds ago 192MB
<none> <none> de0680a0f43a 52 seconds ago 192MB
<none> <none> 2504439881ff 57 seconds ago 192MB
<none> <none> 4810e6e9e606 About a minute ago 117MB
<none> <none> ad6eefc640eb About a minute ago 117MB
ubuntu 22.04 a8780b506fa4 4 days ago 77.8MB
-f 文件
sudo docker build -t mplapack:ubuntu2204 .
。其中 -t
命名一个 tag,-f
指定 dockerfile,.
指定某个路径为当前路径,tee
把 stdout 输出到命令行以及指定的文件。
CMD["命令", "参数1", "参数2", ...]
或者 CMD 命令 参数1 参数2, ...
可以在每次容器开始运行时都执行一次某个命令。
docker run
执行 CMD
中命令时,会把命令行输出转到 host 的命令行。
docker build
会自动检查 Dockerfile 和之前的变化,把前面相同的步骤略过,所以还是不要把所有命令都放在同一个 RUN
里面。
docker build --no-cache
,可以强制重新开始 build,不跳过重复的步骤。
# Comment
写注释
ARG
的命令必须是 FROM
,例如 FROM image:tag
,这和 docker pull repo:tag
一样。例如 FROM ubuntu:22.04
。
RUN 命令
可以在容器的 shell 中执行命令。
\
给命令换行
RUN 命令1 && 命令2 ...
执行多个命令
COPY 本地相对于当前路径的文件文件(夹) 容器内绝对路径/重命名的文件(夹)
可以从外面到里面复制文件。注意第一个路径必须是当前文件夹的某个子文件夹或其中的文件。
ARG
命令基本是定义容器中的环境变量。例如 ARG ver="2.0.1"
,之后可以用例如 RUN ... myapp-${ver}
来获替换成值(双引号不会包含,花括号有时候可以省略)。在 bash session 中不会有该环境变量。
ENV
和 ARG
有什么不同?
sh
,用 SHELL
来修改 Dockerfile 之后的 shell,这个只对 Dockerfile 有用。
ARG DOCKER_UID=1000
ARG DOCKER_USER=docker # 用户名
ARG DOCKER_PASSWD=docker # 用户密码
RUN useradd -u $DOCKER_UID -m $DOCKER_USER \
--shell /bin/bash -G wheel,root && \
echo "$DOCKER_USER:$DOCKER_PASSWD" | chpasswd && \ # 改密码
echo "$DOCKER_USER ALL=(ALL) ALL" >> /etc/sudoers && \ # sodo 权限
echo "$DOCKER_USER ALL=NOPASSWD: ALL" >> /etc/sudoers # 免密码
USER ${DOCKER_USER} # 指定用户, 对 dockerfile 下面命令生效, 对 bash session 生效。
hub用户名/repo名
docker tag 本地镜像 hub用户名/repo名:tag
sudo docker push hub用户名/repo名:tag
sudo docker pull hub用户名/repo名:tag
docker images -a
只会显示一个。
hub用户名/repo名:tag
重复 push,会进行覆盖。
docker run -v 本地绝对路径:容器中的目录
。注意 容器中的目录
如果不存在,会自动创建(多层目录也支持)。
172.17.xxx.xxx
docker run -p HOST_PORT:CONTAINER_PORT 镜像
,这样如果 docker 有一个 web server 就可以从外面访问了。也可使用多次 -p
。
docker pull ubuntu
安装官方 ubuntu docker 镜像,这是一个非常精简的系统,比 ubuntu server 还精简,只有 30 多 M。
apt update
apt install sudo
apt install bash-completion
, 然后在 bashrc 中加上
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
Ubuntu 18.04 服务器版测试成功
sudo systemctl stop docker
sudo rsync -avh /var/lib/docker/ /路径/docker
sudo vim /etc/systemd/system/docker.service.d/10-machine.conf
。记得先备份!
ExecStart=/usr/bin/dockerd
后面加上 --data-root /路径/docker/
,添加完成后完整文件如
sudo systemctl daemon-reload
sudo systemctl start docker
sudo docker images
和容器 sudo docker ps -a
sudo rm -rf /var/lib/docker
也可以移动到一个备份文件夹。