在Ubuntu中使用Docker打包程序(Conda, pip)

使用docker打包开发完的包和程序,有一个很大的好处是,把系统当前的配置环境都完整保存下来。这样只要把docker的image文件发到其他电脑里,就可以快速部署,完全不需要考虑环境配置的问题,特别对于python的程序来说,环境配置一直是个头疼的问题。

1. Docker 安装

有两种选项,一种是默认存储库在Ubuntu上的Docker,另一种是官方存储库的Docker。

建议使用官方存储库的Docker,两种方法我都用过,第一种方法,很多时候在pull对应环境时,会出现名称不匹配的情况,找不到对应的库,但是用回官方的就没这个问题,少踩些坑。

以下配置过程是在Ubuntu18.04上测试的,其他版本可以搜一下,挺多的。

1)更新本地的软件列表数据库

bash 复制代码
sudo apt-get update

2)下载依赖项

bash 复制代码
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
  1. 添加GPG钥匙
bash 复制代码
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

4)安装Docker存储库

bash 复制代码
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu  $(lsb_release -cs)  stable"

5)安装最新版Docker

bash 复制代码
sudo apt-get install docker-ce

6)测试

安装完后,可以运行一下docker指令

bash 复制代码
sudo docker --version

如果有返回当前版本说明安装应该没什么问题,也可以运行sudo docker images查看当前的镜像,但是刚装的docker,应该什么镜像也没有

2. 制作镜像image

在制作镜像前,需要三样东西:

  • Package files: 就是你的程序,整个文件夹,接下来我都会以GPT-SoVITS这个项目做列子
  • environment.yml:由conda输出的环境配置文件,里面会列出所有用到的依赖项,当然里面会有些多余的,这个后面再说
  • Dockerfile: 这个是一个脚本,怎么一步步把依赖库和启动程序构建好,别人run我们的image时,就会根据这个脚本启动

最终在同一路径下,有如图所示的这三个文件:

2.1 准备文件

然后说一下怎么准备上面这些文件:

1)首先第一个是package,这个就是我们的整个项目文件

2)然后是environment.yml,先进入conda的虚拟环境

bash 复制代码
conda activate your_env_name

然后使用指令输出环境配置文件

bash 复制代码
conda env export > environment.yml

这时第二个文件也准备好了。

3)写Dockerfile,先建一个Dockerfile,可以直接用指令touch Dockerfile,也可以手动自己添加,要注意的是,不需要加后缀,就用Dockerfile这个名字就行. 然后是内容,用我现在写的脚本做例子,也是有很多技巧的,以后可以慢慢学习,知道大概流程就行

Docker 复制代码
# 使用一个轻量级的Miniconda基础镜像
FROM continuumio/miniconda3:latest

# 设置工作目录在容器内
WORKDIR /app

# 将从conda导出的 environment.yml 文件复制到容器的当前目录
COPY environment.yml .

# 利用复制的配置文件创建Conda环境
RUN conda env create -f environment.yml

# 激活环境并设置PATH,这样后续命令都会在使用此环境的前提下执行
# 将 `your_env_name` 替换为你的环境名
ENV PATH /opt/conda/envs/your_env_name/bin:$PATH

# 将你的package源代码复制到容器的 /app 目录下
COPY . .

# 设置容器启动时默认执行的命令,例如运行你的package
# 请根据你的package修改此命令,例如 `CMD ["python", "-m", "your_package"]`
WORKDIR /app/GPT-SoVITS
CMD ["python", "api.py", "-d", "cpu", "-a", "0.0.0.0", "-p", "9880", "-dr", "./test_data/test_video.wav", "-dt", "希望以后没有bug。", "-dl", "zh"]

上面的脚本注释里有说明。

PS:要注意的地方是,最后CMD里面,如果需要加入参数的,要用双引号""一个个添加

同时,如果需要通过ip地址和端口处理服务的,如上面的 127.0.0.1:9880,要注意了,docker在容器内对外网卡地址是0.0.0.0,所以在写制作镜像时要注意把程序内部的地址改成0.0.0.0,不然就没办法通讯上了。

2.2 开始制作

1)先进入到上面准备好的三个文件所在的目录,然后运行以下指令制作镜像,-t后面的是这个镜像的名称,只能加一个/,不能加两个,一般前面是签名,后面写版本,最后:后面的是版本号

bash 复制代码
sudo docker build -t gptsovits/ubuntu18_py310:v1.0 .

其实在上面这个过程,会报各种依赖项无法安装,有些是ROS的依赖项和工具包,这些其实不是我上面这个包需要的依赖项,很奇怪,我配的这个conda环境是新建的,应该没包括ROS的东西才对,然后就需要把这些不需要的包,一个个去掉,这里也费了些功夫。

2)制作完镜像后,使用指令sudo docker images就可以查看这个镜像了

然后可以尝试运行它

bash 复制代码
sudo docker run -it --rm -p 9880:9880 gptsovits/ubuntu18_py310:v1.0

一切如预期运行就最好啦,当然如果发现启动没成功,其实可以进入到容器里debug,很多时候是因为路径问题,这个需要慢慢检查,使用如下指令就可以建立一个临时的docker容器进行debug,同时退出时缓存会被清除

bash 复制代码
sudo docker run -it --rm -p 9880:9880 --name gptsovits_debug gptsovits/ubuntu18_py310:v1.0 /bin/bash
2.3 保存和分享镜像

制作完成后,就可以把镜像打包,发送给别人了,也可以上传的docker hub上面

两个方案:

  1. 方案一:离线迁移
    在源电脑上导出镜像
    使用 docker save命令将镜像导出为一个 tar 归档文件。-o参数用于指定输出文件的路径和名称
bash 复制代码
sudo docker save -o my-image.tar <你的镜像名>:<标签>

​​示例​​:如果用我上面的镜像名为 gptsovits/ubuntu18_py310,标签为 v1.0,则命令为:

bash 复制代码
sudo docker save -o gptsovits-ubuntu18-py310-v1.0.tar gptsovits/ubuntu18_py310:v1.0

然后把压缩文件发到别的电脑即可。

在另一台电脑运行

bash 复制代码
sudo docker load -i gptsovits-ubuntu18-py310-v1.0.tar

解压完后,使用sudo docker images看看有没有加载成功,加载成功后,可以尝试运行它

bash 复制代码
sudo docker run -it --rm -p 9880:9880 gptsovits/ubuntu18_py310:v1.0
  1. 方案二:在线迁移
    首先在源电脑上推送镜像到 Docker Hub
    此时,需要先注册一个Docker Hub的账号,点这里进入官网
    注册完后,还要先创建一个仓库,然后需要用到username和仓库名。
    a. 登录 Docker Hub
    在终端中执行以下命令,并输入你的 Docker Hub 用户名和密码进行登录sudo docker login
    b. 为镜像打标签
    为了能推送到 Docker Hub,你的镜像名称必须符合 你的用户名/仓库名:标签的格式。使用 docker tag命令为本地镜像创建一个符合要求的新标签
bash 复制代码
sudo docker tag <原镜像名>:<原标签> <你的DockerHub用户名>/<仓库名>:<标签>

​​示例​​:

bash 复制代码
sudo docker tag gptsovits/ubuntu18_py310:v1.0 yourusername/gptsovits-app:latest

​​c. 推送镜像​​

使用 docker push命令将打好标签的镜像推送到 Docker Hub

bash 复制代码
sudo docker push yourusername/gptsovits-app:latest

​​然后在目标电脑上拉取镜像​​

在目标电脑上,只需一条命令即可从 Docker Hub 拉取镜像

bash 复制代码
sudo docker pull yourusername/gptsovits-app:latest

3. 维护

3.1 管理存储空间

大家在使用过程中,会发现,一个image的size是很大的,所以如何管理docker的存储空间也是个重要的维护任务

清理目标 推荐命令 主要作用与注意事项
全面检查 docker system df 查看 Docker 整体磁盘使用情况,帮助定位哪个区域占用空间最多
​​构建缓存​​ docker builder prune ​​ 清理效果通常最显著​​。删除构建镜像时产生的中间缓存层
悬空镜像 docker image prune 删除标签为 的镜像(通常由新旧镜像替换产生)
已停止的容器 docker container prune 删除所有已停止(Exited)的容器,一般可安全清理
未使用的数据卷 docker volume prune 清理前请确认​​,卷通常用于持久化重要数据(如数据库文件)
一键清理(谨慎) docker system prune 一次性清理上述所有类型的未使用资源(镜像、容器、网络、构建缓存),​​不删除数据卷
3.2 删除镜像

查找所有容器(包括已停止的)
sudo docker ps -a

停止并删除与旧镜像相关的容器(将 <container_id> 替换为实际的容器ID)
sudo docker stop <container_id>
sudo docker rm <container_id>

删除镜像(将 <image_name> 和 替换为你的镜像名称和标签)

例如:sudo docker rmi my-app:latest
sudo docker rmi <image_name>:<tag>

相关推荐
惊讶的猫3 小时前
docker常见命令:从拉取到推送社区仓库
docker
轩辕Ruins3 小时前
docker compose配置容器只允许指定的外部IP访问
docker
❀͜͡傀儡师3 小时前
docker离线镜像文件选择导入脚本
运维·docker·容器
安卓开发者3 小时前
Docker 安装和配置 Elasticsearch 完整指南
elasticsearch·docker·容器
筑梦之路3 小时前
docker ubuntu22.04更新报错问题——筑梦之路
运维·docker·容器
CodeHorizon3 小时前
Docker Buildx 构建多平台镜像的强大工具
其他·docker·容器·eureka
舰长1156 小时前
ubuntu24安装mysql遇到的坑----解决Mysql报错缺少libaio.so.1
linux·mysql·ubuntu
an86950017 小时前
ubuntu 安装 JDK8
linux·运维·ubuntu
weixin_436525077 小时前
Docker 镜像导出与导入教程(Windows - Linux)
运维·docker·容器