Docker:DockerFile

Docker:DockerFile

是什么?

Dockerfile 是用来构建 docker 镜像的文件,是命令参数脚本
构建步骤:

  1. 编写一个 dockerfile 文件
  2. docker build 构建成为一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub、阿里云镜像仓库!)
    我们打开centos - Official Image | Docker Hub
    就能够看到官方的 Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
FROM scratch  
ADD centos-7-x86_64-docker.tar.xz /

LABEL
org.label-schema.schema-version="1.0" \
org.label-schema.name="CentOS Base Image"\
org.label-schema.vendor="Centos" \
org.label-schema.1icense="GPLv2"\
org.1abel-schema.bui1ddate="20200504"\
org.opencontainers.image.title="CentOS Base Image"\
org.opencontainers.image.vendor="Centos"\
org.opencontainers.image.1icenses="GPL-2.0-only"
org.opencontainers.image.created="2020-05-04 00:00:00+01:00"
CMD ["/bin/bash"]

官方都是基础包,啥都没有,我们通常自己搭建镜像

DockerFile构建过程

基础知识

  1. 每个保留关键字(指令)都是必须是大写字母
  2. 从上到下顺序执行
  3. #表示注释
  4. 每一个指令都会创建提交一个新的镜像层并提交
    镜像结构
    步骤:开发,部署,运维
    DockerFile:构建文件,定义步骤,源码
    Docker Images:通过DockerFile 构建生成镜像,是最终发布和运行的产品
    Docker 容器:镜像运行之后提供的服务器

后两块都是用别人的,会第一步才是自己的

指令

指令说明
FROM指定基础镜像,构建镜像的 一切都从这里开始
MAINTAINER指定镜像作者的信息(如姓名+邮箱),现在推荐使用 LABEL 代替
RUN构建镜像时执行的命令(如安装软件等)
ADD添加文件/目录到镜像中,支持自动解压 .tar.gz(比 COPY 强大)
COPY简单的文件/目录复制,不解压,推荐优先使用 COPY 而不是 ADD
WORKDIR设置工作目录,相当于 cd,之后的指令都基于这个目录运行
VOLUME定义挂载点,用于数据卷(数据持久化)
EXPOSE声明容器运行时监听的端口(不会自动映射)
CMD容器启动时执行的命令,只能有一个生效,可被 docker run 覆盖
ENTRYPOINT容器启动时执行的命令,不会被覆盖,但可以追加参数
ONBUILD给未来继承这个镜像的 Dockerfile 预设指令(父镜像的“钩子”)
ENV构建的时候设置环境变量

示例

Docker Hub中 99% 镜像都是从这个基础镜像过来的——FROM scratch,然后配置需要的软件和配置来进行的构建

创建一个自己的ubuntu

1、编写DockerFile文件

1
2
3
4
5
6
7
8
9
10
11
FROM ubuntu:20.04  
MAINTAINER zheep <zheep1209@foxmail.com>
ENV PATH=/usr/local
WORKDIR $PATH
ENV DEBIAN_FRONTEND=noninteractive # 防止 tzdata 交互式安装卡住
RUN apt-get update && \
apt-get install -y vim net-tools && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
EXPOSE 80
CMD ["/bin/bash"]

2、通过该文件构建镜像

docker build -f dockerfile 文件路径 -t 镜像名:[tag]

1
2
3
$ docker build -f mydockerfile -t zheep-ubuntu:0.1 .  
$ docker images
REPOSITORYTAG IMAGE ID CREATEDSIZEzheep-ubuntu0.1 212648d1b860 About a minute ago 142MB

最末尾的这个 .,是 构建上下文(build context) 的路径,意思是:

把当前目录 .(就是你运行这个命令的目录)作为 Docker 构建所用的上下文目录。

建议在构建目录添加 .dockerignore 文件,排除掉如 node_modules、target、.git 等大文件夹

3、测试运行

1
2
$ pwd/usr/local  
$ vim# 正常开启vim面板

使用docker history 镜像id可以查看镜像如何一步步构建的
拿到新镜像就可以这样查看怎么做的。

CMD 和 ENTRYPOINT 区别

1
2
CMD#指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代  
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令

实践:

准备

  1. 准备镜像文件 Tomcat 压缩包,jdk 压缩包

  2. 编写 Dockerfile 文件,官方命名 Dockerfile ,build 会自动寻找这个文件,就不需要 -f 指定了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FROM ubuntu:20.04  
LABEL maintainer="zheep"
# 设置非交互,避免 tzdata 卡住
ENV DEBIAN_FRONTEND=noninteractive
# 安装工具
RUN apt-get update && \
apt-get install -y vim net-tools && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* # 复制文件
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u451-linux-x64.tar.gz /usr/local
ADD apache-tomcat-9.0.105.tar.gz /usr/local
# 设置环境变量
ENV JAVA_HOME=/usr/local/jdk1.8.0_451
ENV CATALINA_HOME=/usr/local/apache-tomcat-9.0.105
ENV PATH="$JAVA_HOME/bin:$CATALINA_HOME/bin:$PATH"
# 工作目录(非必须)
WORKDIR $CATALINA_HOME
# 暴露端口
EXPOSE 8080
# 启动 tomcat(前台)
CMD ["catalina.sh", "run"]

构建镜像

1
$ docker build -t diytomcat .

启动镜像…访问测试…(咕咕咕…

这里直说了,前面都是代码演示,教你什么代码能做什么事
这里请自行测试,自行构建,根据你擅长的项目
比如你擅长前后端,就配个jdk和nginx再来个数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
FROM ubuntu:20.04

# 设置为非交互模式,避免 tzdata 等卡住
ENV DEBIAN_FRONTEND=noninteractive

# 安装常用工具
RUN apt-get update && \
apt-get install -y wget curl gnupg lsb-release vim net-tools software-properties-common && \
rm -rf /var/lib/apt/lists/*

# 安装 Nginx
RUN apt-get update && \
apt-get install -y nginx && \
rm -rf /var/lib/apt/lists/*

# 安装 Java 17
RUN apt-get update && \
apt-get install -y openjdk-17-jdk && \
rm -rf /var/lib/apt/lists/*

ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
ENV PATH="${JAVA_HOME}/bin:${PATH}"

# 安装 MySQL(仅测试用,不建议生产使用此方式)
RUN apt-get update && \
apt-get install -y mysql-server && \
rm -rf /var/lib/apt/lists/*

ENV MYSQL_ROOT_PASSWORD=root
ENV MYSQL_DATABASE=testdb

# 暴露端口
EXPOSE 80 3306 8080

# 启动多个服务(注意:这种写法适合测试,不适合生产)
CMD service mysql start && service nginx start && bash

然后在启动的时候做一个卷挂载,路径只是演示,仅提供思路

1
2
3
4
-v /home/project/mysql/conf:/etc/mysql/comf.d 
-v /home/project/mysql/data:/var/lib/mysql
-v /home/project/nginx/html:/home/share/nginx/html
-v /home/project/java/:/home/java/...

然后把不同端口映射出去,数据库和jar是在容器内互相访问的,因此不用映射数据库

1
2
-p 1008:80    # 映射nginx  
-p 1145:8080 # 映射后端

如果你想让这三个服务真正「长期运行」,可以用 supervisord 来管理
这种很多项目组合在一起的东西,建议分开来写,分成单独的容器,后面我们使用docker-compose来组装容器
终究…现在还是做不到吗…(不是
挖坑(挖坑(挖坑(
挖坑

发布镜像

因为上一步,我们在run的时候做了卷挂载,因此我们可以直接在本地编写项目,说白了就是把你的数据库,jar,前端打包好的文件等等放到挂载到本地的文件夹里

接下来的步骤上文已经全部讲过了,就是 build 成镜像,然后 run 一个容器
如果部署成功,你是可以直接访问的

本文就是教你怎么写DockerFile,以及相关的一系列流程,下期再见
镐击
吗?

如何发布自己的镜像到网上

DockerHub

DockerHub官网

  1. 自己注册登录账号
  2. 在自己的服务器上提交自己的镜像

控制台登录

1
2
3
4
5
6
7
8
9
$ docker login --help                                       

Usage: docker login [OPTIONS] [SERVER]
Authenticate to a registry.
Defaults to Docker Hub if no server is specified.
Options:
-p, --password string Password or Personal Access Token (PAT)
--password-stdin Take the Password or Personal Access Token (PAT) from stdin
-u, --username string Username

docker login -u 你的名字
如果你是国内服务器则需要魔法,不过本来也是写给自己的,不可能有别人看的 XD

push

1
docker push 你的名字/镜像名:版本号

提一嘴:给镜像加版本号docker 镜像id/tomcat:1.0

阿里云镜像服务

  1. 登录阿里云
  2. 找到容器镜像服务
  3. 创建命名空间
  4. 创建镜像仓库
    参考官方,自己看(无慈悲

小结(还需要么


Docker:DockerFile
https://www.zheep.top/posts/2158545144/
作者
西行寺岩羊
发布于
2025年5月17日
许可协议