目 录CONTENT

文章目录
AI

AI 开发通用 Docker 镜像包

解小风
2025-05-08 / 0 评论 / 5 点赞 / 145 阅读 / 0 字

构建通用镜像包

1、构建镜像

# (Step 0)环境需求
Docker_v20+
Docker-Compose_v2.0+
# (Step 1)准备 Dockerfile 文件

######### ./AI_DEV_Build/Dockerfile #########
# 以 ubuntu2204+cuda124 基础镜像为例
FROM nvidia/cuda:12.4.1-cudnn-devel-ubuntu22.04

# 配置环境变量
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8 \
    TZ=Asia/Shanghai \
    DEBIAN_FRONTEND=noninteractive \
    PATH=/opt/conda/bin:$PATH

# 配置系统基础
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
    echo $TZ > /etc/timezone && \
    rm -rf /etc/apt/sources.list.d/* && \
    apt-get update --fix-missing

# 安装核心工具集
# 1. 基础运维工具
RUN apt-get install -y --no-install-recommends \
    ca-certificates \
    wget \
    curl \
    git \
    gnupg \
    apt-transport-https \
    software-properties-common \
    lsb-release \
    && apt-get clean

# 2. 开发编译工具链
# build-essential 包含 gcc/g++/make
RUN apt-get install -y --no-install-recommends \
    build-essential \
    cmake \
    libboost-all-dev \
    ninja-build \
    pkg-config \
    zlib1g-dev \
    libssl-dev \
    libffi-dev \
    libsqlite3-dev \
    libbz2-dev \
    liblzma-dev \
    libreadline-dev \
    && apt-get clean

# 3. 系统调试工具
RUN apt-get install -y --no-install-recommends \
    htop \
    lsof \
    strace \
    ltrace \
    gdb \
    valgrind \
    sysstat \
    && apt-get clean

# 4. 网络工具
RUN apt-get install -y --no-install-recommends \
    net-tools \
    iputils-ping \
    traceroute \
    dnsutils \
    tcpdump \
    && apt-get clean

# 5. 文本/终端工具
RUN apt-get install -y --no-install-recommends \
    vim \
    tmux \
    tree \
    jq \
    rsync \
    zip \
    unzip \
    && apt-get clean

# 安装 FFmpeg 全家桶
RUN apt-get install -y --no-install-recommends \
    ffmpeg \
    libavcodec-dev \
    libavformat-dev \
    libswscale-dev \
    libavutil-dev \
    libpostproc-dev \
    libx264-dev \
    libx265-dev \
    && apt-get clean

# 安装 Miniconda
# 复制本地 miniconda3 安装脚本到镜像中
COPY ./miniconda3-linux-x86.sh /tmp/miniconda.sh
# 运行安装脚本
RUN /bin/bash /tmp/miniconda.sh -b -p /opt/conda && \
    rm /tmp/miniconda.sh && \
    /opt/conda/bin/conda clean -y --all
# 初始化(设置 .bashrc 文件,在 shell 启动时自动激活 conda 的基础环境)
# 解决非交互式 shell 的问题
RUN echo "source /opt/conda/etc/profile.d/conda.sh" >> ~/.bashrc && \
    echo "conda activate base" >> ~/.bashrc && \
    echo "source /opt/conda/etc/profile.d/conda.sh" >> /etc/profile.d/conda.sh

# 安装 Supervisor
RUN apt-get install -y --no-install-recommends \
    supervisor \
    && apt-get clean
# 初始化主配置文件
RUN echo_supervisord_conf > /etc/supervisor/supervisord.conf && \
    echo "\n[include]\nfiles = /etc/supervisor/conf.d/*.conf" >> /etc/supervisor/supervisord.conf
# 初始化子配置文件
RUN mkdir -p /etc/supervisor/conf.d && \
    echo "; [program:my_project]\n\
; directory=/path/to/my_project\n\
; command=/path/to/my_project/python --arg1 value1\n\
; stopsignal=TERM\n\
; stopwaitsecs=60\n\
; autostart=true\n\
; autorestart=true\n\
; startsecs=30\n\
; user=root\n\
; redirect_stderr=true\n\
; stdout_logfile=/path/to/my_project.log\n\
; stdout_logfile_maxbytes=20MB\n\
; stdout_logfile_backups=50\n\
; stderr_logfile=/path/to/my_project_error.log\n\
; stderr_logfile_maxbytes=20MB\n\
; stderr_logfile_backups=50\n\
; environment=CUDA_VISIBLE_DEVICES='0'\n" > /etc/supervisor/conf.d/ai_dev.conf

# 最后统一清理
RUN apt-get autoremove -y && \
    apt-get clean

# 工作目录设置
WORKDIR /app

# 启动命令(Supervisor 随容器启动)
CMD ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]
##############################
# (Step 2)准备 docker-compose.yml 文件

######### ./AI_DEV_Build/docker-compose.yml #########
version: '3.8'
services:
  ai-dev:
    # 构建镜像
    build: .
    # 自行起一个镜像名
    image: faramita/ai-dev:x86-ubuntu2204-cuda12.4.1-cudnn-ffmpeg
    # 分配给容器的共享内存
    shm_size: 4g
    # 工作目录
    working_dir: /app
    # 开启 TTY(终端)
    tty: true
    # 保持标准输入(stdin)对容器开放
    stdin_open: true
##############################
# (Step 3)构建镜像

# 准备 miniconda3 安装包(因 Dockerfile 文件中指定使用)
# ./AI_DEV_Build/miniconda3-linux-x86.sh

# 构建镜像
sudo docker-compose build --no-cache

2、验证镜像

# 启动交互式终端容器进行镜像验证
# 无 GPU 环境
sudo docker run -it --rm --shm-size=4g faramita/ai-dev:x86-ubuntu2204-cuda12.4.1-cudnn-ffmpeg /bin/bash

# 有 GPU 环境(已正确安装配置 NVIDIA 驱动 和 NVIDIA Container Toolkit)
sudo docker run -it --rm --gpus all --shm-size=4g faramita/ai-dev:x86-ubuntu2204-cuda12.4.1-cudnn-ffmpeg /bin/bash
# 验证镜像内各内置工具(参考 Dockerfile 中安装的工具和软件)

# 验证 CUDA(需正确安装配置 NVIDIA 驱动 和 NVIDIA Container Toolkit)
nvcc --version

# 验证 FFmpeg
ffmpeg -version

# 验证 Conda
conda --version

# 验证 Tmux
tmux -V

# 验证 Supervisor
supervisorctl status
# 若出现以下报错为正常情况:
unix:///tmp/supervisor.sock no such file
# 因为 docker run ... /bin/bash 启动会覆盖 CMD 命令,导致 supervisor 不会随之启动
# 正常启动容器后,再进入容器验证 supervisor,不会存在此情况

3、导出镜像

# 保存通用镜像包到 tar 文件并传输到目标服务器
sudo docker save -o docker-image-faramita-ai-dev_x86-ubuntu2204-cuda12.4.1-cudnn-ffmpeg.tar faramita/ai-dev:x86-ubuntu2204-cuda12.4.1-cudnn-ffmpeg

使用通用镜像包

宿主机不需要安装 CUDA12.4,但需确保:

1、正确安装 NVIDIA 驱动并确保驱动版本支持 CUDA12.4

2、正确安装和配置 NVIDIA Container Toolkit(参见附录)

1、导入镜像

# 导入镜像
sudo docker load --input docker-image-faramita-ai-dev_x86-ubuntu2204-cuda12.4.1-cudnn-ffmpeg.tar

# 验证镜像
sudo docker images

2、运行镜像

# (Step 0)环境需求
Docker_v20+
Docker-Compose_v2.0+

# (Step 1)相关资源准备
# 项目代码文件放入 my_project
mkdir -p ./AI_DEV_Run/my_project
# 项目 supervisor 配置文件放入 my_supervisor
mkdir -p ./AI_DEV_Run/my_supervisor
# 项目缓存文件放入 my_cache
mkdir -p ./AI_DEV_Run/my_cache
cd ./AI_DEV_Run
# (Step 2)准备 docker-compose.yml 文件

######### ./AI_DEV_Run/docker-compose.yml #########
version: '3.8'
services:
  ai-dev:
    image: faramita/ai-dev:x86-ubuntu2204-cuda12.4.1-cudnn-ffmpeg
    container_name: AI-DEV-X86-CUDA1241
    restart: always
    privileged: true
    volumes:
      # 容器内 /app 文件夹 映射到 宿主机项目代码文件夹
      - ./my_project:/app
      # 容器内 supervisor 配置文件夹 映射到 宿主机项目配置文件夹
      - ./my_supervisor:/etc/supervisor/conf.d
      # 容器内 /root/.cache 缓存文件夹 映射到 宿主机项目缓存文件夹
      - ./my_cache:/root/.cache
    environment:
      # 指定了 NVIDIA GPU 驱动在容器中可以使用的功能
      #     compute:允许容器使用GPU进行计算操作
      #     utility:提供一些工具和库的支持,如 nvidia-smi
      - NVIDIA_DRIVER_CAPABILITIES=compute,utility
      # 控制物理设备可见性(指定可见的 GPU 设备)
      - NVIDIA_VISIBLE_DEVICES=0
      # 指定 CUDA 运行时可见设备
      - CUDA_VISIBLE_DEVICES=0
    # 容器启动时同时启动 supervisor,来管理所有服务(容器内所有服务都应通过 *.conf 来配置启动)
    command: ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]
    # deploy.resources.reservations.devices 用于指定 GPU 相关配置
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              capabilities: [gpu]
    # 分配给容器的共享内存
    shm_size: 8g
    # 工作目录
    working_dir: /app
    # 开启 TTY(终端)
    tty: true
    # 保持标准输入(stdin)对容器开放
    stdin_open: true
##############################
# (Step 3)一键启动
sudo docker-compose up -d

定制项目镜像包

同上,先确保宿主机:

1、正确安装 NVIDIA 驱动并确保驱动版本支持 CUDA12.4

2、正确安装和配置 NVIDIA Container Toolkit(参见附录)

1、导入通用镜像

# 导入镜像
sudo docker load --input docker-image-faramita-ai-dev_x86-ubuntu2204-cuda12.4.1-cudnn-ffmpeg.tar

# 验证镜像
sudo docker images

2、运行通用镜像

# (Step 0)环境需求
Docker_v20+
Docker-Compose_v2.0+

# (Step 1)相关资源准备
# 将所有需要打包进镜像的文件(项目代码文件除外),放入 my_files 文件夹
mkdir -p ./DIY_Run/my_files
cd ./DIY_Run
# (Step 2)准备 docker-compose.yml 文件

######### ./DIY_Run/docker-compose.yml #########
version: '3.8'
services:
  ai-dev:
    image: faramita/ai-dev:x86-ubuntu2204-cuda12.4.1-cudnn-ffmpeg
    container_name: AI-DEV-X86-CUDA1241
    restart: always
    privileged: true
    volumes:
      # 容器内 /home 文件夹 映射到 宿主机资源文件夹
      - ./my_files:/home
    environment:
      # 指定了 NVIDIA GPU 驱动在容器中可以使用的功能
      #     compute:允许容器使用GPU进行计算操作
      #     utility:提供一些工具和库的支持,如 nvidia-smi
      - NVIDIA_DRIVER_CAPABILITIES=compute,utility
      # 控制物理设备可见性(指定可见的 GPU 设备)
      - NVIDIA_VISIBLE_DEVICES=0
      # 指定 CUDA 运行时可见设备
      - CUDA_VISIBLE_DEVICES=0
    # 容器启动时同时启动 supervisor,来管理所有服务(容器内所有服务都应通过 *.conf 来配置启动)
    command: ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]
    # deploy.resources.reservations.devices 用于指定 GPU 相关配置
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              capabilities: [gpu]
    # 分配给容器的共享内存
    shm_size: 8g
    # 工作目录
    working_dir: /app
    # 开启 TTY(终端)
    tty: true
    # 保持标准输入(stdin)对容器开放
    stdin_open: true
##############################
# (Step 3)一键启动通用镜像
sudo docker-compose up -d

3、生成定制镜像

整体流程

# (Step 1)进入通用镜像容器内部
sudo docker exec -it {容器ID} /bin/bash

# (Step 2)使用通用镜像容器内置工具部署项目环境依赖,如:
# apt 安装所需软件(如 Redis, MySQL 等)
# conda/pip 下载/安装 环境依赖
# 确保项目所需的环境依赖准备完毕后,退出容器
exit

# (Step 3)停止镜像运行
sudo docker stop {容器ID}

# (Step 4)提交容器更改以创建新镜像
# sudo docker commit {容器ID} {自定义镜像名:Tag}
sudo docker commit 69248e8a38da ai/voice:v1.0

# (Step 5)导出定制镜像包到 tar 文件并传输到目标服务器
sudo docker save -o docker-image-ai-voice_v1.0.tar ai/voice:v1.0

完整示例:容器内安装 Redis

# (Step 1)进入通用镜像容器内部
sudo docker exec -it 69248e8a38da /bin/bash
# (Step 2)容器内安装 Redis

# (1)安装 Redis
apt update
apt install -y redis-server

# (2)修改配置
vim /etc/redis/redis.conf
######### /etc/redis/redis.conf #########
# 依次寻找以下配置项进行修改配置
# 在 Docker 容器中,Redis 应该以 前台模式 运行(daemonize no),而不是后台守护进程模式(daemonize yes)。当设置 daemonize yes 时,Redis 会尝试在后台运行,但 Docker 会认为主进程已经完成,从而立即停止容器。
daemonize no
# 持久化数据
dir /data/redis
# 保存数据
save 900 1
# 设置密码
requirepass faramita1012
##############################

# (3)新建并赋权持久化数据文件夹
mkdir -p /data/redis
chown redis:redis /data/redis

# (4)退出容器
exit
# (Step 3)停止镜像运行
sudo docker stop 69248e8a38da

# (Step 4)提交容器更改以创建新镜像
sudo docker commit 69248e8a38da ai/voice:v1.0

# (Step 5)导出定制镜像包到 tar 文件并传输到目标服务器
sudo docker save -o docker-image-ai-voice_v1.0.tar ai/voice:v1.0

完整示例:容器内安装 MySQL

# (Step 1)进入通用镜像容器内部
sudo docker exec -it 69248e8a38da /bin/bash
# (Step 2)容器内安装 MySQL
# (1)安装 MySQL
apt update
apt install -y mysql-server

# (2)修改配置
vim /etc/mysql/mysql.conf.d/mysqld.cnf
######### /etc/mysql/mysql.conf.d/mysqld.cnf #########
# 清空所有内容,配置如下内容
[mysqld]
# 用户名
user = mysql
# pid 和 socket 文件路径
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
# 端口号
port = 3306
# 持久化数据目录(后续挂载到宿主机)
datadir = /var/lib/mysql
# 允许所有 IP 连接(容器环境需要)
bind-address = 0.0.0.0
# 关闭域名解析,加速连接
skip-name-resolve
# 设置字符集
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# 错误日志
log_error = /var/log/mysql/error.log
##############################

# (3)创建 entrypoint 脚本
# 作用:容器启动时自动检测 MySQL 数据目录是否为空(首次挂载空目录的情况),为空则自动初始化 MySQL 系统库并设置 root 密码(以 faramita1012 为例),类似官方 mysql:8.0 镜像的行为。
vim /usr/local/bin/docker-entrypoint.sh
######### /usr/local/bin/docker-entrypoint.sh #########
#!/bin/bash

# 仅当 MYSQL_INIT_ENABLED=true 时,才执行 MySQL 相关初始化
if [ "$MYSQL_INIT_ENABLED" = "true" ]; then
    # 确保运行时目录存在
    mkdir -p /var/run/mysqld
    chown mysql:mysql /var/run/mysqld
    mkdir -p /var/log/mysql
    chown mysql:mysql /var/log/mysql

    # 如果 MySQL 数据目录为空,执行初始化
    if [ -z "$(ls -A /var/lib/mysql 2>/dev/null)" ]; then
        echo "[Entrypoint] Empty MySQL datadir detected, initializing..."

        # 初始化 MySQL 系统库(--initialize-insecure 表示 root 初始无密码)
        mysqld --initialize-insecure --user=mysql --datadir=/var/lib/mysql
        
        # 临时启动 MySQL(仅本地访问,用于设置密码)
        mysqld --user=mysql --skip-networking &
        pid=$!
        
        # 等待 MySQL 就绪(最多等 30 秒)
        for i in $(seq 1 30); do
            if mysqladmin ping --socket=/var/run/mysqld/mysqld.sock &>/dev/null; then
                break
            fi
            sleep 1
        done
        
        # 设置 root 密码并开启远程访问
        mysql --socket=/var/run/mysqld/mysqld.sock -u root <<-EOSQL
            ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'faramita1012';
            CREATE USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'faramita1012';
            GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
            FLUSH PRIVILEGES;
EOSQL
        
        # 停止临时 MySQL
        mysqladmin -u root -pfaramita1012 shutdown
        wait $pid

        echo "[Entrypoint] MySQL initialized successfully. root password: faramita1012"
    fi
fi

# 执行 CMD(即 supervisord)
exec "$@"
##############################

# (4)赋予执行权限
chmod +x /usr/local/bin/docker-entrypoint.sh

# (5)退出容器
exit
# (Step 3)停止镜像运行
sudo docker stop 69248e8a38da

# (Step 4)提交容器更改以创建新镜像
sudo docker commit 69248e8a38da ai/voice:v1.0

# (Step 5)导出定制镜像包到 tar 文件并传输到目标服务器
sudo docker save -o docker-image-ai-voice_v1.0.tar ai/voice:v1.0

# 此时镜像内包含:MySQL + 配置文件 + entrypoint 脚本,但不含任何 MySQL 数据(数据由后续首次启动时自动初始化到挂载目录中)。

4、使用定制镜像

整体流程

# (Step 0)环境需求
Docker_v20+
Docker-Compose_v2.0+

# (Step 1)导入定制镜像
sudo docker load --input docker-image-ai-voice_v1.0.tar
# 验证镜像
sudo docker images

# (Step 2)按需准备项目相关资源
# 放置项目代码文件夹
./AI_Voice
sudo chmod 777 -R ./AI_Voice
# 放置项目缓存文件夹(如果有的话)
./AI_Voice_Cache
sudo chmod 777 -R ./AI_Voice_Cache
# 新建项目 supervisor 配置文件夹
mkdir -p ./AI_Voice_Supervisor  # 暂时为空
sudo chmod 777 -R ./AI_Voice_Supervisor
# (Step 3)准备 supervisor 配置文件

######### ./AI_Voice_Supervisor/ai-voice.conf #########
[program:AI_Voice-Backend]
directory=/app/App_Backend/Python_Backend
command=/opt/conda/envs/ai-voice-py310/bin/gunicorn App_Http_Server:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:15101 --timeout 300
; priority 值小的先启动
priority=20
stopsignal=TERM
stopwaitsecs=60
autostart=true
autorestart=true
startsecs=30
user=root
redirect_stderr=true
stdout_logfile=/app/App_Logs/app-backend.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=50
stderr_logfile=/app/App_Logs/app-backend_error.log
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=50
; 所需环境变量
environment=CUDA_VISIBLE_DEVICES="0"

[program:AI_Voice-Frontend]
directory=/app/App_Frontend
command=/opt/conda/envs/ai-voice-py310/bin/python App_Web_UI.py
priority=30
stopsignal=TERM
stopwaitsecs=60
autostart=true
autorestart=true
startsecs=30
user=root
redirect_stderr=true
stdout_logfile=/app/App_Logs/app-frontend.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=50
stderr_logfile=/app/App_Logs/app-frontend_error.log
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=50
##############################
# (Step 4)准备 docker-compose.yml 文件

######### ./docker-compose-ai-voice.yml #########
version: '3.8'
services:
  ai-voice:
    image: ai/voice:v1.0
    container_name: AI_Voice
    restart: always
    ports:
      # 按需映射端口
      - "12221:12221"
      - "12225:12225"
    privileged: true
    volumes:
      # 按需映射文件夹
      # 容器内 /app 文件夹 映射到 宿主机项目文件夹
      - ./AI_Voice:/app
      # 容器内 /root/.cache 缓存文件夹 映射到 宿主机缓存文件夹(如果有的话)
      - ./AI_Voice_Cache:/root/.cache
      # 容器内 supervisor 配置文件夹 映射到 宿主机配置文件夹
      - ./AI_Voice_Supervisor:/etc/supervisor/conf.d
    environment:
      # Conda 环境配置(默认使用 ai-voice-py310 虚拟环境)
      - PATH=/opt/conda/envs/ai-voice-py310/bin:/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      - PYTHONPATH=/opt/conda/envs/ai-voice-py310/lib/python3.10/site-packages
      - CONDA_DEFAULT_ENV=ai-voice-py310
      - CONDA_PREFIX=/opt/conda/envs/ai-voice-py310
      # 指定了 NVIDIA GPU 驱动在容器中可以使用的功能
      #     compute:允许容器使用GPU进行计算操作
      #     utility:提供一些工具和库的支持,如 nvidia-smi
      - NVIDIA_DRIVER_CAPABILITIES=compute,utility
      # 控制物理设备可见性(指定可见的 GPU 设备)
      - NVIDIA_VISIBLE_DEVICES=0
      # 指定 CUDA 运行时可见设备
      - CUDA_VISIBLE_DEVICES=0
    # 容器启动时同时启动 supervisor,来管理所有服务(容器内所有服务都应通过 *.conf 来配置启动)
    command: ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]
    # deploy.resources.reservations.devices 用于指定 GPU 相关配置
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              capabilities: [gpu]
    # 分配给容器的共享内存
    shm_size: 8g
    # 工作目录
    working_dir: /app
    # 开启 TTY(终端)
    tty: true
    # 保持标准输入(stdin)对容器开放
    stdin_open: true
##############################
# (Step 5)一键启动定制镜像
sudo docker-compose -f docker-compose-ai-voice.yml up -d

# 预计等待 1-3 分钟后才能全部启动完毕,此时方可测试
# 查看后端日志
./AI_Voice/App_Logs/app-backend.log
# 查看前端日志
./AI_Voice/App_Logs/app-frontend.log

完整示例:容器内置 Redis

# (Step 0)环境需求
Docker_v20+
Docker-Compose_v2.0+

# (Step 1)导入定制镜像
sudo docker load --input docker-image-ai-voice_v1.0.tar
# 验证镜像
sudo docker images

# (Step 2)按需准备项目相关资源
# 放置项目代码文件夹
./AI_Voice
sudo chmod 777 -R ./AI_Voice
# 项目代码中配置容器内置 Redis 的相关信息:
redis:
  host: "127.0.0.1"
  port: 6379
  password: "faramita1012"
  dbname: 0

# 新建项目 redis 持久化文件夹
mkdir -p ./AI_Voice_Redis # 暂时为空
sudo chmod 777 -R ./AI_Voice_Redis

# 新建项目 supervisor 配置文件夹
mkdir -p ./AI_Voice_Supervisor # 暂时为空
sudo chmod 777 -R ./AI_Voice_Supervisor
# (Step 3)准备 supervisor 配置文件

######### ./AI_Voice_Supervisor/ai-voice.conf #########
[program:AI_Voice-Redis]
command=redis-server /etc/redis/redis.conf
; priority 值小的先启动,确保 Redis 在项目服务之前启动
priority=10
stopsignal=TERM
stopwaitsecs=30
autostart=true
autorestart=true
startsecs=30
user=root
redirect_stderr=true
stdout_logfile=/app/App_Logs/app-redis.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=50
stderr_logfile=/app/App_Logs/app-redis_error.log
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=50

[program:AI_Voice-Backend]
directory=/app/App_Backend/Python_Backend
command=/opt/conda/envs/ai-voice-py310/bin/gunicorn App_Http_Server:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:15101 --timeout 300
priority=20
stopsignal=TERM
stopwaitsecs=60
autostart=true
autorestart=true
startsecs=30
user=root
redirect_stderr=true
stdout_logfile=/app/App_Logs/app-backend.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=50
stderr_logfile=/app/App_Logs/app-backend_error.log
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=50
; 所需环境变量
environment=CUDA_VISIBLE_DEVICES="0"

[program:AI_Voice-Frontend]
directory=/app/App_Frontend
command=/opt/conda/envs/ai-voice-py310/bin/python App_Web_UI.py
priority=30
stopsignal=TERM
stopwaitsecs=60
autostart=true
autorestart=true
startsecs=30
user=root
redirect_stderr=true
stdout_logfile=/app/App_Logs/app-frontend.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=50
stderr_logfile=/app/App_Logs/app-frontend_error.log
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=50
##############################
# (Step 4)准备 docker-compose.yml 文件

######### ./docker-compose-ai-voice.yml #########
version: '3.8'
services:
  ai-voice:
    image: ai/voice:v1.0
    container_name: AI_Voice
    restart: always
    ports:
      # 按需映射端口
      - "12221:12221"
      - "12222:6379"
      - "12225:12225"
    privileged: true
    volumes:
      # 按需映射文件夹
      # 容器内 /app 文件夹 映射到 宿主机项目文件夹
      - ./AI_Voice:/app
      # 容器内 /data/redis 文件夹 映射到 宿主机 Redis 持久化文件夹
      - ./AI_Voice_Redis:/data/redis
      # 容器内 supervisor 配置文件夹 映射到 宿主机配置文件夹
      - ./AI_Voice_Supervisor:/etc/supervisor/conf.d
    environment:
      # Conda 环境配置(默认使用 ai-voice-py310 虚拟环境)
      - PATH=/opt/conda/envs/ai-voice-py310/bin:/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      - PYTHONPATH=/opt/conda/envs/ai-voice-py310/lib/python3.10/site-packages
      - CONDA_DEFAULT_ENV=ai-voice-py310
      - CONDA_PREFIX=/opt/conda/envs/ai-voice-py310
      # 指定了 NVIDIA GPU 驱动在容器中可以使用的功能
      #     compute:允许容器使用GPU进行计算操作
      #     utility:提供一些工具和库的支持,如 nvidia-smi
      - NVIDIA_DRIVER_CAPABILITIES=compute,utility
      # 控制物理设备可见性(指定可见的 GPU 设备)
      - NVIDIA_VISIBLE_DEVICES=0
      # 指定 CUDA 运行时可见设备
      - CUDA_VISIBLE_DEVICES=0
    # 容器启动时同时启动 supervisor,来管理所有服务(容器内所有服务都应通过 *.conf 来配置启动)
    command: ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]
    # deploy.resources.reservations.devices 用于指定 GPU 相关配置
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              capabilities: [gpu]
    # 分配给容器的共享内存
    shm_size: 8g
    # 工作目录
    working_dir: /app
    # 开启 TTY(终端)
    tty: true
    # 保持标准输入(stdin)对容器开放
    stdin_open: true
##############################
# (Step 5)一键启动定制镜像
sudo docker-compose -f docker-compose-ai-voice.yml up -d

# 预计等待 1-3 分钟后才能全部启动完毕,此时方可测试
# 查看 Redis 日志
./AI_Voice/App_Logs/app-redis.log
# 查看后端日志
./AI_Voice/App_Logs/app-backend.log
# 查看前端日志
./AI_Voice/App_Logs/app-frontend.log

完整示例:容器内置 MySQL

# (Step 0)环境需求
Docker_v20+
Docker-Compose_v2.0+

# (Step 1)导入定制镜像
sudo docker load --input docker-image-ai-voice_v1.0.tar
# 验证镜像
sudo docker images

# (Step 2)按需准备项目相关资源
# 放置项目代码文件夹
./AI_Voice
sudo chmod 777 -R ./AI_Voice
# 项目代码中配置容器内置 MySQL 的相关信息:
mysql:
  host: "127.0.0.1"
  port: 3306
  user: "root"
  password: "faramita1012"

# 新建项目 mysql 配置文件夹
mkdir -p ./AI_Voice_MySQL/data # 暂时为空
mkdir -p ./AI_Voice_MySQL/log # 暂时为空
sudo chmod 777 -R ./AI_Voice_MySQL

# 新建项目 supervisor 配置文件夹
mkdir -p ./AI_Voice_Supervisor # 暂时为空
sudo chmod 777 -R ./AI_Voice_Supervisor
# (Step 3)准备 supervisor 配置文件

######### ./AI_Voice_Supervisor/ai-voice.conf #########
[program:AI_Voice-MySQL]
command=/usr/sbin/mysqld --user=mysql
; priority 值小的先启动,确保 MySQL 在项目服务之前启动
priority=10
stopsignal=TERM
stopwaitsecs=30
autostart=true
autorestart=true
startsecs=30
user=root
redirect_stderr=true
stdout_logfile=/app/App_Logs/app-mysql.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=50
stderr_logfile=/app/App_Logs/app-mysql_error.log
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=50

[program:AI_Voice-Backend]
directory=/app/App_Backend/Python_Backend
command=/opt/conda/envs/ai-voice-py310/bin/gunicorn App_Http_Server:app --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:15101 --timeout 300
priority=20
stopsignal=TERM
stopwaitsecs=60
autostart=true
autorestart=true
startsecs=30
user=root
redirect_stderr=true
stdout_logfile=/app/App_Logs/app-backend.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=50
stderr_logfile=/app/App_Logs/app-backend_error.log
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=50
; 所需环境变量
environment=CUDA_VISIBLE_DEVICES="0"

[program:AI_Voice-Frontend]
directory=/app/App_Frontend
command=/opt/conda/envs/ai-voice-py310/bin/python App_Web_UI.py
priority=30
stopsignal=TERM
stopwaitsecs=60
autostart=true
autorestart=true
startsecs=30
user=root
redirect_stderr=true
stdout_logfile=/app/App_Logs/app-frontend.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=50
stderr_logfile=/app/App_Logs/app-frontend_error.log
stderr_logfile_maxbytes=20MB
stderr_logfile_backups=50
##############################
# (Step 4)准备 docker-compose.yml 文件

######### ./docker-compose-ai-voice.yml #########
version: '3.8'
services:
  ai-voice:
    image: ai/voice:v1.0
    container_name: AI_Voice
    restart: always
    ports:
      # 按需映射端口
      - "12221:12221"
      - "12222:3306"
      - "12225:12225"
    privileged: true
    volumes:
      # 按需映射文件夹
      # 容器内 /app 文件夹 映射到 宿主机项目文件夹
      - ./AI_Voice:/app
      # 容器内 MySQL 数据目录 映射到 宿主机持久化文件夹
      - ./AI_Voice_MySQL/data:/var/lib/mysql
      - ./AI_Voice_MySQL/log:/var/log/mysql
      # 容器内 supervisor 配置文件夹 映射到 宿主机配置文件夹
      - ./AI_Voice_Supervisor:/etc/supervisor/conf.d
    environment:
      # 开启 MySQL 初始化
      - MYSQL_INIT_ENABLED=true
      # Conda 环境配置(默认使用 ai-voice-py310 虚拟环境)
      - PATH=/opt/conda/envs/ai-voice-py310/bin:/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      - PYTHONPATH=/opt/conda/envs/ai-voice-py310/lib/python3.10/site-packages
      - CONDA_DEFAULT_ENV=ai-voice-py310
      - CONDA_PREFIX=/opt/conda/envs/ai-voice-py310
      # 指定了 NVIDIA GPU 驱动在容器中可以使用的功能
      #     compute:允许容器使用GPU进行计算操作
      #     utility:提供一些工具和库的支持,如 nvidia-smi
      - NVIDIA_DRIVER_CAPABILITIES=compute,utility
      # 控制物理设备可见性(指定可见的 GPU 设备)
      - NVIDIA_VISIBLE_DEVICES=0
      # 指定 CUDA 运行时可见设备
      - CUDA_VISIBLE_DEVICES=0
    # entrypoint 负责检测 MySQL 数据目录并自动初始化
    entrypoint: ["/usr/local/bin/docker-entrypoint.sh"]
    # 容器启动时同时启动 supervisor,来管理所有服务(容器内所有服务都应通过 *.conf 来配置启动)
    command: ["/usr/bin/supervisord", "-n", "-c", "/etc/supervisor/supervisord.conf"]
    # deploy.resources.reservations.devices 用于指定 GPU 相关配置
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              capabilities: [gpu]
    # 分配给容器的共享内存
    shm_size: 8g
    # 工作目录
    working_dir: /app
    # 开启 TTY(终端)
    tty: true
    # 保持标准输入(stdin)对容器开放
    stdin_open: true
##############################
# (Step 5)一键启动定制镜像
sudo docker-compose -f docker-compose-ai-voice.yml up -d

# 预计等待 1-3 分钟后才能全部启动完毕,此时方可测试
# 查看后端日志
./AI_Voice/App_Logs/app-backend.log
# 查看前端日志
./AI_Voice/App_Logs/app-frontend.log

附录

安装 NVIDIA Container Toolkit

在线安装

# 验证显卡驱动,如果驱动不存在需要先安装显卡驱动
nvidia-smi

# 配置包
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey \
 | sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg

curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list \
 | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' \
 | sudo tee /etc/apt/sources.list.d/nvidia-container-toolkit.list

# 更新包列表
sudo apt-get update

# 安装 NVIDIA Container Toolkit
sudo apt-get install -y nvidia-container-toolkit

# 验证是否安装成功
nvidia-ctk --version

# 重启 Docker 服务
sudo systemctl restart docker

离线安装

# 验证显卡驱动,如果驱动不存在需要先安装显卡驱动
nvidia-smi

# 前往 NVIDIA 的 GitHub 主页找到 Ubuntu 系统对应的 NVIDIA Container Toolkit 安装包
https://github.com/NVIDIA/libnvidia-container/tree/gh-pages/stable/deb/amd64
# 示例版本为 1.17.0,下载后的文件如下:

# 基础库包,提供了最基本的功能,其他包都依赖于它
libnvidia-container1_1.17.0-1_amd64.deb
# 基础工具包,依赖于 libnvidia-container1
libnvidia-container-tools_1.17.0-1_amd64.deb
# 基础组件包,依赖于前面的包
nvidia-container-toolkit-base_1.17.0-1_amd64.deb
# 主要的工具包,依赖于以上所有包
nvidia-container-toolkit_1.17.0-1_amd64.deb
# 调试符号包,只在调试问题时使用
libnvidia-container1-dbg_1.17.0-1_amd64.deb
# 开发包,只在进行开发时使用
libnvidia-container-dev_1.17.0-1_amd64.deb
# 最后两个安装包(调试包和开发包)可以选择不下载和不安装
# 按顺序执行安装
sudo dpkg -i libnvidia-container1_1.17.0-1_amd64.deb
sudo dpkg -i libnvidia-container-tools_1.17.0-1_amd64.deb
sudo dpkg -i nvidia-container-toolkit-base_1.17.0-1_amd64.deb
sudo dpkg -i nvidia-container-toolkit_1.17.0-1_amd64.deb

# 验证是否安装成功
nvidia-ctk --version

# 重启 Docker 服务
sudo systemctl restart docker

5

评论区