如何通过Dockerfile创建docker image
通过docker build命令我们可以简单的创建出我们想要的docker image。
很多时候我们所需要提供的仅仅只是一个Dockerfile。
譬如说我们可以用如下的Dockerfile创建一个带有httpd的docker image.
# cat httpd/Dockerfile
FROM centos:latest
RUN yum -y install httpd
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
# docker build httpd -t 127.0.0.1:5000/my_httpd:latest -t 127.0.0.1:5000/my_httpd:v0.1
Image创建完成后,其它需要用到httpd这个image的服务就可以在Dockerfile里面定义如下字段来reference这个image了
FROM 127.0.0.1:5000/my_httpd:latest
不过像httpd这种共通的docker image一般docker官方都已经有现成的了,如果不是要做一些特殊的定制,我们都是可以直接用官方的。
定制Dockerfile执行自己的prog
当然我们也可以创建运行自己的可执行文件的docker image。这个时候我们就需要提供一个Dockerfile和一个可执行文件my_prog,此时假设这两个文件在docker目录下。
# ls docker
Dockerfile my_prog
# cat docker/Dockerfile
FROM centos:latest
LABEL MAINTAINER="my_prog_maintainer" name="my_prog"
COPY my_prog /
CMD ["/my_prog"]
# docker build docker -t 127.0.0.1:5000/my_prog:latest -t 127.0.0.1:5000/my_prog:v0.1
当image创建出来后我们就可以通过如下命令来启动我们的container了。
# docker run -dit --name my-prog --network host 127.0.0.1:5000/my_prog
创建需要Access外部Resource的Docker Image
有些时候我们在创建docker image的时候需要访问一些外部的资源。
譬如说有如下这种情况
# ls project
app docker
docker目录下是Dockerfile,而app目录下则是我们的application。我们需要在创建image的时候把我们application拷贝到根目录。最快能想到的办法是在docker目录下创建一个软链接,让它link到app目录,这样不管app目录如何变化,每次创建image的时候都会用最新的。可是这个动作在创建docker image的时候是不允许的。我们在创建的时候会遇到Forbidden错误。
# cat docker/Dockerfile
FROM centos:latest
COPY app /
CMD ["/app/run"]
# docker build docker -t 127.0.0.1:5000/app:latest
...
Forbidden path outside the build context
通过Google发现,通过symlink不行,但我们可以通过mount来实现。这个时候我们可以在最外层提供一个build.sh来辅助我们创建image.
build.sh负责创建前mount app目录,创建docker image,并且在创建结束后不管成功与否进行清理。
#!/bin/bash
# Exit when error happen
set -e
# Assume app directory already exist within docker directory
# Clean mount when shell exit
trap 'umount docker/app' EXIT
# Docker forbidden path outside the build context
mount -o bind app docker/app
# Build docker image
docker build docker -t 127.0.0.1:5000/app:latest -t 127.0.0.1:5000/app:v0.1
这样我们就只需要在project目录下执行./build.sh就可以把image创建出来啦。
# ls project
app build.sh docker
# ./build.sh