How to create a Docker image and a Dockerfile case


1. Create based on an existing image

1. Create a boot image

1)首先启动一个镜像,在容器里做修改
docker run -itd centos:7 /bin/bash

insert image description here

2. Generate a new image

2)将修改后的容器提交为新的镜像,需要使用该容器的 ID 号创建新镜像
docker commit -m "new-images" -a  "test" dda50e36fd55   centos:test
#常用选项:
-m 说明信息;
-a 作者信息;
-p 生成过程中停止容器的运行;
 
docker images
#查看新生成的镜像

insert image description here

3. Create based on Dockerfile

1. Dockerfile structure and layering

The Dockerfile structure is roughly divided into four parts: basic image information , maintainer information , image operation instructions , and execution instructions when the container starts

Dockerfile is a text file, which contains a series of instructions (Instruction), each instruction builds a layer, so the content of each instruction is to describe how the layer should be built. With Dockerfile, when we need to customize our own additional requirements, we only need to add or modify instructions on the Dockerfile and regenerate the image, saving the trouble of typing commands.

In addition to manually generating Docker images, you can use Dockerfile to automatically generate images. Dockerfile is a file composed of multiple instructions, each of which corresponds to a command in Linux, and the Docker program will read the instructions in the Dockerfile to generate a specified image

The structure of the Docker image is layered :
the image is not a single file, but consists of multiple layers. The container actually adds a read-write layer on top of the image, and any file changes made in the running container will be written to this read-write layer. If the container is deleted, its top read-write layer is also deleted, and file changes are lost. Docker uses storage drivers to manage the content of each layer of the image and the container layer of the readable and writable layer.

(1) Each instruction in the Dockerfile will create a new image layer;

(2) The image layer will be cached and reused;

(3) When the instructions of the Dockerfile are modified, the copied file changes, or the variables specified when building the image are different, the corresponding image layer cache will become invalid;

(4) If the image cache of a certain layer is invalid, the cache of the image layer after it will be invalid;

(5) The image layer is immutable. If you add a file in one layer and then delete it in the next layer, the file will still be included in the image, but the file will not be affected if it is invisible in the container. data in the mirror.

2. Joint file system

Union File System (unionFS): A layered, lightweight and high-performance file system, that is, a layer-by-layer superposition and then made into a mirror image. The bottom layer is loaded by the kernel, then the rootfs system, and the upper layer is the read-only basis Image, after the image is started, it becomes a container, which is a readable and writable layer. This layer stores data, etc., and then can be packaged into a new image to store data.

Features: Load multiple file systems at the same time, but from the outside, only one file system can be seen. Joint loading will superimpose the file systems of all layers, so that the final file system will contain all underlying files and directories.

The layers we see when we download are the joint file system.

3. The principle of docker image loading

insert image description here
①Docker's image is actually composed of layer-by-layer file systems, and this layer of file systems is UnionFS

②bootfs mainly includes bootloader and kernel. The bootloader is mainly used to guide and load the kernel. When Linux starts, it will load the bootfs file system.

③The bottom layer of the Docker image is bootfs, which is the same as our typical Linux/Unix system, including the boot loader and kernel. When the boot loading is complete, the entire kernel is in the memory. At this time, the right to use the memory has been transferred from the bootfs to the kernel. At this time, the system will also unload the bootfs.

④ We can understand that there is nothing in the kernel at the beginning, and a command is used to download debian, and then a layer of basic image will be added to the kernel; after installing emacs, a layer of image will be superimposed on the basic image; and then install An apache will superimpose another layer of image on top of images. In the end they look like a filesystem i.e. the rootfs of the container. In the Docker system, these rootfs are called Docker images. However, at this time, each layer of rootfs is read-only, and we cannot operate it at this time. When we create a container, that is, instantiate the Docker image, the system will allocate an empty read-write rootfs on top of one or more layers of read-only rootfs.

⑤Why the size of centos in the container is only 200M

Because for a streamlined OS, the rootfs can be very small, and only needs to contain the most basic commands, tools, and program libraries. Because the underlying layer directly uses the kernel of the host machine, you only need to provide the rootfs. It can be seen that for different Linux distributions, the bootfs is basically the same, and the rootfs will be different, so different distributions can share the bootfs.

4. Commonly used instructions for dockerfile operations

(1) The FROM command
is used to specify the basic input on which to generate a new image. The first command of the dockerfile must be FROM to specify the base image process on which the generated image is based. A FROM is required for each image created.

(2) MAINTAINER command
Indicates the maintainer information of the new image

(3) RUN command
Executes commands on the mirror image it is based on and submits it to the new mirror image, such as executing yum installation, etc.

(4) ENTRYPOINT command
ENTRYPOINT ["program to run", "parameter 1", "parameter 2"]

Set the command and its parameters to be run first when the container is started. This command is the command parameter added when entering the container with docker exec.
You can override the content of the ENTRYPOINT directive in the image by using the command docker run --entrypoint

(5) CMD command
CMD ["program to run", "parameter 1", "parameter 2"]

This instruction is the first command or step after entering the container, and the first command executed in the shell in the container after entering the container. There can only be one CMD command in the dockerfile. If there are multiple CMDs, only the last command will be executed. .

If a command is specified during docker run or there is an ENTRYPOINT command in the image, the CMD program will not be executed.

docker RUN priority > ENTRYPOINT command > CMD command

(6) EXPOSE command
EXPOSE "port number"

Specify the port to be opened when the new image generated by the dockerfile is loaded into Docker

(7) ENV command
ENV environment variable variable value

(8) ADD command
ADD source path target path

The ADD command is used to copy the source file to the new image generated by the dockerfile, and the source file must be in the same folder as the dockerfile, or under the same url. There are the following considerations:

①When the source path is a file and the target path ends with /, dockerfile will treat the target file as a directory and save the file in the source path to the directory of the template path, and automatically create the template path if the template path does not exist

②When the source path is a file and the target path does not end with /, dockerfile will treat the target path as a file, and directly overwrite the content of the target path file but the name will not change. If the template path does not exist, it will create a target path named The file, the content is the file content of the source path

③When the source path is a folder, if the target path exists, directly copy the folder of the original path to the directory of the template path.

If the target path does not exist, a folder named after the target path will be automatically created and the source folder will be copied to the directory.

④If the source file is an archive file or a compressed file, docker will automatically help decompress it. The URL download and decompression features cannot be used together. Any compressed files copied by URL will not be automatically decompressed.

(9) COPY instruction
copy source file/directory target file/directory

Only copy the files/directories on the local host to the mirror. It is required that the local file must be in the same path as the dockerfile.

Comparison between ADD and copy:

① All have the function of copying files and directories locally to the mirror

②ADD copy archive files and compressed files will be automatically decompressed

③All require to be in the same folder as the dockerfile

④URL pull directory to copy

⑤COPY can only copy the local host file to the mirror, ADD can copy to the url

(10) VOLUME command
volume ["directory"]

Create a mount point in the container

(11) USER command
USER username/uid

Specify the user when running the container

(12) The WORKDIR command
specifies the working directory for the subsequent RUN/CMD/ENTRYPOINT, which can be understood as switching to the specified directory to execute other commands such as RUN.

(13) ONBUILD instruction
specifies the command to be allowed when the generated image is used as a basic image. When calling the image with ONBUILD command, the ONBUILD command will be executed first. When using other mirrors, carefully check the contents of the ONBUILD command.

When the ONBUILD instruction is added to a Dockerfile, the instruction will not have any substantial impact on using the Dockerfile to build an image (such as an A image). But when writing a new Dockerfile to build a mirror based on the A mirror (such as a B mirror), the ONBUILD command in the Dockerfile file that constructs the A mirror will take effect at this time. In the process of building the B mirror, it will first execute The instructions specified by the ONBUILD instruction are executed before other instructions are executed.

(14) HEALTHCHECK
health check

4. Dockerfile case

1. Dockerfile builds an httpd instance

vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
#建立工作目录
mkdir  /opt/apache
cd  /opt/apache
echo '<h1>this is my Dockerfile</h1>' > index.html

vim Dockerfile
#基于的基础镜像
#指定基础镜像
FROM centos:7

#描述维护者信息
MAINTAINER this is apache image from centos7 <ll 2023-6-8>

#镜像操作指令安装apache软件
RUN yum install -y httpd

#复制网站首页文件
ADD index.html /var/www/html

#开启 80 端口
#开启 443 端口
EXPOSE 80
EXPOSE 443

#启动容器时执行脚本
CMD ["/usr/sbin/apachectl","-D","FOREGROUND"] 
docker build -t apache:centos7 .

insert image description here

docker run -itd --name c1 -p 1314:80 apache:centos7

insert image description here
insert image description here

2. Dockerfile builds nginx instance

mkdir /opt/nginx
cd /opt/nginx/
cp /opt/nginx-1.12.0.tar.gz /opt/nginx
#创建nginx目录,将nginx安装包放到创建的nginx目录下,必须与Dockerfile文件在同一目录下

vim Dockerfile
#编辑nginx的dockerfile文件内容如下
FROM centos:7


MAINTAINER this is nginx image from centos7 <wl 2023-6-8>

ADD nginx-1.22.0.tar.gz /opt/

RUN yum -y install pcre-devel zlib-devel openssl-devel gcc gcc-c++ make &&\
useradd -M -s /sbin/nologin nginx &&\
cd /opt/nginx-1.22.0 &&\
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install

ENV PATH $PATH:/usr/local/nginx/sbin

EXPOSE 80
#EXPOSE 443

ENTRYPOINT ["/usr/local/nginx/sbin/nginx"]
CMD ["-g","daemon off;"]

insert image description here
insert image description here
insert image description here
Change web page

cd /opt/nginx
mkdir html
echo '<h1>this is my test web</h1>' >  html/index.html
docker rm -f e7888865896b  #删除之前创建的nginx容器
docker run -itd --name c2 -P -v /opt/nginx/html:/usr/local/nginx/html  nginx:centos7

insert image description here

insert image description here

3. Dockerfile builds a tomcat instance

mkdir /opt/tomcat
cd /opt/tomcat/
#将apache-tomcat-9.0.16.tar.gz包和jdk-8u91-linux-x64.tar.gz包拷贝到tomcat目录下
tar xf apache-tomcat-9.0.16.tar.gz 
tar xf jdk-8u91-linux-x64.tar.gz 
vim Dockerfile

FROM centos:7
MAINTAINER this is tomcat image from centos7 <ll 2023-6-8>

#安装jdk
ADD jdk-8u91-linux-x64.tar.gz /usr/local/
ENV JAVA_HOME=/usr/local/jdk1.8.0_91
ENV JRE_HOME=${
    
    JAVA_HOME}/jre
ENV CLASSPATH=.:${
    
    JAVA_HOME}/lib:${
    
    JRE_HOME}/lib
ENV PATH=${
    
    JAVA_HOME}/bin:${
    
    JRE_HOME}/bin:$PATH

#安装tomcat
ADD apache-tomcat-9.0.16.tar.gz /usr/local/
EXPOSE 8080
#前台运行tomcat
ENTRYPOINT ["/usr/local/apache-tomcat-9.0.16/bin/catalina.sh","run"]

docker pull centos:7
docker build -t tomcat:centos7 .

insert image description here

docker run -itd --name c3 -p 8080:8080 tomcat:centos7

insert image description here
insert image description here

4. Use Dockerfile to build lnmp service

#部署php(容器IP 为 172.18.0.30)
mkdir /opt/php
cd /opt/php

上传 php-7.1.10.tar.bz2 到 /opt/php 目录中

vim Dockerfile

FROM centos:7
MAINTAINER this is php image <wl 2023-6-8>
RUN yum -y install gd \
libjpeg libjpeg-devel \
libpng libpng-devel \
freetype freetype-devel \
libxml2 libxml2-devel \
zlib zlib-devel \
curl curl-devel \
openssl openssl-devel gcc gcc-c++ make

ADD php-7.1.10.tar.bz2 /opt/
RUN cd /opt/php-7.1.10 && \
./configure \
--prefix=/usr/local/php \
--with-mysql-sock=/usr/local/mysql/mysql.sock \
--with-mysqli \
--with-zlib \
--with-curl \
--with-gd \
--with-jpeg-dir \
--with-png-dir \
--with-freetype-dir \
--with-openssl \
--enable-fpm \
--enable-mbstring \
--enable-xml \
--enable-session \
--enable-ftp \
--enable-pdo \
--enable-tokenizer \
--enable-zip && make -j2 && make install && \
cp /opt/php-7.1.10/php.ini-production /usr/local/php/lib/php.ini && \
sed -i '939c date.timezone = Asia/Shanghai' /usr/local/php/lib/php.ini && \
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf && \
sed -i '17c pid = run/php-fpm.pid' /usr/local/php/etc/php-fpm.conf && \
cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf && \
useradd -M -s /sbin/nologin nginx && \
sed -i -e '23c user = nginx' -e '24c group = nginx' -e '36c listen = 172.18.0.30:9000' -e '62c listen.allowed_clients = 172.18.0.10' /usr/local/php/etc/php-fpm.d/www.conf

EXPOSE 9000

ENTRYPOINT ["/usr/local/php/sbin/php-fpm","-F"]

docker build -t php:centos7 .

insert image description here

cd /opt/nginx
docker cp 158f23b25a66:/usr/local/nginx/conf/nginx.conf ./
vim nginx.conf

insert image description here

docker network create --subnet 172.18.0.0/16 --opt "com.docker.network.bridge.name"="docker1" mynetwork

docker network ls

insert image description here

docker run -itd --name nginx -p 80:80 -v /opt/nginx/nginx.conf:/usr/local/nginx/conf/nginx.conf -v /opt/nginx/html:/usr/local/nginx/html --network mynetwork --ip 172.18.0.10 nginx:centos7

insert image description here
insert image description here
Browser access http://192.168.154.10:80
insert image description here

vim /opt/nginx/html/index.php
<?php
phpinfo();
?>
#把之前创建的php容器删除,重新创建
docker run -itd --name php -p 9000:9000 --volumes-from nginx --network mynetwork --ip 172.18.0.30 php01:centos7

insert image description here

insert image description here

5. Reduce the size of the mirror image

How to reduce the size of the image

1) Use as small a base image as possible

2) Minimize the number of instructions in the Dockerfile as much as possible

3) Add the command to clear the system and application cache at the end of the image building step

4) Use multi-stage (multi-stage) builds
FROM AS 别名
COPY --from 别名

#体积比较小的jdk的镜像
docker pull openjdk:8-jdk-alpine

insert image description here

Create tomcat based on this jdk image

insert image description here

docker build -t tomcat2:jdk .

insert image description here

docker run -itd -P tomcat2:jdk

insert image description here

insert image description here
Change the volume size of the previous php image

vim  /opt/php/Dockerfile 

FROM centos:7 AS installphp
MAINTAINER this is php image <wl 2023-6-8>
RUN yum -y install gd \
libjpeg libjpeg-devel \
libpng libpng-devel \
freetype freetype-devel \
libxml2 libxml2-devel \
zlib zlib-devel \
curl curl-devel \
openssl openssl-devel gcc gcc-c++ make

ADD php-7.1.10.tar.bz2 /opt/
RUN cd /opt/php-7.1.10 && \
./configure \
--prefix=/usr/local/php \
--with-mysql-sock=/usr/local/mysql/mysql.sock \
--with-mysqli \
--with-zlib \
--with-curl \
--with-gd \
--with-jpeg-dir \
--with-png-dir \
--with-freetype-dir \
--with-openssl \
--enable-fpm \
--enable-mbstring \
--enable-xml \
--enable-session \
--enable-ftp \
--enable-pdo \
--enable-tokenizer \
--enable-zip && make -j2 && make install && \
cp /opt/php-7.1.10/php.ini-production /usr/local/php/lib/php.ini && \
sed -i '939c date.timezone = Asia/Shanghai' /usr/local/php/lib/php.ini && \
cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf && \
sed -i '17c pid = run/php-fpm.pid' /usr/local/php/etc/php-fpm.conf && \
cp /usr/local/php/etc/php-fpm.d/www.conf.default /usr/local/php/etc/php-fpm.d/www.conf && \
sed -i -e '23c user = nginx' -e '24c group = nginx' -e '36c listen = 172.18.0.30:9000' -e '62c listen.allowed_clients = 172.18.0.10' /usr/local/php/etc/php-fpm.d/www.conf

FROM centos:7
COPY --from=installphp /usr/local/php/ /usr/local/php/
RUN useradd -M -s /sbin/nologin nginx
EXPOSE 9000

ENTRYPOINT ["/usr/local/php/sbin/php-fpm","-F"]

docker build -t php3:centos7 .
docker images

insert image description here

Guess you like

Origin blog.csdn.net/ll945608651/article/details/131077919