news 2026/4/17 14:36:34

Docker Compose 实战指南:目录结构、核心配置解析与镜像构建/推送全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Docker Compose 实战指南:目录结构、核心配置解析与镜像构建/推送全流程

这篇文章来源于我自己搭建和调试 Docker Compose 时的各种实践和踩坑记录 是一点点摸索出来的经验总结;如果你发现有更好的做法 或者某些地方值得讨论 欢迎在评论区留言;一起把这些细节理顺 把 Compose 玩得更顺手;

目录结构

config/
├── docker-compose.yml ← 我们的核心我文件
├── .env.example ← 这个是分享的配置示例
├── .env ← 这个是我们自己本地的文件(port/username/password...)
├── Dockerfile ←帮你把 docker-compose.yml 和 .env.example 打包成一个镜像的

docker-compose.yml

version: "3.8" services: # MySQL mysql: image: mysql:8.0 container_name: mysql-nacos env_file: - .env environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} MYSQL_USER: ${MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD} ports: - "3311:3306" volumes: - ./mysql-data:/var/lib/mysql networks: - config_network restart: always networks: config_network: driver: bridge

version: "3.8":

这个可有可无这个是 Docker Compose v1/v2 时期的一个规范号从 Docker Compose V2 开始(现在所有 Docker Desktop 都是 V2) 现在已经被官方废弃了,写不写都行看个人习惯;

services(核心)

声明这个以后可以在这里面写你需要拉取的服务了;

这些属性都是什么?
mysql: image: mysql:8.0

image

要运行的镜像 → 官方 MySQL 8.0;

container_name: mysql-nacos

container_name
你给容器取的名字 方便 docker ps 里识别;

env_file: - .env

env_file
从当前目录加载.env文件里的变量 比如密码、数据库名;

environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} MYSQL_USER: ${MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD}

environment
.env里面的变量注入到容器内部;

等于在容器里运行时自动执行:

MYSQL_ROOT_PASSWORD=你的密码

这些是 MySQL 官方环境变量 用来初始化数据库

ports: - "3311:3306"

ports
把宿主机 → 容器的端口做映射

33113306
你本机访问容器的 MySQL

别人访问你的 MySQL:ip:3311
容器内部服务访问 MySQL:mysql:3306

volumes: - ./mysql-data:/var/lib/mysql

volumes(数据挂载)

左边:你电脑上的mysql-data

右边:容器内 MySQL 数据目录

容器删了 数据不丢; MySQL 占用空间在宿主机 ;

networks: - config_network

networks
让 mysql 和 其他的服务在同一个网络里可以互相访问

相当于给它们都加入了一个局域网

restart: always

restart 策略
容器异常退出会自动重启
服务器重启后自动启动


.env

.env是 Docker Compose 运行时真正加载的环境变量文件

也就是说 compose 启动容器的时候依赖的所有变量,都从.env

.env里要写什么?

就是所有 Compose 里用到的${XXX}值, compose 里包含:

MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} MYSQL_USER: ${MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD} SPRING_DATASOURCE_URL: ${NACOS_JDBC_URL} SPRING_DATASOURCE_USERNAME: ${NACOS_DB_USER} SPRING_DATASOURCE_PASSWORD: ${NACOS_DB_PASS}

所以.env应该长这样

# MySQL MYSQL_ROOT_PASSWORD=你的root密码 MYSQL_DATABASE=你的数据库名 MYSQL_USER=你的用户名 MYSQL_PASSWORD=你的用户密码 # NACOS 使用 MySQL 连接 NACOS_JDBC_URL=jdbc:mysql://mysql-nacos:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai NACOS_DB_USER=你的数据库用户名 NACOS_DB_PASS=你的数据库密码

.env.example

它是一个 示例环境变量文件 ;作用很简单:用来告诉别人 .env 应该怎么写、有哪些变量需要填;

真正运行 Compose 的时候 Docker 只认:

.env(默认)

或你手动指定的env_file

.env.example 不会被 Docker 读取 它就是给人看的模板文件;

文件用途
.env真正执行的环境变量,自己本地用
.env.example提供给别人参考的“模板”,不包含敏感值

Dockerfile

dockerfile是什么?一句话:

Dockerfile = 告诉 Docker:我要怎么做一个镜像

dockerfile文件:

FROM nginx:latest WORKDIR /share COPY docker-compose.yml . COPY .env.example . CMD ["sh", "-c", "tar -czf - *"]

它的作用就是

帮你把 docker-compose.yml 和 .env.example 打包成一个镜像,方便分享

Dockerfile 就像食谱:
FROM:基底

我选择了 nginx 镜像 仅仅是为了方便,本地就有nginx:latest,无需再去拉取 ,正常应该是为FROM alpine 但是这个需要从 Docker Hub 拉基础镜像,本地没 alpine,它就要从国外拉 ,这个就需要魔法了

这个时候就有人问了 博主博主 我没有nginx也没有魔法怎么办呢?我搜了一下可以替换成

FROM debian:stable-slim RUN apt-get update && apt-get install -y tar WORKDIR /share COPY docker-compose.yml . COPY .env.example . CMD ["sh", "-c", "tar -czf - *"]

这个我没有试过 可以试试 如果不行也没有魔法的情况下就下个nginx试试吧 我把代码放在下面了

version: "3.8" services: # MySQL mysql: image: mysql:8.0 container_name: mysql-nacos env_file: - .env environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} MYSQL_USER: ${MYSQL_USER} MYSQL_PASSWORD: ${MYSQL_PASSWORD} ports: - "3311:3306" volumes: - ./mysql-data:/var/lib/mysql networks: - config_network restart: always # Nginx nginx: image: nginx:latest container_name: nginx ports: - "80:80" volumes: - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf - ./nginx/conf.d:/etc/nginx/conf.d - ./nginx/html:/usr/share/nginx/html - ./nginx/log:/var/log/nginx networks: - config_network restart: always networks: config_network: driver: bridge

WORKDIR:在容器里工作目录
COPY:把你的文件塞进镜像里
CMD:运行容器时做什么(你这里是打包成 tar)

最终:
你自己写的文件 → 通过 Dockerfile → 变成镜像 → 推到 Docker Hub → 别人拉取你的 compose 镜像


构建镜像

登录

首先需要先登录我们的docker-hub

前往docker-hub登录

构建

登陆后本地执行命令:

docker build -t yourname/compose-share:1.0 .

注意!这里是在目录config执行的(参考目录结构)这里的“.”指的是所在的这个文件夹

docker build -t 你docker-hub登陆的名字 / 你取的名字;

这个前面一定要是登录的名字 不然到时候push上去会有认证的问题!


执行以后会弹出类似这样

此时你就构建成功了 !接下来就要执行:

docker login

因为我们前面登陆过了的话就会自己去验证

弹出这样的也是登录成功了


推送

接下来我们执行推送上去的命令

docker push yourname/compose-share:1.0

执行后弹出

就是推上去成功了


如何查看?

点击前往docker-hub查看

打开→我的中心

这里可以查看我们上传的所有的镜像;


如何修改名字?

有人又问了:博主博主 我想改这个镜像的名字怎么办?

好问题!

依旧在我们的仓库内部打开

因为当前docker-hub不支持修改名字 那么我们就需要创建一个新的仓库

创建完了以后就给自己本地刚刚我们构建好的镜像重新打tag:

docker tag yourname/compose-share:1.0 yourname/compose-modify:1.0

docker tag 你原来的compose文件构建的 你想要修改的名字;

docker push yourname/compose-modify:1.0

直接推上去即可;


如何覆盖?

比如你更新了你的 docker-compose.yml 或 .env.example:

重新 build

docker build -t yourname/compose-share:1.0 .

重新 push(直接覆盖)

docker push yourname/compose-share:1.0

完成!Docker Hub 上的 1.0 就变成新版本了

总结:改文件 → build → push → 覆盖同名 tag → 完成更新


如何获取你的compose 文件

Linux / Mac

docker run --rm yourname/compose-share:1.0 > compose.tar.gz tar -xzf compose.tar.gz

Windows PowerShell

docker run --rm yourname/compose-share:1.0 > compose.tar.gz tar -xzf compose.tar.gz

Windows CMD

docker run --rm yourname/compose-share:1.0 > compose.tar.gz tar -xf compose.tar.gz

执行完后,他们的目录里会出现:

docker-compose.yml
.env.example

因为我们已经加了Dockerfile所以不需要输出其他的命令了


结语

如果你能看到这里 真的非常感谢你的时间;希望这些实践经验能帮你少踩一些我踩过的坑;如果你有新的想法、遇到奇怪的问题、或想讨论更多 Compose 的玩法 随时欢迎在评论区交流;你的每一句反馈 都是推动我继续分享的动力;祝你部署顺利!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 23:18:21

DeepFM vs 传统推荐算法:效率提升实测对比

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 实现一个推荐算法对比测试平台,包含:1. DeepFM完整实现 2. 矩阵分解、逻辑回归等baseline算法 3. 自动化评估流程 4. 效果对比可视化 5. 资源消耗监控。重点…

作者头像 李华
网站建设 2026/4/1 10:48:21

工作七年总结:这 7 种设计模式,解决 99% 的 Java 开发场景

工作七年总结:这 7 种设计模式,解决 99% 的 Java 开发场景 (2025 年真实项目版,背下来直接升架构师) 我把过去 7 年踩过的坑、背过的锅、扛过的锅,全都浓缩成这 7 个模式。 99% 的业务系统(电…

作者头像 李华
网站建设 2026/4/17 7:59:32

5大核心技术揭秘:卷积神经网络如何颠覆传统图像识别 [特殊字符]

5大核心技术揭秘:卷积神经网络如何颠覆传统图像识别 🚀 【免费下载链接】CNN卷积神经网络讲解50多页PPT详细介绍 本PPT深入浅出地讲解了卷积神经网络(CNN)的核心原理与应用,涵盖从基础结构到卷积、池化等操作的详细解析…

作者头像 李华
网站建设 2026/4/13 19:45:31

250M参数撬动百亿市场:ModernVBERT重构智能文档检索范式

250M参数撬动百亿市场:ModernVBERT重构智能文档检索范式 【免费下载链接】modernvbert 项目地址: https://ai.gitcode.com/hf_mirrors/ModernVBERT/modernvbert 导语 在参数规模动辄千亿的大模型时代,仅2.5亿参数的ModernVBERT以"小而美&q…

作者头像 李华
网站建设 2026/4/16 19:06:42

Sysbench自动化测试:效率提升10倍的秘诀

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 构建一个Sysbench自动化测试平台,功能包括:1) 测试用例模板库;2) 一键触发多机分布式测试;3) 自动收集和聚合测试结果;4)…

作者头像 李华
网站建设 2026/4/7 9:50:26

875-LangChain框架Use-Cases - 代码调试系统 - 案例分析

1. 案例目标 本案例旨在构建一个基于LangGraph的AI驱动Python代码调试系统,通过自动化流程执行代码、分析错误、建议修复并验证修正。 系统主要实现以下目标: 自动执行Python代码并捕获错误使用AI分析错误并识别根本原因生成修复后的代码和单元测试验…

作者头像 李华