What exactly is in the images? Operating system, core code, system tools, system libraries, runtime environment
Why make a mirror? Aren't there many mirrors on github? It cannot fully meet our requirements; it is not safe enough and may cause safety hazards.
Advantages of making a small image:
1. Users download quickly
2. Storage consumes small disk space
3. Small memory consumption when running containers
The idea of making a small mirror:
1. Use the basic image to make it smaller
2. Use less RUN, COPY, ADD, and WORKDIR (these instructions will increase the number of layers)
3. After using the image to start the container, install the software inside and use the volume to mount the data.
Image layering
The idea of image layering: an image is composed of many layers of data
base image: provides a minimally installed Linux distribution
Scratch image: an empty image that can be used to build ultra-small images such as busybox without relying on other images.
When the container starts, a new writable layer will be loaded on top of the image. This layer is called the "container layer". Everything below the "container layer" is called the "image layer". All the requirements for the container Changes (addition, deletion, modification) will only occur in the container layer. When the container starts, the kernel starts bootfs (what is needed when the container starts) and directly loads the basic image, and then loads it layer by layer from bottom to top; when the file is accessed after the container is running, it loads from top to bottom, one by one. Access layer by layer
The benefits of image layering: shared resources, easy resource reuse
Dockerfile
Dockerfile is the configuration file for making images - the recipe file
Dockerfile instructions--generally written in uppercase:
instruction | effect | Remark |
FROM | Specify base image | |
WORKDIR | Specify which directory you are in when entering the container | This command will also increase the number of mirroring layers - if the working directory is not the / directory (custom directory), it will be increased. If it is /, the number of mirroring layers will not be increased. |
ADD | Copy files or directories in the host to a directory in the container, which has the same effect as the COPY command | |
RUN | Specify the command to run when the image creation is in progress | |
CMD | Program to run when starting the container, older usage | |
ENTRYPOINT | Program to run when starting a container, relatively new usage | When the CMD instruction exists at the same time, the ENTRYPOINT instruction shall prevail, and the contents in CMD will become the parameters in ENTRYPOINT. |
ENV | Define environment variables | |
EXPOSE | Declare open port numbers | |
VOLUME | Using a volume in a container means mounting a path in the container to a volume on the host. | For example: VOLUME /var/lib/mysql, which creates a volume on the host. The name will be randomly generated and mounted to /var/lib/mysql in the container. |
STOP SIGNAL | Declare a signal to stop the container from running | |
HEALTHCHECK | Set up commands to check container health | Check whether the container is still running normally and whether it can provide services to the outside world. |
Case 1: Use Go language compiled code to create an image
Install the go language environment in advance:
[root@sc-docker go]# yum install epel-release -y
[root@sc-docker go]# yum install golang -y
1. Write the code of a simple web server server.go
package main
//server.go是主运行文件
import (
"net/http"
"github.com/gin-gonic/gin"
)
//gin-->go中的web框架
//入口函数
func main(){
//创建一个web服务器
r:=gin.Default()
// 当访问/=>返回{"message":"hello, sanchuang"}
r.GET("/",func(c *gin.Context){
//200,返回的数据
c.JSON(http.StatusOK,gin.H{
"message":"hello,sanchuanger 2023 nice",
})
})
//运行web服务
r.Run()
}
Compile server.go into a binary file. What needs to be put into the image is a binary file. The go language must be compiled into a binary file to run.
[root@sc-docker go]# go mod init web
[root@sc-docker go]# go env -w GOPROXY=https://goproxy.cn,direct #指定国内的源
[root@sc-docker go]# go mod tidy
[root@sc-docker go]# go run server.go #运行代码,默认监听的是8080,这个步骤只是测试我们的server.go能否正常运行
[root@sc-docker go]# go build -o hnweb . #hnweb就是我们编译好的核心代码
2.Write Dockerfile
[root@sc-docker go]# vim Dockerfile
[root@sc-docker go]# cat Dockerfile
FROM centos:7
WORKDIR /go
COPY . /go
RUN ls /go && pwd
ENTRYPOINT ["/go/hnweb"]
3. Make a mirror
[root@sc-docker go]# docker build -t hnweb:1.0 .
[root@sc-docker go]# docker images #查看是否制作成功
REPOSITORY TAG IMAGE ID CREATED SIZE
hnweb 1.0 f9cc1be0bde6 About a minute ago 221MB
...
In the docker build command: the -t option is used to specify the name of the image. The last one means that it is made based on the Dockerfile file in the current folder.
4. Start the container and use the image hnweb
[root@sc-docker go]# docker run -d --name hnweb-1 -p 7788:8080 hnweb:1.0
83dd8736d8dcaa846e705bef729b21440925cd94b4fa105a6f5e64fc369ad775
5. Go to a browser or other machine to access the host IP + port number to check whether it is used successfully.
Case 2: Write a Dockerfile based on nginx and build an image named nginxtest. It requires installing a tcpdump tool in the image, downloading or pulling a tar package from local and decompressing it, building the image and running the container, and exposing port access. .
[root@sc-docker yuan]# cat Dockerfile
FROM nginx:latest
WORKDIR /
RUN apt-get update && apt-get install tcpdump -y
RUN curl -O https://nginx.org/download/nginx-1.25.1.tar.gz && tar xf nginx-1.25.1.tar.gz
ENTRYPOINT ["/docker-entrypoint.sh"] #核心程序使用基础镜像中的,最后4行都是基于nginx镜像中的
EXPOSE 80
STOPSIGNAL SIGQUIT
CMD ["nginx", "-g", "daemon off;"]
[root@sc-docker yuan]# docker build -t sumengnginx:1.0 .
[root@sc-docker yuan]# docker run -d -p 4433:80 --name su-nginx-1 sumengnginx:1.0
8521143e2255c49e268e07165ee253e0b91a955f1eb86931dedb011de03a825a
Supplement: nginx uses Debian system
root@83c27adccd24:/# cat /etc/issue
Debian GNU/Linux 11 \n \l
Install the tcpdump command on Debian systems:
root@018ecad85391:/# apt-get update #更新Debian系统的仓库的源文件-->告诉系统去哪里可以下载软件,等同于centos中下载.repo文件
root@018ecad85391:/# apt-get install tcpdump -y