Dockerfile制作多应用的镜像(一、环境镜像)
文章目录
- Dockerfile制作多应用的镜像(一、环境镜像)
- 应用列表
- 步骤
- 一、制作环境镜像
- Step1、下载需要的安装包
- Step2、编写Dockerfile及启动脚本
- Step3、docker build 构建镜像
- Step4、docker run 启动容器
- Step5、docker exec 进入容器进行验证
- ==完成==
介绍基于centos7基础镜像,使用Dockerfile制作一个多应用的Docker镜像。
应用列表
- CentOS 7.6
- Mysql 5.7
- JDK 1.8
- Nginx 1.16.1
- Python 3.6 anaconda
- 其他项目应用
步骤
- 制作环境镜像:基于基础镜像centos7,安装mysql、anaconda、nginx、jdk
- 制作项目应用镜像:基于环境镜像,安装并启动项目应用的程序包
本文介绍的是第一步:制作环境镜像
一、制作环境镜像
主要步骤:
Step1、下载需要的安装包
Step2、编写Dockerfile及启动脚本
Step3、docker build 构建镜像
Step4、docker run 启动容器
Step5、docker exec 进入容器进行验证
Step1、下载需要的安装包
文件结构 /opt/dockermaker
[root@bg-244 dockermaker]# tree /opt/dockermaker
/opt/dockermaker
├── Anaconda3
│ ├── Anaconda3-5.2.0-Linux-x86_64.sh
│ ├── cachetools-4.0.0-py3-none-any.whl
│ ├── grpcio-1.27.2-cp36-cp36m-manylinux1_x86_64.whl
│ ├── msgpack-1.0.0-cp36-cp36m-manylinux1_x86_64.whl
│ ├── protobuf-3.11.3-cp36-cp36m-manylinux1_x86_64.whl
│ ├── pycryptodomex-3.9.7-cp36-cp36m-manylinux1_x86_64.whl
│ ├── redis-3.0.1-py2.py3-none-any.whl
│ └── redis_py_cluster-2.0.0-py2.py3-none-any.whl
├── bootstrap.sh
├── Dockerfile
├── java
│ └── jdk-8u221-linux-x64.tar.gz
└── mysql
├── mysql-community-client-5.7.29-1.el7.x86_64.rpm
├── mysql-community-common-5.7.29-1.el7.x86_64.rpm
├── mysql-community-libs-5.7.29-1.el7.x86_64.rpm
├── mysql-community-libs-compat-5.7.29-1.el7.x86_64.rpm
├── mysql-community-server-5.7.29-1.el7.x86_64.rpm
└── mysql_init.sh
其中,mysql_init.sh
是Dockerfile的RUN命令中执行的脚本,用于设置mysql数据库root临时密码为roottmp123
。bootstrap.sh
是Dockerfile的ENTRYPOINT命令中执行的脚本,基于当前镜像创建容器时会被执行。
为了高效地生成镜像,需要事先下载mysql、jdk、pip的安装包,使用本地安装。
Step2、编写Dockerfile及启动脚本
为了缩减镜像尺寸,应尽量注意:
- 在一个RUN语句中执行多个命令,而不应该写多个RUN语句。
- 清理无用文件:使用完的安装包,yum缓存等。
下面是代码及说明。
Dockerfile:
# 基础镜像
FROM centos:centos7
LABEL maintainer='jason9211' centos_version='7.6' mysql_version='5.7.29' jdk_version='1.8' nginx_version='1.16.1' python_version='3.6'
# 1、复制文件
WORKDIR /opt/Anaconda3
COPY Anaconda3/Anaconda3-5.2.0-Linux-x86_64.sh /opt/Anaconda3
COPY Anaconda3/msgpack-1.0.0-cp36-cp36m-manylinux1_x86_64.whl /opt/Anaconda3
COPY Anaconda3/pycryptodomex-3.9.7-cp36-cp36m-manylinux1_x86_64.whl /opt/Anaconda3
COPY Anaconda3/grpcio-1.27.2-cp36-cp36m-manylinux1_x86_64.whl /opt/Anaconda3
COPY Anaconda3/protobuf-3.11.3-cp36-cp36m-manylinux1_x86_64.whl /opt/Anaconda3
COPY Anaconda3/cachetools-4.0.0-py3-none-any.whl /opt/Anaconda3
COPY Anaconda3/redis-3.0.1-py2.py3-none-any.whl /opt/Anaconda3
COPY Anaconda3/redis_py_cluster-2.0.0-py2.py3-none-any.whl /opt/Anaconda3
WORKDIR /opt/mysql
COPY bootstrap.sh /opt/
COPY mysql/mysql-community-client-5.7.29-1.el7.x86_64.rpm /opt/mysql
COPY mysql/mysql-community-common-5.7.29-1.el7.x86_64.rpm /opt/mysql
COPY mysql/mysql-community-libs-5.7.29-1.el7.x86_64.rpm /opt/mysql
COPY mysql/mysql-community-libs-compat-5.7.29-1.el7.x86_64.rpm /opt/mysql
COPY mysql/mysql-community-server-5.7.29-1.el7.x86_64.rpm /opt/mysql
COPY mysql/mysql_init.sh /opt/mysql
WORKDIR /opt/nginx/security
COPY java/jdk-8u221-linux-x64.tar.gz /opt
# 2、指定工作目录
WORKDIR /opt
# 3、安装
# install Anaconda3
RUN cd /opt/Anaconda3 \
&& yum -y install unzip zip --nogpgcheck \
&& yum -y install bzip2 --nogpgcheck \
&& echo "===================================== Anaconda3 install start... " \
&& bash Anaconda3-5.2.0-Linux-x86_64.sh -b -p /root/anaconda3 \
&& rm -f Anaconda3-5.2.0-Linux-x86_64.sh \
# && echo "export PATH=/root/anaconda3/bin:$PATH" >> ~/.bashrc \
&& /root/anaconda3/bin/pip -V \
&& /root/anaconda3/bin/pip install msgpack-1.0.0-cp36-cp36m-manylinux1_x86_64.whl \
&& /root/anaconda3/bin/pip install pycryptodomex-3.9.7-cp36-cp36m-manylinux1_x86_64.whl \
&& /root/anaconda3/bin/pip install grpcio-1.27.2-cp36-cp36m-manylinux1_x86_64.whl \
&& /root/anaconda3/bin/pip install protobuf-3.11.3-cp36-cp36m-manylinux1_x86_64.whl \
&& /root/anaconda3/bin/pip install cachetools-4.0.0-py3-none-any.whl \
&& /root/anaconda3/bin/pip install redis-3.0.1-py2.py3-none-any.whl \
&& /root/anaconda3/bin/pip install redis_py_cluster-2.0.0-py2.py3-none-any.whl \
&& echo "===================================== Anaconda3 install success " \
&& echo "===================================== mysql install start... " \
&& cd /opt/mysql \
&& yum install -y iproute --nogpgcheck \
&& yum localinstall -y /opt/mysql/mysql-community-common-5.7.29-1.el7.x86_64.rpm --nogpgcheck \
&& yum localinstall -y /opt/mysql/mysql-community-libs-5.7.29-1.el7.x86_64.rpm --nogpgcheck \
&& yum localinstall -y /opt/mysql/mysql-community-libs-compat-5.7.29-1.el7.x86_64.rpm --nogpgcheck \
&& yum localinstall -y /opt/mysql/mysql-community-client-5.7.29-1.el7.x86_64.rpm --nogpgcheck \
&& yum localinstall -y /opt/mysql/mysql-community-server-5.7.29-1.el7.x86_64.rpm --nogpgcheck \
&& rm -rf /opt/mysql/*.rpm \
&& echo "===================================== mysql install success " \
&& echo "===================================== mysql init start... " \
&& mysqld --initialize --explicit_defaults_for_timestamp --user=mysql \
&& chmod 777 /opt/bootstrap.sh \
&& chmod 777 /opt/mysql/mysql_init.sh \
&& bash /opt/mysql/mysql_init.sh \
&& echo "===================================== mysql init success " \
&& echo "===================================== nginx install start... " \
&& cd /opt/nginx \
&& rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm \
&& yum install -y nginx-1.16.1 --nogpgcheck \
&& echo "daemon off;" >> /etc/nginx/nginx.conf \
&& echo "===================================== nginx install success " \
&& echo "===================================== java install start... " \
&& cd /opt \
&& tar -zxvf jdk-8u221-linux-x64.tar.gz \
&& rm -rf jdk-8u221-linux-x64.tar.gz \
&& echo 'export JAVA_HOME=/opt/jdk1.8.0_221' >> /etc/profile \
&& echo 'export PATH=$JAVA_HOME/bin:$PATH' >> /etc/profile \
&& echo 'export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar' >> /etc/profile \
&& source /etc/profile \
&& java -version \
&& echo "export JAVA_HOME=/opt/jdk1.8.0_221" >> ~/.bashrc \
&& echo "export PATH=/root/anaconda3/bin:$JAVA_HOME/bin:$PATH" >> ~/.bashrc \
&& echo "export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar" >> ~/.bashrc \
&& echo "===================================== java install success " \
&& rm -rf /var/cache/yum/*
# 4、设置环境变量
ENV JAVA_HOME /opt/jdk1.8.0_221
ENV PATH /root/anaconda3/bin:/opt/jdk1.8.0_221/bin:$PATH
ENV CLASSPATH /opt/jdk1.8.0_221/lib/dt.jar:/opt/jdk1.8.0_221/lib/tools.jar
# 5、暴露的容器端口
EXPOSE 22 80 443 3306 8090 8091
# 6、容器运行时执行的脚本
ENTRYPOINT ["/opt/bootstrap.sh"]
CMD ["/usr/sbin/init"]
mysql_init.sh:
#!/bin/bash
set -x
echo "#################################### mysql_init.sh start running..."
echo ""
INIT_ROOT_PASSWORD="roottmp123"
echo "############## set MYSQL root temp password : $INIT_ROOT_PASSWORD"
echo "############## start MYSQL ..."
mysqld --user=mysql &
sleep 2
function start_mysql(){
for p in {3..0};do
PORT=$(ss -anlp|grep 3306|wc -l)
if [ $PORT != 1 ]; then
echo "[WARN] MYSQL not run, now start..."
mysqld --user=mysql &
sleep 2
else
echo "[WARN] MYSQL is running"
break
fi
if [ $p = 0 ]; then
echo >&2 '[ERROR] MYSQL start failed!'
exit 1
fi
done
}
start_mysql
echo "############## change MYSQL root temp password ..."
PASSWORD=$(awk '/password/{print $NF}' /var/log/mysqld.log)
echo "change root password..."
mysql --connect-expired-password -uroot -p"$PASSWORD" << EOF
alter user 'root'@'localhost' identified by '$INIT_ROOT_PASSWORD';
grant all on *.* to root@'%' identified by '$INIT_ROOT_PASSWORD';
EOF
echo "############## MYSQL shutdown... "
mysqladmin -uroot -p$INIT_ROOT_PASSWORD shutdown
echo "#################################### mysql_init.sh start finished "
bootstrap.sh:
#!/bin/bash
echo "#################################### bootstrap.sh start running..."
echo "############## start MYSQL ..."
mysqld --user=mysql &
echo ""
echo "############# source /etc/profile"
source /etc/profile
echo ""
echo "############## show java version"
java -version
echo ""
echo "############## show pip version"
pip -V
echo ""
echo "############## nginx start by /usr/sbin/nginx. And bootstrap.sh finished..."
/usr/sbin/nginx
代码说明:
1)ENTRYPOINT脚本执行
COPY bootstrap.sh /opt/
RUN chmod 777 /opt/bootstrap.sh
ENTRYPOINT ["/opt/bootstrap.sh"]
CMD ["/usr/sbin/init"]
COPY语句复制过来的脚本,被Dockerfile限制了执行权限,需要chmod
才能执行。
启动容器时,会执行ENTRYPOINT
语句中指定的shell脚本/opt/bootstrap.sh
。
CMD在这里是启动容器时的默认参数。启动命令中如果设置了参数,将会覆盖CMD中的参数。
2)在docker中运行Nginx
在ENTRYPOINT脚本bootstrap.sh
的最后一句是:
/usr/sbin/nginx
ENTRYPOINT脚本执行结束后,docker容器会自动停止。
所以为了避免这种情况,需要将Nginx设为daemon off;
。
RUN \
&& echo "daemon off;" >> /etc/nginx/nginx.conf \
或在Nginx启动时添加参数。
/usr/sbin/nginx -g 'daemon off;'
3)项目配置
建议在构建应用镜像时进行mysql库表初始化及Nginx配置。
在构建基础镜像时,尽量不要有项目痕迹。
4)使用mysql用户启动数据库
mysqld --initialize --explicit_defaults_for_timestamp --user=mysql
mysqld --user=mysql
5)Dockerfile中设置环境变量的方式
RUN \
&& echo "export PATH=/root/anaconda3/bin:$JAVA_HOME/bin:$PATH" >> ~/.bashrc \
或
&& echo 'export JAVA_HOME=/opt/jdk1.8.0_221' >> /etc/profile \
&& source /etc/profile \
...
或
ENV JAVA_HOME /opt/jdk1.8.0_221
在bootstrap.sh
脚本中,也可以执行 source /etc/profile
。
6)清楚yum缓存
RUN \
&& rm -rf /var/cache/yum/*
Step3、docker build 构建镜像
构建镜像:
# 进入 Dockerfile 文件所在路径
cd /opt/dockermaker
# build --- 创建镜像的命令
# -t --- 指定target 名称
# centos-nmjpy:v1 --- 镜像名称:镜像tag
# . --- 执行当前路径下的 Dockerfile 文件
docker build -t centos-nmjpy:v1 .
查看镜像:
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-nmjpy v1 4bdd37c68d92 1 hours ago 6.14GB
centos centos7 5e35e350aded 3 months ago 203MB
docker下会有两个镜像,一个是基础镜像centos:centos7,另一个就是刚刚构建的镜像。
查看镜像内部层级及大小:
docker history centos-nmjpy:v1
删除镜像:
# docker image rm <镜像名:tag 或 镜像ID>
docker image rm centos-nmjpy:v1
docker image rm 4bdd37c68d92
Step4、docker run 启动容器
启动容器:
docker run -v /tmp/:/tmp -itd --privileged --cap-add=SYS_ADMIN \
-p 40022:22 -p 40443:443 -p 40080:80 -p 43306:3306 \
-p 48090:8090 -p 48091:8091 \
--name=centos-nmjpy \
centos-nmjpy:v1 \
/usr/sbin/init
-
-v /tmp/:/tmp
:挂载宿主机的一个目录,冒号":"前面的目录是宿主机目录,后面的目录是容器内目录。 -
-it
: 启动互动模式。 -
-d
: 后台运行。 -
--privileged
: 指定容器是否是特权容器。在docker容器运行时,让系统拥有真正的root权限。 -
--cap-add SYS_ADMIN
: 添加系统的权限,不然系统很多功能都用不了的。 -
-p 43306:3306
:端口映射,格式:宿主机端口:容器端口
。 -
--name=centos-nmjpy
:将容器命名为centos-nmjpy
。 -
centos-nmjpy:v1
:指定镜像,格式:镜像名称:镜像tag
-
/usr/sbin/init
:初始容器里的CENTOS,用于启动dbus-daemon。
查看容器:
docker ps -a
-
-a
:列出全部容器。若不加这个参数,只会列出正在运行的容器。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5f0d417764a6 centos-nmjpy:v1 "/opt/bootstrap.sh /…" 1 hours ago 1 hours ago 0.0.0.0:40022->22/tcp, 0.0.0.0:40080->80/tcp, 0.0.0.0:40443->443/tcp, 0.0.0.0:43306->3306/tcp, 0.0.0.0:48090->8090/tcp, 0.0.0.0:48091->8091/tcp centos-nmjpy
停止容器:
# docker stop <容器名或容器ID>
docker stop centos-nmjpy
docker stop 5f0d417764a6
运行容器:
# docker start <容器名或容器ID>
docker start centos-nmjpy
docker start 5f0d417764a6
删除容器:
# docker rm <容器名或容器ID>
docker rm centos-nmjpy
docker rm 5f0d417764a6
Step5、docker exec 进入容器进行验证
进入容器:
docker exec -it centos-nmjpy bash
退出容器(不停止容器):
Ctrl+P+Q 同时按下
完成
至此,制作环境镜像就制作完成了,接下来就可以 制作项目应用镜像 了。