第 7 節

Manually create a Docker image

0瀏覽次數0訪問次數--跳出率--平均停留

Docker 镜像是通过 Dockerfile 文件来构建的。该文件没有任何扩展名,文件名固定为 Dockerfile

从本质上来说,Dockerfile 可以看作是一份用于自动化构建镜像的脚本文件。我们在日常使用 Linux 系统时,在终端中执行的各种安装、配置命令(例如安装软件、修改环境变量等),都可以按照一定的语法规则写入到 Dockerfile 中。

不过,这些普通的 Shell 命令需要配合 Docker 提供的特定指令(如 RUNCOPYENV 等)一起使用,Docker 才能够正确解析并执行这些步骤。构建镜像的过程,本质上就是按照 Dockerfile 中定义的指令,从上到下一步步执行,最终生成一个可用的镜像。

通过这种方式,我们可以将环境配置过程标准化、自动化,从而实现环境的一致性与可复现性。

下面列出了一些常用的 Dockerfile 指令及其作用:

DockerFile常用命令

|command|Explanation|Here is the translation of the provided Simplified Chinese Markdown fragment into natural American English, following all specified rules.


Example| |:---|:---|:---| |FROM|Specify the base image, which is the starting point of the Dockerfile.|FROM ubuntu:22.04| |LABEL|Add metadata (such as author, version, etc.)|LABEL maintainer="you@example.com"| |ENV|Set environment variables|ENV PORT=8080| |ARG|Build parameters, only available during the build process.|ARG VERSION=1.0| |RUN|When building the image, run the command|RUN apt-get update && apt-get install -y curl| |COPY|Copy files into the image|COPY . /app| |ADD|Similar to COPY, with additional support for extracting .tar files or remote URLs (not recommended for URLs).|ADD archive.tar.gz /data/| |WORKDIR|Set the working directory|WORKDIR /opt| |CMD|Set the default command when the container starts (can be overridden by docker run).|CMD "node", "index.js"| |ENTRYPOINT|Set a fixed command when the container starts (commonly used for CLI tools, etc.)|ENTRYPOINT "python3"| |EXPOSE|Declare the ports that services inside the image listen on (will not be automatically mapped).|EXPOSE 80| |VOLUME|Declare the data volume mount point|VOLUME "/data"| |USER|Set the user for subsequent command execution.|USER appuser| |ONBUILD|Build instructions triggered when an image is used as the base image for other images.|ONBUILD COPY . /src| |SHELL|Change the default shell, for example, change sh -c to bash -c.|SHELL "/bin/bash", "-c"| |HEALTHCHECK|Define the health check command for the container runtime.|HEALTHCHECK CMD curl --fail http://localhost:8080| |STOPSIGNAL|Signal sent when the container stops|STOPSIGNAL SIGKILL|

Create your own container

Manually created

首先创建一个文件夹来存放你的Dockerfile

比如我在~/UserFolder/MySource/下创建了一个MyDocker文件夹.

创建好后,在个文件夹下打开vscode.

cd ~/UserFolder/MySource/MyDocker
code .

在VScode插件中安装Dev Containers,Container Tools这俩插件.

alt text

  1. Plugin 1: Microsoft Docker Tool

The Docker extension plugin has evolved into Container Tools. Please install Container Tools.

  1. Plugin 2: Microsoft Docker Remote Development Tool

Below is the plugin for remote development.

接下来创建Dockerfile文件:

alt text

我们创建一个最简单的X86架构的镜像,这个镜像的内容是:

  1. 基于Ubuntu24.04系统的镜像
  1. 自带CUDA和CuDNN
  1. 默认Shell环境为bash
  1. 换源为国内镜像源
  1. Shell添加上丰富的颜色
# 基于NVIDIA官方CUDA 12.6和CuDNN基础镜像
FROM nvidia/cuda:12.6.0-cudnn-devel-ubuntu24.04

# 设置环境变量以防止交互安装
ENV DEBIAN_FRONTEND=noninteractive

# 强制使用 Bash 作为默认 Shell
SHELL ["/bin/bash", "-c"]

# 先更新包列表并安装CA证书
RUN apt-get update && apt-get install -y ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# 替换为清华大学的DEB822格式镜像源
RUN sed -i 's|http://archive.ubuntu.com/ubuntu/|https://mirrors.tuna.tsinghua.edu.cn/ubuntu/|g' /etc/apt/sources.list.d/ubuntu.sources

# 配置终端颜色和提示符
RUN sed -i 's/#force_color_prompt=yes/force_color_prompt=yes/g' /root/.bashrc && \
    # 自定义PS1(带颜色的提示符)
    echo 'export PS1="\[\033[1;36m\]\u@\h\[\033[00m\]:\[\033[1;34m\]\w\[\033[00m\]\$ "' >> /root/.bashrc && \
    # 给ls、grep等命令添加别名
    echo "alias ls='ls --color=auto'" >> /root/.bashrc && \
    echo "alias grep='grep --color=auto'" >> /root/.bashrc && \
    echo "alias ll='ls -alFh --color=auto'" >> /root/.bashrc && \
    # 清理临时文件
    rm -rf /tmp/LS_COLORS

alt text

在x86电脑上编译x86的镜像(一定要有科学的网络环境,不然拉取不了英伟达的镜像):

命令格式为docker build -t 镜像名称 .

比如:

docker build -t ubuntu24_cuda126_cudnn:latest .

alt text

然后使用docker images命令查看编译好的镜像.

alt text

运行此镜像

使用run命令的参数非常重要里的run命令来运行创建好的镜像.

应该把--name修改为你要创建的容器的名字,比如ubuntu24cuda126,然后最底下那行应该写你刚才创建的镜像的名字,比如ubuntu24_cuda126_cudnn:latest.

对应本教程的命令应该为:

sudo docker run --name=ubuntu24cuda126 \
--gpus all \
-e NVIDIA_DRIVER_CAPABILITIES=all \
-e DISPLAY=$DISPLAY \
-dit \
--privileged \
--net=host \
--group-add audio \
--group-add video \
--group-add dialout \
-e XAUTHORITY=$HOME/.Xauthority \
-e WAYLAND_DISPLAY=$WAYLAND_DISPLAY \
-e XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR \
-e QT_QPA_PLATFORM=xcb \
-v /tmp/.X11-unix:/tmp/.X11-unix:rw \
-v /dev/dri:/dev/dri \
-v $HOME/.Xauthority:$HOME/.Xauthority:ro \
-v /run/user/$(id -u)/wayland-0:/run/user/$(id -u)/wayland-0 \
-v /run/user/$(id -u):/run/user/$(id -u) \
-v $HOME:$HOME \
-w $HOME \
ubuntu24_cuda126_cudnn:latest

出现下列这一行,代表成功了.

alt text

可以在VScode的插件里看到容器已经成功运行.

alt text

打开容器里的Ubuntu24系统的终端

命令格式为docker exec -it 容器名称 bash

比如:

docker exec -it ubuntu24cuda126 bash

如下图你已经进入了容器里的Ubuntu24系统的终端了.

alt text

接下来可以安装一个neofetch测试一下.

注意,你这里已经是在root的身份下运行Ubuntu24系统的终端了,所以不需要每条命令前加sudo了,比如sudo apt update可以直接用apt update代替.

apt update
apt install neofetch
neofetch

alt text

然后可以顺便测试下英伟达驱动和CUDA以及CuDNN的安装情况:

nvidia-smi
nvcc -V
cat /usr/include/cudnn_version.h | grep CUDNN_MAJOR -A 2

如下图可知,容器中的Ubuntu24共享了宿主的英伟达驱动,版本为595.80.

自带CUDA12.6与CuDNN9.3.0

alt text

将镜像推送至Docker Hub

The steps to push a Docker image to Docker Hub are as follows:

  1. Create a Docker Hub account

If you don't already have a Docker Hub account, please go to Docker Hub to register a free account.

  1. Log in to Docker Hub

In the terminal, use the following command to log in to your Docker Hub account:

docker login

Enter your Docker Hub username and password for verification.

  1. Tag your image

Docker Hub uses the format <用户名>/<镜像名>:<标签> to identify images. You need to tag your image so it can be pushed to Docker Hub. Use the following command:

docker tag 镜像名:标签 <你的用户>/新镜像名:标签

For example, if your Docker Hub username is tungchiahui, you should run:

docker tag ubuntu24_cuda126_cudnn:latest tungchiahui/ubuntu24_cuda126_cudnn:latest
  1. Push the image to Docker Hub

Use the following command to push the image to Docker Hub:

docker push <你的用户>/镜像名:标签

For example:

docker push tungchiahui/ubuntu24_cuda126_cudnn:latest
  1. Verify the push was successful.

You can verify whether your image has been successfully pushed by visiting your personal page on Docker Hub.

Notes

  • Make sure your image size stays within Docker Hub's limits (typically 10GB).
  • If you plan to make the image public, you can set it as a public repository; if you want only yourself to have access, you can set it as a private repository.

手动创建(跨平台多架构构建)(高阶的,暂时不用学)

If you want to build images on an x86/x64 computer (i.e., native x86 devices) and also build Docker images for ARM64 devices like Raspberry Pi, Jetson, etc. , you need to use Docker's cross-platform build functionality. Here is the complete solution:


启用 Docker 跨平台构建

To simulate an ARM64 environment on an x86 host, the following tools are required:

  1. 启用 buildx(只需执行一次)
docker buildx create --name multiarch_builder --use

This will create and enable a builder that supports multi-architecture builds, and it will persist even after a computer restart, so it only needs to be run once.

  1. 安装 QEMU 支持(一般新版 Docker Desktop 已自带,但是Linux必须要安装) 如果你用的是服务器或Linux发行版,确保有 qemu 模拟器:
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes

After restarting your computer, it will disappear, so you need to run this command once after each restart, before the buildx command.

  1. 修改dockerfile为多架构版本
# 支持多架构,使用变量指定架构
ARG TARGETARCH

# 基于NVIDIA官方CUDA 12.6和CuDNN基础镜像
FROM --platform=linux/${TARGETARCH} nvidia/cuda:12.6.0-cudnn-devel-ubuntu24.04

# 设置环境变量以防止交互安装
ENV DEBIAN_FRONTEND=noninteractive

# 强制使用 Bash 作为默认 Shell
SHELL ["/bin/bash", "-c"]

# 先更新包列表并安装CA证书
RUN apt-get update && apt-get install -y ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# 替换为清华大学的DEB822格式镜像源
RUN if [ "$(dpkg --print-architecture)" = "amd64" ]; then \
        sed -i 's|http://archive.ubuntu.com/ubuntu/|https://mirrors.tuna.tsinghua.edu.cn/ubuntu/|g' /etc/apt/sources.list.d/ubuntu.sources; \
    elif [ "$(dpkg --print-architecture)" = "arm64" ]; then \
        sed -i 's|http://ports.ubuntu.com/ubuntu-ports/|https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/|g' /etc/apt/sources.list.d/ubuntu.sources; \
    fi

# 配置终端颜色和提示符
RUN sed -i 's/#force_color_prompt=yes/force_color_prompt=yes/g' /root/.bashrc && \
    # 自定义PS1(带颜色的提示符)
    echo 'export PS1="\[\033[1;36m\]\u@\h\[\033[00m\]:\[\033[1;34m\]\w\[\033[00m\]\$ "' >> /root/.bashrc && \
    # 给ls、grep等命令添加别名
    echo "alias ls='ls --color=auto'" >> /root/.bashrc && \
    echo "alias grep='grep --color=auto'" >> /root/.bashrc && \
    echo "alias ll='ls -alFh --color=auto'" >> /root/.bashrc && \
    # 清理临时文件
    rm -rf /tmp/LS_COLORS
  1. 构建多架构镜像 用下面的命令构建 amd64 和 arm64:
docker buildx build --platform linux/amd64,linux/arm64 -t <你的镜像>:<> --push .

例子:

docker buildx build \
--platform linux/amd64,linux/arm64 \
 -t tungchiahui/ubuntu24_cuda126_cudnn:latest \
 --push \
 .

Note: --platform specifies multi-architecture. --push is required because buildx's multi-platform builds cannot be loaded locally by default (unless --load is added, but that only supports a single architecture).

Clear build cache

# 清理BuildKit构建缓存
docker builder prune -f

音乐页