添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

apt 安装

  • 最简单的一行命令安装: curl -fsSL https://get.docker.com | sudo sh
  • ubuntu x86/64 安装 Docker Engine 参考 这里
  • 测试安装成功,用 sudo docker run hello-world

    deb 安装包安装

    • 但是如果 apt 不能用的话,也可以下载 deb 文件离线安装
    • 安装包 下载链接 ,选择系统版本代号,然后 pool/stable/amd64/
    • 选好了以后需要下载三个安装包,依次安装(如果次序不对也问题不大,会提示 dependency 找不到的错误)
    • 三个安装包依次是 containerd.io , docker-ce-cli , docker-ce , 用 dpkg -i xxx.deb 安装即可

      1. 基础

      • 截止到 2024-8-14 国内无法拉取 dockerhub,一些解决办法如 这里 这里
      • 参考 官方入门
      • docker 和 chroot 的对比
      • docker 在功能上基本和虚拟机一样,但是占用资源要少得多,因为共享 host 系统的内核
      • docker 本质上就是一个进程
      • windows 和 mac 上有 docker desktop,建议使用
      • 用了 docker 就不能用 virtualbox 了,必须要在 eufi 把 Hyper V 关掉或打开才可以
      • 最新的 windows docker 默认使用 WSL2 运行。
      • 重启以后启动 docker,登录,用 powershell 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 导入。
      • 注意区分容器(container)和镜像(image)和仓库(repo)。仓库相当于 VirtualBox 虚拟机,镜像相当于增量备份点(snapshot),而容器相当于虚拟机的目前状态。容器也有运行和非运行的状态。
      • 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。
      • docerk 镜像没有简单的上锁设置,就算修改了 passwd。能执行 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。运行后会给出确认提示。
      • 如果一个镜像 ID 有多个 tag,那么无法直接删除 ID,需要具体指定 tag。
      • 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 镜像

        dockerd 设置

        • docker 镜像默认存在 /var/lib/docker/
        • 容器的根目录大小默认是 10GB
        • 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。

          2. Dockerfile

          • dockerfile 是一系列创建 docker image 的命令。当然也可以写一个 bash 脚本直接在容器中运行,但前者更灵活方便。
          • 一个简单的 Dockerfile,一共 6 步
          • 如果 dockerfile 中如果有某行出错,然后稍微改动了一点,那么改动前的那些命令基本都会从临时的 image 里面生成,所以会很快。
            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
            
          • 如果想指定其他的 Dockerfile 文件名,用 -f 文件
          • 一个例子是 mplapack 的 sudo docker build -t mplapack:ubuntu2204 . 。其中 -t 命名一个 tag, -f 指定 dockerfile, . 指定某个路径为当前路径, tee 把 stdout 输出到命令行以及指定的文件。
          • 每个命令会建立一个 layer ,应该相当于 git 的一次 commit。每个 layer 保存两个 image 之间的差别,可以从任意 layer 建立容器。
          • 不一定每个 layer 都有 tag,但都会有 id。
          • CMD["命令", "参数1", "参数2", ...] 或者 CMD 命令 参数1 参数2, ... 可以在每次容器开始运行时都执行一次某个命令。
          • docker run 执行 CMD 中命令时,会把命令行输出转到 host 的命令行。
          • docker build 会自动检查 Dockerfile 和之前的变化,把前面相同的步骤略过,所以还是不要把所有命令都放在同一个 RUN 里面。
          • 如果用 docker build --no-cache ,可以强制重新开始 build,不跳过重复的步骤。
            • 这里参考 github 上 mplapack 中的 Dockerfiles
            • # Comment 写注释
            • dockerfile 命令一般用大写(但严格来说不区分大小写)
            • 第一个除了 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 有什么不同?
            • docker 默认的 shell 是 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 生效。
              

              3. 本地镜像 push 到服务器

              • 首先在 dockerhub 上面登录并创建新的 repo:hub用户名/repo名
              • retag 镜像:docker tag 本地镜像 hub用户名/repo名:tag
              • push:sudo docker push hub用户名/repo名:tag
              • pull:sudo docker pull hub用户名/repo名:tag
              • 如果用 Dockerfile 生成镜像时存在许多没有 tag 的镜像,这些不会被 push。如果把所有镜像删掉再 pull,docker images -a 只会显示一个。
              • 如果镜像是通过 dockerfile 生成的,那么 push 以后在 dockerhub 上面会看到每个 layer 的生成命令。
              • 如果相同的 hub用户名/repo名:tag 重复 push,会进行覆盖。

                4. docker 文件夹映射

                • 如果想从 docker 中访问本地文件夹,就用 docker run -v 本地绝对路径:容器中的目录。注意 容器中的目录 如果不存在,会自动创建(多层目录也支持)。

                  5. docker 网络端口映射

                • 容器自己的 ip 默认为 172.17.xxx.xxx
                • 如果要把容器的端口映射到 host 的端口,使用 docker run -p HOST_PORT:CONTAINER_PORT 镜像,这样如果 docker 有一个 web server 就可以从外面访问了。也可使用多次 -p

                  6. ubuntu image 缺少的功能

                  • 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
                    

                    7. X11 转发

                    • 参考这篇文章
                    • 以及这篇文章

                      8. docker 迁移数据文件夹

                      • Ubuntu 18.04 服务器版测试成功
                      • 服务器系统盘被 nginx 占用太多了,尝试移动到挂载硬盘
                      • sudo systemctl stop docker
                      • sudo rsync -avh /var/lib/docker/ /路径/docker
                      • 修改 docker 服务文件如 sudo vim /etc/systemd/system/docker.service.d/10-machine.conf。记得先备份!
                      • ExecStart=/usr/bin/dockerd 后面加上 --data-root /路径/docker/,添加完成后完整文件如
                      • 加载服务 config sudo systemctl daemon-reload
                      • 开启 docker 服务 sudo systemctl start docker
                      • 检查所有镜像 sudo docker images 和容器 sudo docker ps -a
                      • sudo rm -rf /var/lib/docker 也可以移动到一个备份文件夹。
                        致读者: 小时百科一直以来坚持所有内容免费无广告,这导致我们处于严重的亏损状态。 长此以往很可能会最终导致我们不得不选择大量广告以及内容付费等。 因此,我们请求广大读者热心打赏 ,使网站得以健康发展。 如果看到这条信息的每位读者能慷慨打赏 20 元,我们一周就能脱离亏损, 并在接下来的一年里向所有读者继续免费提供优质内容。 但遗憾的是只有不到 1% 的读者愿意捐款, 他们的付出帮助了 99% 的读者免费获取知识, 我们在此表示感谢。 友情链接: 超理论坛 | ©小时科技 保留一切权利