🌟前言
本文适合中国Docker Compose小白体质🐼
🎈正文
1. Dockerfile和Docker Compose的关系
- Dockerfile:像是"菜谱",告诉Docker如何一步步构建一个镜像(比如你的应用环境)
- Docker Compose :像是"餐厅点单系统",你可以一次性管理 多个容器(服务) 及其之间的关系
简单说:【Dockerfile】用来构建 【单个容器】 ,【Docker Compose】用来【编排多个容器】组成的应用。
2. 从Dockerfile到Docker Compose的快速转换
假设你有一个简单的Node.js应用的Dockerfile:
dockerfile
# Dockerfile
FROM node:14
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
对应的docker-compose.yml可能是:
yaml
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
3. Docker Compose核心概念
这一块内容建议全文背诵
3.1 【重点】services (服务)
- 每个service 对应一个容器
- 可以指定镜像或使用Dockerfile构建
yaml
services:
web:
build: . # 使用当前目录的Dockerfile构建
ports:
- "5000:5000" # 左边是宿主机端口,右边是容器端口
redis:
image: "redis:alpine" # 直接使用现成镜像
上例子!
假设你的配置如下:
Dockerfile
# Dockerfile
FROM node:14
EXPOSE 3000
# 此处的EXPOSE 3000 只是【文档声明】,容器设计上会使用3000端口,实际效果取决于:
# 1. 应用代码是否真的监听3000端口(如app.js中的app.listen(3000))
# 2. 是否通过docker run -p或compose的ports:做了端口映射
CMD ["node", "app.js"]
那么你的docker-compose.yml文件可以是这样:
yml
# docker-compose.yml
services:
web:
build: .
ports:
- "8080:3000" # 真正把宿主机的8080映射到容器的3000
也就是说:
- 容器内部:应用运行在3000端口(由Dockerfile的
EXPOSE
声明) - 主机访问:通过
localhost:8080
访问(由compose的ports
实现)
3.2 networks (网络)
- 默认会创建一个网络,所有服务都能通过服务名互相访问
- 可以自定义网络
yaml
networks:
my-network:
driver: bridge
3.3 volumes (卷)
- 持久化数据
- 共享数据
yaml
volumes:
db-data: # 声明一个卷
4. 常用指令对比
Dockerfile指令 | Docker Compose对应配置 |
---|---|
FROM | image: |
RUN | 在Dockerfile中保留【这些指令应该继续写在 Dockerfile 里,不需要转移到 docker-compose.yml】 |
COPY/ADD | 在Dockerfile中保留【这些指令应该继续写在 Dockerfile 里,不需要转移到 docker-compose.yml】 |
EXPOSE | ports: |
CMD | command: |
ENV | environment: |
5. 实际案例【可以拿来参考】:一个Web应用+数据库
yaml
version: '3.8'
# ❗❗❗每个【service】对应一个【容器】!!!
services:
web: # 这是一个service 也就是一个容器
build: .
ports:
- "3000:3000"
environment:
- DB_HOST=db
- DB_PORT=5432
depends_on:
- db
volumes:
- .:/app # 开发时挂载代码目录
db: # 这也是一个service 也是一个容器
image: postgres:13
environment:
- POSTGRES_PASSWORD=secret
- POSTGRES_DB=mydb
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
6. Docker Compose常用命令
docker-compose up
:启动所有服务(加-d
后台运行)docker-compose down
:停止并移除所有容器docker-compose build
:重新构建镜像docker-compose logs
:查看日志docker-compose ps
:查看运行中的服务
7. 如果有人问你为啥学docker compose的满分答案
- 一键启停:不用记住每个容器的启动参数
- 环境隔离:每个项目可以有独立的compose环境
- 简化网络:自动创建网络,服务间通过名称访问
- 开发友好:方便配置开发环境(如挂载代码目录)
8. 从开发到生产
开发环境可能这样配置:
yaml
services:
web:
build: . # 每次启动从本地Dockerfile实时构建
ports:
- "3000:3000" # 映射到非标准端口(避免冲突)
volumes:
- .:/app # 将主机代码目录挂载到容器(实现代码修改即时生效)
environment:
- NODE_ENV=development # 开发模式(启用调试日志等)
目的是啥:
- 快速迭代 :通过
volumes
挂载代码,开发者修改主机代码后,容器内立即生效(无需重建镜像)。 - 调试友好 :
NODE_ENV=development
会启用更详细的日志、热重载等功能。 - 安全性较低:开发环境通常不需要高安全配置。
生产环境则可能:
yaml
services:
web:
image: myapp:prod # 使用预构建的优化镜像(非实时构建)
ports:
- "80:3000" # 映射到HTTP默认端口80(方便用户访问)
environment:
- NODE_ENV=production # 生产模式(优化性能和安全)
deploy:
replicas: 3 # 启动3个容器实例(负载均衡和高可用)
目的是啥:
- 稳定性优先 :使用预构建的
myapp:prod
镜像(经过测试和优化,而非实时构建)。 - 高性能 :
NODE_ENV=production
会启用代码压缩、缓存等优化。 - 高可用 :通过
replicas: 3
启动多个实例(需配合 Swarm/Kubernetes 实现负载均衡)。 - 标准化访问:端口 80 是 HTTP 默认端口,用户无需输入端口号。
👋最后
Dockerfile是基础,Docker Compose是进阶工具,它们不是替代关系而是互补关系!
收摊!
🍃