使用 docker 构建 AFEPack 镜像来减少安装 AFEPack 的痛苦
先前写了一篇如何在 Ubuntu 安装 AFEPack 的教程,但现在感觉有些陈旧了。在暑假到澳门大学学习期间,结识了 xywei , 他使用 docker 构建了 AFEPack,镜像地址在这里。先前也知道 docker 掀起的热潮,但一直没有学习它。
关于 docker 的学习,网上一搜一大堆。我自己买了本 杨保华、戴王剑、曹亚仑 编著的《Docker 技术入门与实践》,利用一个下午学会了基本操作,后面的有些功能自己用不到就没有再深究下去。闲话少说,下面进入正题。
安装 docker
首先,要构建 docker 镜像,你需要安装 docker
,具体安装过程见官网或者 Google 、Baidu 一下。
编写 Dockerfile
要想实现自动构建 Docker 镜像,就需要编写 Dockerfile。只要知道 Dockerfile 编写时需要用的一些指令和编译安装的命令就可以了。
下面是我最后写好的 Dockerfile 。我在下面用中文添加注释,原文件参考我 GitHub 上的项目AFEPackDocker。
FROM ubuntu:16.04 # 以 ubuntu 16.04 作为镜像的基础系统
MAINTAINER FSSlc, liuchang011235 AT gmail DOT com # 维护者的相关信息
# install essential packages
RUN \ # RUN 后面跟上要运行的命令即可
mkdir -p /root/Pkg && \
# use aliyun's mirror for better download speed
sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && \
apt-get update && \
apt-get install -y make automake autoconf wget build-essential \
libdeal.ii-dev mpi-default-dev nano # libhypre-dev trilinos-all-dev petsc-dev --no-install-recommends
## set some env varibles # 设置与 AFEPack 相关的环境变量
COPY env.txt /root/Pkg/env.txt
## prepare AFEPack easymesh
RUN \
cd /root/Pkg && \
wget http://dsec.pku.edu.cn/~rli/AFEPack-snapshot.tar.gz && \
wget http://dsec.pku.edu.cn/~rli/source_code/easymesh.c.gz && \
tar -xzf ./AFEPack-snapshot.tar.gz -C /root/Pkg/ && \
gunzip easymesh.c.gz && \
## compile and install AFEPack
cat /root/Pkg/env.txt >> /root/.bashrc && . /root/.bashrc && \
cd /root/Pkg/AFEPack && \ # 将 ubuntu 中安装的 deal.ii 库文件改名
ln -s /usr/lib/x86_64-linux-gnu/libdeal.ii.g.so.8.1.0 /usr/lib/x86_64-linux-gnu/libdeal_II.g.so && \
ln -s /usr/lib/x86_64-linux-gnu/libdeal.ii.so.8.1.0 /usr/lib/x86_64-linux-gnu/libdeal_II.so && \
aclocal && autoconf && automake --add-missing && \
env EXTRA_INCDIR="-I/usr/include/deal.II/" EXTRA_LIBDIR="-L/usr/lib/x86_64-linux-gnu/" ./configure && \
# make -j8 && make install # 下面分开编译 AFEPack,直接编译会报错,镜像就编译不下去了
cd ./template/ && make -j8 && cd ../library/ && make -j8 && make install && \
cd ../example/ && make -j8 && \
## compile and install easymesh
cd /root/Pkg/ && \
gcc -o easymesh easymesh.c -lm && \
mv ./easymesh /usr/local/bin/ && \
## do some clean work # 清理一些不需要的文件,减小镜像大小
rm easymesh.c AFEPack-snapshot.tar.gz env.txt && \
rm -rf /var/lib/apt/lists/*
CMD ["/bin/bash"]
UPDATE
为了能够本地编译安装 AFEPack 的镜像,我编写了两个 Dockerfile,一个是直接使用
Ubuntu 16.04 里面 8.1 版本的 deal.II,另一个是在 Ubuntu 14.04 里使用源码编译的 deal.II 6.3.1,请自行选择。
UPDATE 20181103
好久没有更新了,最近在做 docker 相关的事。了解到 docker 可以进行所谓的多阶段构建了。这个功能可以进一步地减小镜像的大小,所以我今天就尝试了一下,效果还是很明显的。从原来的 1.07GB
减少到现在的 573MB
。
另外 AFEPack 的包做了一些更新,居然默认 std=c++14
了!所以原来的 Dockerfile 可能不能使用了,所以我顺便做了更新。从构建的结果看,step-7
这个例子跑不通,这次更新后的 Dockerfile 都有这个问题,它们获取的
AFEPack 源码都是今天我从官网下载的。但是我放在 docker Hub 的镜像可以运行。。。
使用 docker build
命令构建镜像
编写完 Dockerfile 后,便可以构建镜像了。使用的命令是:
sudo docker build -t afepack:v0 .
其中 -t
选项是指定编译后镜像的名称,即所谓的 tag
。
具体使用时,一般运行:
docker run -ti -v $HOME/Pkg:/opt afepack:v0 bash
上面的命令将启动一个容器,其中的 -v
选项将把主机中的 $HOME/Pkg
目录挂载到容器中的 /opt
目录,这样我们便可以在 $HOME/Pkg
中让主机和容器之间进行数据交互。