惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LangChain Blog
V
V2EX
爱范儿
爱范儿
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Martin Fowler
Martin Fowler
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
小众软件
小众软件
Vercel News
Vercel News
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
V
Visual Studio Blog
J
Java Code Geeks
P
Proofpoint News Feed
MongoDB | Blog
MongoDB | Blog
B
Blog
美团技术团队
量子位

云端的解构者 | 西行寺岩羊的博客

苏州 记录:傻逼win11美化插件导致资源管理器崩溃 炸鸡 武汉 最近在干嘛 当善良成为廉价品:为什么你的帮助换不来感激? Minecraft跨平台服务器搭建记录 防弹笔记法(草稿 CSS纸张阴影二三事 Docker:网络 Docker:容器数据卷 Docker:镜像讲解 Docker:基本命令 Spring:登录后逻辑:JWT、拦截器与ThreadLocal Spring:Redis
Docker:DockerFile
西行寺岩羊 · 2025-05-17 · via 云端的解构者 | 西行寺岩羊的博客

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. 创建镜像仓库
    参考官方,自己看(无慈悲

小结(还需要么