这份笔记总结了在 Ubuntu 服务器上部署 Docker、构建镜像、运行容器并进行远程开发的完整流程。它包含了所有我们遇到过的坑、以及被证明最稳定可靠的“最佳实践”解决方案,旨在提供一个通用、详细、可重复的操作指南。

第一部分:服务器准备与 Docker 安装(防弹流程)

这一部分将确保 Docker 在各种网络环境下都能被正确安装。

步骤 1.1:服务器初始化

在新服务器上,首先进行基础准备,避免后续出现乱码和依赖冲突。

  1. 更新系统: 确保所有软件包都是最新的。

    sudo apt update && sudo apt upgrade -y
    
    
  2. 设置系统区域 (Locale): 防止终端输出乱码,确保能看清所有提示。

    sudo apt install -y language-pack-en-base
    sudo locale-gen en_US.UTF-8
    sudo update-locale LANG=en_US.UTF-8
    
    

    操作完成后,务必退出服务器并重新 SSH 登录,以使设置生效。

步骤 1.2:安装 Docker 引擎(官方仓库 + 国内镜像)

这是最核心的部分,它结合了使用官方工具和国内镜像的优点,以应对复杂的网络环境。

  1. 准备 Docker 的 GPG 密钥

    • 挑战: 在企业或特殊网络环境下,服务器可能无法通过 curlwget 直接从 download.docker.com 下载 GPG 密钥文件。

    • 解决方案 (手动传输):

      1. 在本地电脑上: 打开浏览器,访问并下载密钥文件:https://download.docker.com/linux/ubuntu/gpg。可将其重命名为 docker.gpg

      2. 上传到服务器: 使用 scp 命令将下载好的 docker.gpg 文件上传到服务器的某个已知路径下,例如 /bigdata/xxx/

        # 示例:在本地 Windows PowerShell 中执行
        scp C:\path\to\docker.gpg your_username@your_server_ip:/bigdata/xxx/
        
        
      3. 验证上传: SSH 登录服务器后,务必验证文件已在正确位置

        ls -l /bigdata/xxx/docker.gpg
        
        

        只有看到文件信息,才能继续下一步。

  2. 配置 APT 软件源

    • 挑战: 直接访问 Docker 官方仓库 download.docker.com 可能会因网络问题(SSL 握手失败)而超时或失败。

    • 解决方案 (使用国内镜像源并正确关联密钥):

      1. 清理旧配置: 确保环境干净。

        sudo rm /etc/apt/sources.list.d/docker.list || true
        sudo rm /etc/apt/keyrings/docker.gpg || true
        
        
      2. 从正确路径安装密钥并创建配置文件:

        这个命令块会完成所有事情:创建密钥目录、从你指定的路径复制密钥、设置权限、最后创建指向阿里云镜像源并正确关联密钥的配置文件。

        # 确保目标目录存在
        sudo install -m 0755 -d /etc/apt/keyrings
        # 从您指定的正确路径复制密钥文件
        sudo cp /bigdata/xxx/docker.gpg /etc/apt/keyrings/docker.gpg
        # 确保密钥文件权限正确
        sudo chmod a+r /etc/apt/keyrings/docker.gpg
        # 创建指向正确密钥和阿里云镜像的配置文件
        echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
        
        
  3. 执行安装

    # 更新软件包列表,这次会从阿里云成功获取
    sudo apt-get update
    # 安装 Docker 及其所有推荐组件
    sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    
    
步骤 1.3:安装后配置
  1. 将当前用户添加到 docker 组 (免 sudo)

    sudo usermod -aG docker ${USER}
    
    
  2. 应用变更: 再次强调,必须退出服务器并重新 SSH 登录,用户组变更才会生效。重新登录后,就可以直接使用 docker 命令了。

第二部分:镜像管理

步骤 2.1:从本地 .tar 文件加载镜像
  1. 上传: 使用 scp 将你的 .tar 镜像文件(如 123.tar)上传到服务器。

  2. 加载: 使用 docker load 命令将其加载到 Docker 中。

    docker load -i /path/to/your/image.tar
    
    
  3. 验证: 使用 docker images 查看已加载的镜像。

步骤 2.2:从 Dockerfile 构建镜像
  1. 准备文件: 将 Dockerfile 以及所有需要 COPY 的文件(如 env.yaml)都放在服务器的同一个项目文件夹内。

  2. 执行构建: 在该文件夹内,执行 docker build 命令。

    # -f 指定 Dockerfile 文件名
    # -t 给镜像起一个名字和标签 (repository:tag)
    # . 表示使用当前目录作为构建上下文
    docker build -f Dockerfile.gpu -t my-app:latest .
    
    
  3. 常见构建问题排查 (以 Conda 为例):

    • 问题: Conda 提示“服务条款未接受 (Terms of Service have not been accepted)”。

    • 解决方案: 在 Dockerfile 中,conda env create 之前,加入专用的接受条款命令。

      # ... 安装 Miniconda 之后 ...
      
      # 使用 conda tos accept 命令接受默认仓库的服务条款
      RUN conda run -n base conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main && \
          conda run -n base conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r
      
      # ... 然后再 COPY env.yaml 并执行 conda env create ...
      
      

第三部分:运行与管理容器(以开发为目的)

步骤 3.1:编写一个健壮的 docker run 命令

一个好的启动命令是稳定运行的基石。以下是一个针对复杂应用(GPU、音频、代码挂载)的优秀模板。

docker run -d \
  --name my-app-container \
  --restart unless-stopped \
  --gpus all \
  --net=host \
  -v /path/on/host/project_code:/workspace \
  -v /etc/timezone:/etc/timezone:ro \
  -v /etc/localtime:/etc/localtime:ro \
  --device /dev/snd \
  --group-add $(getent group audio | cut -d: -f3) \
  -v /run/user/$(id -u)/pulse/native:/run/user/$(id -u)/pulse/native \
  -e PULSE_SERVER=unix:/run/user/$(id -u)/pulse/native \
  -v ~/.config/pulse/cookie:/root/.config/pulse/cookie \
  my-app:latest

  • --restart unless-stopped: 服务器重启后容器会自动运行。

  • --gpus all: GPU 应用标准配置。自动处理所有驱动和设备。

  • -v /path/on/host/...:/workspace: 代码同步。将宿主机的代码目录挂载到容器,实现热更新。

  • --net=host 及所有音频相关参数 (--device, --group-add, pulse 等): 音频应用标准配置,让容器能使用宿主机的声卡。

  • 注意: 我们移除了不稳定的 -v /tmp/audio_pipe:/tmp/audio_pipe 挂载。

步骤 3.2:日常容器管理命令
  • docker ps: 查看正在运行的容器。

  • docker ps -a: 查看所有容器(包括已停止的)。

  • docker start <容器名>: 启动一个已停止的容器。

  • docker stop <容器名>: 停止一个正在运行的容器。

  • docker rm <容器名>: 删除一个已停止的容器。

  • docker logs <容器名>: 查看容器的日志,排查错误的首选。

  • docker exec -it <容器名> bash: 进入容器内部进行交互式操作。

第四部分:理解 Docker 环境的核心概念

步骤 4.1:为什么容器“系统版本”看起来不对?
  • 现象: 在基于 Ubuntu 22.04 镜像的容器内执行 uname -a,却显示出宿主机 Ubuntu 20.04 的内核信息。

  • 原因: Docker 容器与宿主机共享同一个 Linux 内核uname 命令显示的是内核版本,而不是容器内的库和文件系统(用户空间)版本。

步骤 4.2:如何正确查看容器的系统版本?

在容器内部执行以下任一命令:

# 方法一:详细信息
cat /etc/os-release

# 方法二:简洁信息
lsb_release -a

输出会明确显示容器内部的发行版信息,例如 Ubuntu 22.04.x LTS

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐