Dockerfile制作多应用Docker镜像(一、环境镜像)

本文详述了如何使用Dockerfile从基础镜像centos7构建包含Mysql5.7、JDK1.8、Nginx1.16.1、Python3.6 anaconda等多应用的Docker镜像,包括下载安装包、编写Dockerfile、构建镜像、启动容器及验证流程。
部署运行你感兴趣的模型镜像

Dockerfile制作多应用的镜像(一、环境镜像)

介绍基于centos7基础镜像,使用Dockerfile制作一个多应用的Docker镜像。

应用列表

  • CentOS 7.6
  • Mysql 5.7
  • JDK 1.8
  • Nginx 1.16.1
  • Python 3.6 anaconda
  • 其他项目应用

每个应用的具体获取方式可以看–>这里

步骤

  1. 制作环境镜像:基于基础镜像centos7,安装mysql、anaconda、nginx、jdk
  2. 制作项目应用镜像:基于环境镜像,安装并启动项目应用的程序包

本文介绍的是第一步:制作环境镜像

一、制作环境镜像

主要步骤:
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 同时按下

完成

至此,制作环境镜像就制作完成了,接下来就可以 制作项目应用镜像 了。

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

### 编写 Dockerfile 并构建 Docker 镜像 Dockerfile个文本文件,包含了系列指令,用于自动构建 Docker 镜像Docker 读取 Dockerfile,按照其中的指令逐步创建镜像,每步都会生成个新的镜像层(layer)[^3]。以下是编写 Dockerfile 并构建 Docker 镜像的详细步骤。 #### Dockerfile 的基本语法 Dockerfile 的基本语法包括系列指令,每条指令对应个构建步骤。常见的指令包括: - `FROM`:指定基础镜像,构建镜像的第步通常是从个已有的镜像开始。 - `RUN`:在镜像中执行命令,用于安装软件包或配置环境。 - `CMD`:指定容器启动时运行的默认命令。 - `EXPOSE`:声明容器运行时监听的端口。 - `COPY` 和 `ADD`:将本地文件复制到镜像中。 - `WORKDIR`:设置工作目录,后续的命令将在该目录下执行。 - `ENTRYPOINT`:配置容器启动时运行的可执行程序。 例如,个简单的 Dockerfile 可能如下所示: ```dockerfile # 使用官方的 Nginx 镜像作为基础镜像 FROM nginx:latest # 设置工作目录 WORKDIR /usr/share/nginx/html # 将本地文件复制到容器中 COPY index.html index.html # 暴露 80 端口 EXPOSE 80 # 启动 Nginx CMD ["nginx", "-g", "daemon off;"] ``` #### 构建 Docker 镜像 在编写好 Dockerfile 文件后,可以使用 `docker build` 命令将文件构建成镜像。命令的使用方法如下: ```bash docker build -f dockerfile文件路径 -t 镜像名称 . ``` 其中: - `-f`:指定 Dockerfile 的文件路径,可以是绝对路径,也可以是相对路径。 - `-t`:为构建的镜像指定个名称和标签,格式为 `名字:标签`。 - `.`:表示构建上下文的路径,必须指定[^2]。 例如,如果 Dockerfile 文件位于当前目录,并希望构建个名为 `my_build:nginx1` 的镜像,可以执行以下命令: ```bash docker build -t my_build:nginx1 . ``` #### 查看镜像的构建历史 可以使用 `docker history` 命令查看镜像的构建历史,了解每层是如何生成的。命令如下: ```bash docker history 镜像ID ``` 该命令会列出镜像的所有构建层,包括每步的指令、大小、创建时间等信息。 #### 实操训练:构建 Nginx 镜像 假设需要构建个名为 `my_build:nginx1` 的 Nginx 镜像,并将 Dockerfile 文件保存在目录 `dockerfile-nginx1` 中。具体操作如下: 1. 创建目录 `dockerfile-nginx1` 并进入该目录: ```bash mkdir dockerfile-nginx1 cd dockerfile-nginx1 ``` 2. 创建并编辑 Dockerfile 文件,内容如下: ```dockerfile FROM nginx:latest WORKDIR /usr/share/nginx/html COPY index.html index.html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] ``` 3. 创建个简单的 `index.html` 文件作为网页内容: ```bash echo "<h1>Hello, Docker!</h1>" > index.html ``` 4. 执行构建命令: ```bash docker build -t my_build:nginx1 . ``` 5. 查看构建的镜像: ```bash docker images ``` 6. 运行容器并测试: ```bash docker run -d -p 8080:80 my_build:nginx1 curl http://localhost:8080 ``` 通过上述步骤,可以成功编写 Dockerfile 并构建 Docker 镜像。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jason9211

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值