news 2026/9/5 16:44:18

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/9/4 17:24:28

CppSharp终极指南:轻松实现C++到.NET的无缝集成

CppSharp终极指南:轻松实现C到.NET的无缝集成 【免费下载链接】CppSharp Tools and libraries to glue C/C APIs to high-level languages 项目地址: https://gitcode.com/gh_mirrors/cp/CppSharp 在当今多语言开发环境中,C与.NET的互操作性一直是…

作者头像 李华
网站建设 2026/9/4 23:12:24

AI如何解决‘Unable to Connect to Anthropic Services‘错误

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 开发一个AI辅助调试工具,能够自动检测Unable to Connect to Anthropic Services错误。工具应包含以下功能:1. 网络连接诊断模块,检查API端点可达…

作者头像 李华
网站建设 2026/9/4 13:15:35

​​​​​​​拼多多API应用场景大揭秘,让你的店铺玩法多样!

引言 在电商竞争日益激烈的今天,仅仅依靠平台的前台操作界面进行店铺管理已经远远不够。拼多多开放平台提供的API(应用程序接口)为商家和开发者打开了一扇通往自动化、精细化、智能化运营的大门。善用API,不仅能大幅提升运营效率&…

作者头像 李华
网站建设 2026/9/5 13:46:19

蓝牙模块介绍

1.蓝牙模块简介蓝牙模块(蓝牙转串口模块)可以将有线串口数据流转换为无线蓝牙数据流,实现无线串口功能蓝牙模块实物图一定要注意蓝牙的分类,不同的蓝牙类别是不兼容的,所能够连接的设备和实现的功能也会不一样2.硬件连…

作者头像 李华
网站建设 2026/9/5 7:00:11

电商系统实战:Java Base64图片处理全流程

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 生成一个电商系统中的图片处理模块代码,要求:1.前端上传图片转Base64的JavaScript代码 2.后端Java接收Base64并保存为文件的接口 3.图片压缩和缩略图生成的实…

作者头像 李华
网站建设 2026/9/4 14:20:16

比手动快10倍:自动化处理证书过期的技巧

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 构建一个证书自动化管理工具,功能包括:1. 定时扫描所有域名证书状态 2. 过期前30/15/7天分级预警 3. 与Lets Encrypt API集成自动续期 4. 支持多服务器证书部…

作者头像 李华