# Docker镜像制作 # 基于rocky手动构建nginx镜像 Docker镜像制作类似于虚拟机的模板制作,即按照公司的实际业务将需要安装的软件、相关配置等基础环境配置完成,然后将容器再提交为模板,最后再批量从模板批量创建新的虚拟机,这样可以极大地简化业务中相同环境的虚拟机运行环境的部署工作,Docker的镜像制作分为手动制作可自动制作(基于DockerFile),企业通常都是基于DockerFile制作镜像。 ## 从初始镜像开始构建 一、启动一个RockyLinux容器,安装好nginx以及常用软件 ```bash [root@localhost ~]# docker run -it -d --name mynginx_server rockylinux:9 bash 18914b0f6005e7b20122508f8bc70a830845711ff6200392bf0a7c76dc4a8a60 [root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 18914b0f6005 rockylinux:9 "bash" 3 seconds ago Up 2 seconds mynginx_server [root@localhost ~]# docker exec -it mynginx_server bash # 进入容器以后,安装nginx以及一些常用的软件 [root@18914b0f6005 /]# yum install -y epel-release nginx [root@18914b0f6005 /]# yum install vim wget pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop -y ``` 二、关闭nginx后台运行 ```bash [root@18914b0f6005 /]# vim /etc/nginx/nginx.conf ...... daemon off; ...... ``` 三、自定义web界面 ```bash [root@18914b0f6005 /]# vim /etc/nginx/nginx.conf [root@18914b0f6005 /]# echo "
# DockerFile制作镜像
Dockerfile 是一种可以被 Docker 程序解释的脚本,它是一个文本文件,包含了一系列指令,用于定义如何构建 Docker 镜像。每一条指令都会创建镜像的一层,最终生成的镜像是由这些层叠加而成的。Dockerfile 中的指令关键字必须大写,执行顺序是从上到下,且每条指令创建一个镜像层。
Docker 程序会读取 Dockerfile 并根据指令生成 Docker 镜像。Dockerfile 的指令类似于 Linux 下的命令,但 Docker 程序会将这些 Dockerfile 指令翻译成真正的 Linux 命令来执行。相比手动制作镜像的方式,Dockerfile 能更直观地展示镜像是如何产生的。有了写好的 Dockerfile 文件,当后期某个镜像有额外的需求时,只需在之前的 Dockerfile 中添加或修改相应的操作,即可重新生成新的 Docker 镜像,避免了重复手动制作镜像的麻烦。
## 指令说明
### 配置指令
| 指令 | 说明 |
| :------------ | :--------------------------------- |
| `ARG` | 定义创建镜像过程中使用的变量 |
| `FROM` | 指定所创建镜像的基础镜像 |
| `LABEL` | 为生成的镜像添加元数据标签信息 |
| `EXPOSE` | 声明镜像内服务监听的端口 |
| `ENV` | 指定环境变量 |
| `ENTRYPOINT` | 指定镜像的默认入口命令 |
| `VOLUME` | 创建一个数据卷挂载点 |
| `USER` | 指定运行容器时的用户名或UID |
| `WORKDIR` | 配置工作目录 |
| `ONBUILD` | 创建子镜像时指定自动执行的操作指令 |
| `STOPSIGNAL` | 指定退出的信号值 |
| `HEALTHCHECK` | 配置所启动容器如何进行健康检查 |
| `SHELL` | 指定默认shell类型 |
### 操作指令
| 指令 | 说明 |
| :----- | :--------------------------- |
| `RUN` | 运行指定命令 |
| `CMD` | 启动容器时指定默认执行的命令 |
| `ADD` | 添加内容到镜像 |
| `COPY` | 复制内容到镜像 |
## 配置指令详解
### ARG
定义创建过程中使用到的变量,例如 `HTTP_PROXY`、`HTTPS_PROXY`、`FTP_PROXY`、`NO_PROXY` 等,不区分大小写。
### FROM
指定所创建镜像的基础镜像。为了保证镜像精简,可以选用体积较小的 Alpin 或 Debian 作为基础镜像。
### EXPOSE
声明镜像内服务监听的端口。例如:
```bash
EXPOSE 22 80 8443
```
该指令只是起到声明作用,并不会自动完成端口映射。
### ENTRYPOINT
指定镜像的默认入口命令,该入口命令会在启动容器时作为根命令执行,所有传入值作为该命令的参数。支持两种格式:
- `ENTRYPOINT ["executable","param1","param2"]`(exec 调用执行)
- `ENTRYPOINT command param1 param2`(在 shell 中执行)
此时 `CMD` 指令指定值将作为根命令的参数。每个 Dockerfile 中只能有一个 `ENTRYPOINT`,当指定多个时只有最后一个起效。
### VOLUME
创建一个数据卷挂载点。例如:
```bash
VOLUME ["/data"]
```
### WORKDIR
为后续的 `RUN`、`CMD`、`ENTRYPOINT` 指令配置工作目录。例如:
```bash
WORKDIR /path/to/workdir
```
可以使用多个 `WORKDIR` 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如:
```bash
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
```
最终路径为 `/a/b/c`。因此,为了避免出错,推荐在 `WORKDIR` 指令中只使用绝对路径。
### 操作指令详解
### RUN
运行指定Linux命令。每条 `RUN` 指令将在当前镜像基础上执行指定命令,并提交为新的镜像层。当命令较长时可以使用 `\` 来换行。
### CMD
`CMD` 指令用来指定启动容器时默认执行的命令。支持三种格式:
- `CMD ["executable","param1","param2"]`(相当于执行 `executable param1 param2`)
- `CMD command param1 param2`(在默认的 shell 中执行,提供给需要交互的应用)
- `CMD ["param1","param2"]`(提供给 `ENTRYPOINT` 的默认参数)
每个 Dockerfile 只能有一条 `CMD` 命令。如果指定了多条命令,只有最后一条会被执行。
### ADD
添加内容到镜像。例如:
```bash
ADD
# 镜像上传
## 官方docker仓库
- 准备账户
登陆到docker hub官网创建账号,登陆后点击settings完善信息
- 填写账户基本信息

- 登陆仓库
```bash
[root@docker-server ~]# docker login docker.io
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: smqy
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@docker-server ~]# ls -a
. .bash_history .bashrc dockerfile .tcshrc
.. .bash_logout .cshrc docker_in.sh .viminfo
anaconda-ks.cfg .bash_profile .docker .pki
[root@docker-server ~]# cat .docker/config.json
{
"auths": {
"https://index.docker.io/v1/": {
"auth": "YmJqMTAzMDp6aGFuZ2ppZTEyMw=="
}
}
}[root@docker-server ~]#
```
- 给镜像tag标签并上传
```bash
[root@docker-server ~]# docker tag nginx:v1 docker.io/smqy/nginx:v1
[root@docker-server ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx v1 fbd06c1753c0 12 minutes ago 581MB
smqy/nginx v1 fbd06c1753c0 12 minutes ago 581MB
centos_nginx v1 74acdcca8c97 21 hours ago 525MB
nginx latest 2b7d6430f78d 3 weeks ago 142MB
centos 7 eeb6ee3f44bd 12 months ago 204MB
nginx 1.8 0d493297b409 6 years ago 133MB
[root@docker-server ~]# docker push docker.io/smqy/nginx:v1
The push refers to repository [docker.io/smqy/nginx]
4f86a3bf507f: Pushed
0d11c01ff3ef: Pushed
45fc5772a4e4: Pushed
174f56854903: Mounted from library/centos
v1: digest: sha256:385bfe364839b645f1b2aa70a1d779b0dca50256ea01ccbe4ebde53aabd1d96d size: 1164
```
- 到docker官网进行验证

- 更换到其他docker服务器下载镜像
```bash
[root@docker-server ~]# docker login docker.io
```
## 阿里云仓库
将本地镜像上传至阿里云,实现镜像备份与统一分发的功能
https://cr.console.aliyun.com/
注册并且登录阿里云镜像仓库,创建namespace空间,创建一个普通的镜像仓库
具体如何拉取镜像,上传镜像,可以查看阿里云仓库下方提供的操作指南
### Push镜像案例
一、登录阿里云仓库
```bash
[root@localhost nginx]# docker login --username=Echooool registry.cn-hangzhou.aliyuncs.com
i Info → A Personal Access Token (PAT) can be used instead.
To create a PAT, visit https://app.docker.com/settings
Password:
Error response from daemon: Get "https://registry.cn-hangzhou.aliyuncs.com/v2/": unauthorized: authentication required
[root@localhost nginx]# docker login --username=Echooool registry.cn-hangzhou.aliyuncs.com
i Info → A Personal Access Token (PAT) can be used instead.
To create a PAT, visit https://app.docker.com/settings
Password:
WARNING! Your credentials are stored unencrypted in '/root/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/
Login Succeeded
```
二、推送镜像
```bash
# 先给要推送的镜像打上标签
[root@localhost nginx]# docker tag 9c86d96dfba0 registry.cn-hangzhou.aliyuncs.com/atopos/docker_hub:nginx_games-v1
# 推送镜像
docker push registry.cn-hangzhou.aliyuncs.com/atopos/docker_hub:nginx_games-v1
```
三、阿里云查看

四、拉取镜像
```bash
[root@localhost nginx]# docker pull registry.cn-hangzhou.aliyuncs.com/atopos/docker_hub:nginx_games-v1
nginx_games-v1: Pulling from atopos/docker_hub
446f83f14b23: Already exists
d9262d5a1401: Already exists
7330c5b74c49: Already exists
55e1c23f0b49: Already exists
5de772a29709: Already exists
f4819c5e7596: Already exists
Digest: sha256:f9a6ac50b9771c524017304847f3d8b2ffa4acbe01cef9279052272e50a9a3f3
```