找回密码
 立即注册
首页 业界区 业界 Docker | 如何在 Linux 服务器使用 docker

Docker | 如何在 Linux 服务器使用 docker

挫莉虻 3 天前
目录

  • 00 需求
  • 01 安装 docker
  • 02 准备工作
  • 03 配置 Dockerfile 和 docker composer
  • 04 启动 docker
  • 05 测试能否 ssh 连接这个 docker
  • 06 Debug

    • 6.1 ssh 连接不成功
    • 6.2 发现 Dockerfile 或 docker composer 写错了

  • 07 配置环境的后续工作

(致谢技术非常强的专家
00 需求

需要在新的服务器上配环境。
服务器只能通过 boss 的账号(ssh boss@172.16.1.100)连接,通过 boss 的账号连接后,需要在 /data1 磁盘下创建自己的 docker,然后用 ssh 连接自己的 docker,从而使用服务器。这样,即可实现 服务器只为 boss 创建了一个账号,但可以通过 boss 的账号支持多人登录,各自管理各自的环境。
(boss 和 172.16.1.100 地址均为虚构,在使用时,需要替换成自己希望配置的服务器地址,和可以使用的账号)
服务器的配置:Ubuntu 20.04,nvidia 显卡的驱动版本分别是 11.3 和 12.2。
01 安装 docker

(我需要配置的服务器里已经安装了 docker,因此没有做这个步骤。以下教程是 LLM 生成的)
  1. # 首先,确保系统中没有旧版本的 Docker
  2. sudo apt-get remove docker docker-engine docker.io containerd runc
  3. # 然后,更新包列表并安装必要的包
  4. sudo apt-get update
  5. sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
  6. # 添加 Docker 的官方 GPG 密钥
  7. curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
  8. # 设置 Docker 的稳定版仓库
  9. sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
  10. # 更新包列表以包含 Docker 仓库中的软件包
  11. sudo apt-get update
  12. # 安装 Docker CE、Docker CLI 和 Containerd
  13. sudo apt-get install docker-ce docker-ce-cli containerd.io
  14. # 检查 Docker 的安装版本
  15. docker --version
  16. # 验证 Docker 是否安装成功,这个命令会下载并运行一个测试镜像
  17. sudo docker run hello-world
  18. # 最后,配置 Docker 开机自启
  19. sudo systemctl enable docker
复制代码
为了不使用 sudo 运行 Docker 命令,可以将当前用户(boss)添加到 docker 组:
  1. sudo usermod -aG docker $USER
复制代码
然后,重新登录或重启系统以使组更改生效。
02 准备工作

现在,我们通过 ssh 登入 boss 的账号,然后在 /data1 磁盘下,新建准备放 docker 的目录,并改变目录权限:
( 是我的名字,在跑命令时,需要替换成希望 docker 拥有的名字)
  1. sudo mkdir /data1/<user_name>  # 新建目录
  2. sudo chown boss /data1/<user_name>/ -R
  3. sudo chgrp boss /data1/<user_name>/ -R
  4. mkdir /data1/<user_name>/docker
  5. mkdir /data1/<user_name>/project
复制代码
为了通过 ssh 登录 docker,先配置 ssh 的 authorized_keys:
  1. cd /data1/<user_name>/docker/
  2. vim authorized_keys
  3. # 然后,把本地电脑 user/.ssh 里面的 id_rsa.pub 的内容复制上去
复制代码
03 配置 Dockerfile 和 docker composer

Dockerfile 和 docker composer 的原理:(个人理解,乱说,我其实不懂 docker)
Dockerfile 里面写了一系列指令。在 Dockerfile 里写一个指令,相当于在建好的 docker 里运行这个指令,因此,Dockerfile 里可以写一些安装包之类的指令。
Dockerfile 的每一个指令都会构建一个 layer;如果已经 docker compose build 了一遍 Dockerfile,然后我又修改了其中几个指令,那么下次更新 docker、重新 build 的时候,只会跑修改后的几个指令,而不会把所有的指令重新跑一遍。
Dockerfile 的主要指令包括:

  • FROM: 指定基础镜像。
  • RUN: 在容器中运行命令。
  • CMD: 指定容器启动时默认执行的命令。
  • ENTRYPOINT: 类似于CMD,但不会被docker run命令行参数覆盖。
  • COPY: 将文件或目录从主机复制到镜像中。
  • ENV: 设置环境变量。
  • EXPOSE: 声明容器将监听的端口。
  • WORKDIR: 设置工作目录。
Docker composer 的原理我还不太了解,但(deepseek 给我生成的)docker composer 里面 1. 定义了 docker 的名字,2. 定义了 ssh 端口,3. 定义了 docker 内外的目录映射,4. 定义了 ssh 连 docker 的 authorized_keys 的文件路径映射,5. 定义了 runtime 环境是 nvidia,6. 执行打开 ssh + sleep infinity 指令,避免 docker 自动死掉。
新建 Dockerfile:
  1. cd /data1/<user_name>/docker/
  2. vim Dockerfile
复制代码
然后,查询一下 boss 账号的 id,在 boss 账号里运行 id 命令。在下文中,假设我们查到的 id 是 1001。
Dockerfile 的具体内容:
  1. # 看一下 docker images 里面有哪些镜像,然后选择一个有 cuda 的
  2. # 这样,可以避免在新 docker 环境里安装显卡驱动
  3. FROM nvidia/cuda:11.6.0-devel-ubuntu20.04
  4. # 设置时区
  5. ENV TZ=Asia/Shanghai
  6. RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
  7. # 安装基础软件
  8. RUN apt-get update && \
  9.     apt-get install -y \
  10.     openssh-server \
  11.     python3 \
  12.     python3-pip \
  13.     vim \
  14.     git \
  15.     wget \
  16.     curl \
  17.     unzip \
  18.     sudo \
  19.     net-tools \
  20.     iputils-ping \
  21.     build-essential \
  22.     cmake \
  23.     htop \
  24.     && apt-get clean \
  25.     && rm -rf /var/lib/apt/lists/*
  26. # 安装其他软件
  27. RUN apt-get update && \
  28.     apt-get install -y \
  29.     tmux \
  30.     && apt-get clean \
  31.     && rm -rf /var/lib/apt/lists/*
  32. # 创建用户(保持与宿主机相同的 UID 避免权限问题)
  33. RUN useradd -m -u 1001 -s /bin/bash <user_name>
  34. # sudo without password
  35. RUN echo "<user_name> ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
  36. USER <user_name>
  37. WORKDIR /home/<user_name>
  38. # 创建 .ssh 目录并设置权限
  39. RUN mkdir -p /home/<user_name>/.ssh && \
  40.     chown -R <user_name>:<user_name> /home/<user_name>/.ssh && \
  41.     chmod 700 /home/<user_name>/.ssh
  42. # 安装 Conda
  43. RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh && \
  44.     bash miniconda.sh -b -p /home/<user_name>/miniconda && \
  45.     rm miniconda.sh
  46. RUN /home/<user_name>/miniconda/bin/conda init bash
  47. CMD ["/bin/bash"]
复制代码
配置 docker composer 之前,先确认哪个端口可用:
  1. sudo netstat -tuln
  2. # 找一个不被列出的端口,比如 8012
复制代码
然后,新建 docker composer:
  1. cd /data1/<user_name>/docker/
  2. vim docker-compose.yml
复制代码
docker-compose.yml 的具体内容:
  1. version: '3.8'
  2. services:
  3.   <user_name>:
  4.     container_name: <user_name> # 设置容器名称
  5.     build: . # 使用当前目录下的 Dockerfile 构建镜像
  6.     image: <user_name> # 镜像名称
  7.     restart: unless-stopped
  8.     runtime: nvidia # 启用 GPU 支持
  9.     ports:
  10.       - "8012:22" # 选择一个未被占用的端口(请确认 8012 可用)
  11.     volumes:
  12.         # 挂载项目目录,所有不希望丢失、希望存在服务器磁盘上的文件都需要放在 project 里
  13.       - /data1/<user_name>/project:/home/<user_name>/project
  14.         # ssh 的 authorized_keys 的映射
  15.       - /data1/<user_name>/docker/authorized_keys:/home/<user_name>/.ssh/authorized_keys  # SSH
  16.     environment:
  17.       - NVIDIA_DRIVER_CAPABILITIES=all
  18.     command: /bin/bash -c "sudo service ssh start && sleep infinity"
复制代码
一个兼容旧版本 docker 的 docker composer(我并不懂什么旧版本,都是专家写的)
  1. services:
  2.   container_name: <user_name> # 设置容器名称
  3.   build: . # 使用当前目录下的 Dockerfile 构建镜像
  4.   restart: unless-stopped
  5.   ports:
  6.     - "8012:22" # 选择一个未被占用的端口(请确认 8012 可用)
  7.   volumes:
  8.     - /data1/<user_name>/project:/home/<user_name>/project # 挂载项目目录
  9.     - /data1/<user_name>/docker/authorized_keys:/home/<user_name>/.ssh/authorized_keys  # SSH
  10.   environment:
  11.     - NVIDIA_DRIVER_CAPABILITIES=all
  12.   command: /bin/bash -c "sudo service ssh start && sleep infinity"
复制代码
04 启动 docker

然后,启动 docker:
  1. cd /data1/<user_name>/docker/
  2. docker compose build  # build Dockerfile
  3. docker compose up -d  # 启动 docker
  4. # 旧版本 docker
  5. docker-compose build  # build Dockerfile
  6. docker-compose up -d  # 启动 docker
  7. # 进入 docker 看一下
  8. docker exec -it <user_name> bash
  9. # 然后 ls,会看到 miniconda 和 project 两个目录,所有需要映射到磁盘、不希望丢失的文件都需要放到 project 里
  10. # 列出所有 docker
  11. docker ps
  12. docker ps -a  # 列出更详细的信息,包括已停止的 docker
  13. # 暂时停止和启动 docker
  14. docker stop <user_name>
  15. docker start <user_name>
  16. # 把我自己的 docker 关掉(没有在本地挂在的目录会丢失)
  17. docker compose down
复制代码
05 测试能否 ssh 连接这个 docker
  1. # 在本地电脑上连接
  2. ssh -p 8012 <user_name>@172.16.1.100
复制代码
应该会连接成功,并自动激活 conda 的 (base) 环境。
06 Debug

6.1 ssh 连接不成功

ssh 连接不成功(比如让输密码),很可能是 docker 内外的 .ssh 或 authorize_keys 的权限出了问题:docker 外要改成 boss,dockers 内要改成 。
在 docker 外改权限:
  1. # 发现权限有问题,退出 docker,再改一下目录的权限
  2. sudo chown boss /data1/<user_name>/ -R
  3. sudo chgrp boss /data1/<user_name>/ -R
复制代码
在 docker 内改权限:
  1. cd /data1/<user_name>/docker/
  2. docker exec -it <user_name> bash  # 进入 docker
  3. # 把 ~/.ssh 的权限改成我自己
  4. sudo chown <user_name> ~/.ssh -R
  5. sudo chgrp <user_name> ~/.ssh -R
复制代码
如果 ssh 连接时出现
  1. ECDSA host key for [172.16.1.100]:8012 has changed and you have requested strict checking.
  2. Host key verification failed.
复制代码
然后连接不成功,则需要把本机的 ~.ssh/known_host 里面的 172.16.1.100 删除。
6.2 发现 Dockerfile 或 docker composer 写错了

如果发现 Dockerfile / docker composer 写错了,或者想加一些指令之类,可以再跑
  1. cd /data1/<user_name>/docker/
  2. # 如果发现 Dockerfile 写错了,或者想加一些东西,可以再跑
  3. docker compose build  # build Dockerfile,只会跑修改过的 layer
  4. docker compose up -d  # 会变成 Recreating <user_name>
复制代码
07 配置环境的后续工作

<ul>给 conda 和 pip 换源:Conda | 如何在 Linux 服务器安装 conda
配置 git 和 GitHub 访问权限:Git | 如何在新服务器上配置 git
配置代理:Python · GitHub · Linux | 使用本机作为代·理服务器
安装 MuJoCo、mujoco_py:Python · MuJoCo | MuJoCo 与 mujoco_py 的版本对应,以及安装 Cython
您需要登录后才可以回帖 登录 | 立即注册