1. dockerfile用于通过脚本生成镜像
2.进入docker容器后,配置环境完,导出容器快照为镜像,拷贝到另一个主机,再进行加载;
3.在本地将依赖库等需要的文件按照目录整理好,映射到docker中。
1. dockerfile用于通过脚本生成镜像
用到的文件操作指令:
将当前的目录复制到/app中
COPY . /app
设置进入后工作路径
WORKDIR /app
本地存在一个start.sh文件,将脚本文件复制到目录中
COPY ./start.sh /app/
RUN chmod 777 /app/start.sh
A. 在本地编写一个test.dockerfile文件,从网上拉取一个ubuntu:20.04镜像,并进行简单配置
# 使用Ubuntu 20.04作为基础镜像
FROM ubuntu:20.04
# 设置环境变量TZ为Asia/Shanghai
ENV TZ=Asia/Shanghai
# 设置时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 将当前目录下的文件复制到容器的/app目录中
# 注意:通常使用/app而不是~/,因为~/可能依赖于容器的shell和用户的HOME环境变量
COPY . /app
RUN sed -i 's/# \(deb .* universe\)$/\1/g' /etc/apt/sources.list && \
sed -i 's/# \(deb-src .* universe\)$/\1/g' /etc/apt/sources.list
# 更新apt包列表
# RUN apt-get update
# RUN apt-get install -y python3
# apt-get install -y python3 && \
# rm -rf /var/lib/apt/lists/*
# 创建一个简单的Python脚本
RUN touch test.py
RUN echo "print('hello')" >> test.py
# 设置工作目录为/app
WORKDIR /app
# 使用CMD指令运行Python脚本
# 注意:CMD中的路径应该是相对于WORKDIR或者绝对路径,这里使用相对路径
# CMD ["python3", "./test.py"]
# TAG test:20.04
如果pip install无法联网,则可以更换源
FROM test:20.04
# RUN mkdir ./app
WORKDIR /app
RUN pwd
RUN ls
RUN touch hello.txt
# TAG test001:20.04
# 更新软件包列表并安装基本工具和库
RUN apt update && apt install -y \
python3 \
python3-pip \
pkg-config \
cmake \
g++ \
build-essential \
libglib2.0-dev \
apt-utils \
default-jdk \
python3-all-dev \
liblua5.1-dev \
golang \
doxygen \
git \
python3.8-dev \
python3.8-tk \
tk-dev \
libfreetype6-dev \
vim \
net-tools \
iputils-ping \
libatlas-base-dev \
liblapack-dev \
gfortran
# 设置pip源
ENV PIP_DEFAULT_TIMEOUT=100
ENV PIP_DISABLE_PIP_VERSION_CHECK=1
RUN mkdir /pip
# pip.conf 文件内容如下
# [global]
# index-url = https://pypi.tuna.tsinghua.edu.cn/simple
COPY pip.conf /pip/
ENV PIP_CONFIG_FILE=/pip/pip.conf
# 或者直接在RUN命令中设置
RUN pip install --index-url https://pypi.tuna.tsinghua.edu.cn/simple some-package
# 使用pip安装Python库
RUN apt-get install -y python3-matplotlib
RUN pip3 install --upgrade pip
RUN pip3 install matplotlib scipy pandas
# 清理无用的apt缓存(可选,减少镜像大小)
RUN apt clean && rm -rf /var/lib/apt/lists/*
# 设置工作目录(如果需要的话)
WORKDIR /app
COPY ./start.sh /app/
RUN chmod 777 /app/start.sh
CMD ["python3", "test.py"]
# CMD [ "/bin/bash", "-c", "./start.sh"]
# TAG test001:20.04
# docker buildx build --file /home/gdp/test/dockertest/test001.dockerfile --tag test001:20.04 .
B. 运行指令,生成镜像,镜像的tag为test:20.04
docker buildx build --file /home/gdp/test/dockertest/test.doc
kerfile --tag test:20.04 .
C. 在本地编写一个test001.dockerfile文件,基于上一步生成test:20.04镜像,并进行简单配置。省的每次build需要花较长的时间。
start.sh文件内容如下,末尾添加bash,在程序运行结束后,会保持端口打开,不会自动关闭。
#!/bin/bash
python3 test.py
bash
FROM test:20.04
# RUN mkdir ./app
WORKDIR /app
RUN pwd
RUN ls
RUN touch hello.txt
# TAG test001:20.04
RUN apt-get update
RUN apt install -y python3
RUN apt-get install -y pkg-config
RUN apt-get install -y cmake
RUN apt-get install -y g++
RUN mv /test.py /app/test.py
COPY ./start.sh /app/
RUN chmod 777 /app/start.sh
# CMD [ "/bin/bash", "-c", "./start.sh"]
D. 运行指令,生成镜像,镜像的tag为test001:20.04
docker buildx build --file /home/gdp/test/dockertest/test001.dockerfile --tag test001:20.04 .
反复运行该指令,并修改test001.dockerfile,
该方式:适合配置一些简单的基础包。不合适 用于改动或调试工程代码或处理复杂的安装依赖文件等。
2.进入docker容器后,配置环境完,导出容器快照为镜像
在Docker容器中配置环境,并将其作为镜像供另一台机器使用,例如,上述方法中没有安装eigen库,下面在进入docker后安装库,并不丢失的保存为镜像。
a. 进入镜像
docker run --rm -it test001:20.04
b. 安装eigen
查看是否已安装eigen3库
root@ac447a8ed1dc:/app# pkg-config --modversion eigen3
没有安装的话,安装一下
root@ac447a8ed1dc:/app# apt-get install libeigen3-dev
二、将配置好的容器保存为镜像
docker 查看container的名称
docker container ls
提交容器为镜像:
docker commit eager_bardeen eigentest:eigen3
docker commit 镜像名称 新的镜像名:新标签
可以查看到镜像
gdp@gdp:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
eigentest eigen3 bd3483f2d3ae 41 seconds ago 290MB
启动eigentest镜像的交互终端,再次运行,验证是否已安装eigen
pkg-config --modversion eigen3
已安装eigen,将镜像导出并传输到另一台机器
docker save -o myeigen.tar eigentest:eigen3
生成.tar文件,将导出的tar文件传输到另一台机器
进行镜像的加载
docker load -i myeigen.tar
运行容器
docker run --rm -it eigentest:eigen3
--rm
,一旦容器停止,它就会被自动删除
-it
选项,你将能够在一个交互式shell中操作容器,就好像你直接在容器内部工作一样
成功进入!
通过以上步骤,你可以在Docker容器中配置环境,并将其作为镜像供另一台机器使用。
3.文件按照目录整理好,映射到docker中,将所需文件复制到目录中
新建一个shell文件docker_load.sh,用于docker加载时的一些操作
#生成docker镜像
# docker buildx build --file /home/gdp/test/dockertest/test001.dockerfile --tag test001:20.04 .
# 获取当前脚本所在的绝对路径目录
current_pwd=$(cd $(dirname $0); pwd)
current_pwd_short=$(basename $(pwd))
# echo $current_pwd
# echo $current_pwd_short
root_dir=$current_pwd/../
root_dir="/home/gdp/test/dockertest"
# # 配置容器参数
docker_args="\
-v $root_dir:/app"
docker run --rm -it $docker_args test001:20.04
最后两句-v $root_dir:/app将宿主机工程目录映射到docker中
再在根目录新建一个docker_build.sh的shell脚本,用于在进入docker之后进行编译操作
# 将放在本地目录下整理好的库文件复制到docker本地./environment相当于/,
# 将./environment/usr文件复制到docker的/下,-ar保证同时不损害原来docker:/usr中的文件
current_dir=$(pwd)
environment_dir=$current_dir/environment
cp -ar $environment_dir/usr /
cd build
cmake ..
make
编译一个eigen的工程,参考如下链接一次成功流水账-Cmake组织工程并调用Eigen库_cmakelist eigen-CSDN博客
由于docker中没有安装eigen库,也没有映射进去,所以报错。
将eigen库运行需要的文件按照目录放置在environment的目录下usr文件夹中,
包括可执行文件,库文件,.cmake文件和头文件等。
通过如下cp -ar的 指令将文件复制到docker的本地/usr目录中,同时不破坏docker原有的/usr目录下的文件。
-a
:以归档模式复制,这意味着它会尽可能保留源文件的属性(如权限、时间戳、链接等),并递归地复制目录。-r
:递归复制,但因为-a
已经包含了这一行为,所以在这里是可选的。
再次修改docker_build.sh脚本
将映射后目录的内容复制到docker本地目录中
current_dir=$(pwd)
environment_dir=$current_dir/environment
cp -ar $environment_dir/usr /
cd build
cmake ..
make
./Eigentest
生成可执行文件./Eigentest
能够正常运行。
在配置好运行环境之后,正常的流程如下
1. 修改代码和cpp文件
2. 执行./scripts/docker_load.sh脚本,启动docker,映射目录
3. 执行./docker_build.sh脚本,将库文件等复制到docker容器环境中,并进行编译并运行。
docker中如何显示仿真界面,以及在docker中如何使用nvidia显卡,都是可以实现的。涉及到如下一些指令参数,仅供参考。
首先,在主系统里运行,就是你host主机,需要注意的是,每次重新开机,需要在本机操作一次xhost +
$ sudo apt-get install x11-xserver-utils
$ xhost +
docker run 添加如下两个参数0或1可以试下, -e DISPLAY=:1 -v /tmp/.X11-unix:/tmp/.X11-unix
docker_args="-v $root_dir:/app -e DISPLAY=:1 -v /tmp/.X11-unix:/tmp/.X11-unix"
如果在docker中使用nvidia的驱动和显示
需要在宿主机提前安装好nvidia-docker这个软件,安装教程可以参考Ubuntu 20.04 系统安装Docker及nvidia-docker2 - 文章 - 开发者社区 - 火山引擎
echo "# working in WITH NVIDIA Card"
docker run -it -d --device=/dev/dri \
--env="DISPLAY" --env="QT_X11_NO_MITSHM=1" -e DISPLAY=$DISPLAY -e NVIDIA_VISIBLE_DEVICES=all -e NVIDIA_DRIVER_CAPABILITIES=compute,utility,graphics --runtime=nvidia \
$docker_args > /dev/null 2>&1