# docker compose和docker区别

Docker 是单容器管理工具，负责构建和运行独立容器；Docker Compose 是多容器编排工具，用于定义和协调多个容器组成的应用 。两者核心区别在于管理粒度与配置方式，Compose 底层依赖 Docker 引擎运行 。

## 核心定位与依赖关系

1. 管理对象：Docker 专注于单个容器的生命周期管理（如启动、停止、删除）。Docker Compose 则管理一组关联容器，将多个服务视为一个整体应用进行编排 。
2. 依赖关系：Docker 可独立运行，而 Docker Compose 必须依赖 Docker 环境，通过调用 Docker API 实现容器集群的快速编排 。
3. 网络与存储：Docker 需手动配置容器间网络连接；Compose 可在配置文件中自动定义服务间网络互通及共享数据卷 。

## 配置文件与命令差异

1. 配置方式：Docker 使用命令行参数或 `Dockerfile` 定义单个镜像构建 。Docker Compose 使用 `docker-compose.yml` 文件声明式定义所有服务的端口、环境和依赖 。
2. 命令格式：
   - 旧版命令为 `docker-compose up`（带连字符）。
   - 新版 Docker 推荐插件版命令 `docker compose up`（空格分隔），需确保安装版本支持 。
3. 操作效率：Docker 启动多服务需逐条执行 `docker run`；Compose 仅需一条命令即可启动或停止所有服务 。

## 适用场景对比

1. Docker 场景：适合单一服务的快速测试、部署或构建自定义镜像，如独立运行 Nginx 或 Redis。
2. Compose 场景：适合微服务架构或复杂系统（如 Web+ 数据库 + 缓存），需协调服务启动顺序及依赖关系的场景 。
3. 开发维护：简单应用用 Docker 更直接；复杂应用用 Compose 更易于版本控制和环境复现 。

## 如何编写Dockerfile
编写Dockerfile是构建Docker镜像的基本步骤，它定义了如何构建镜像以及在其中运行的软件。下面是一个基本的步骤指南和示例，帮助你开始使用Dockerfile。

1. 了解Dockerfile的基本结构

一个简单的Dockerfile看起来像这样：

```dockerfile
使用官方Python运行时作为父镜像
FROM python:3.8-slim

设置工作目录在容器内
WORKDIR /app

将当前目录内容复制到位于/app的容器中
COPY . /app

使用pip安装requirements.txt中指定的任何依赖项
RUN pip install --no-cache-dir -r requirements.txt

使端口80可用对外的连接
EXPOSE 80

定义环境变量
ENV NAME World

运行app.py 当容器启动时
CMD ["python", "app.py"]
```

2. 创建Dockerfile

1. 打开文本编辑器，创建一个新文件，命名为`Dockerfile`（没有文件扩展名）。
2. 添加指令：根据上述示例，添加你的指令。例如，如果你正在创建一个Python应用，你可以按照上面的示例来写。

3. 构建Docker镜像

在包含Dockerfile的目录中打开终端或命令提示符，运行以下命令来构建你的Docker镜像：

```bash
docker build -t your-image-name .
```

这里，`your-image-name`是你给镜像起的名字，`.`表示Dockerfile位于当前目录。

4. 运行你的Docker容器

一旦镜像构建完成，你可以使用以下命令来运行你的容器：

```bash
docker run -p 4000:80 your-image-name
```

这里，`-p 4000:80`将容器的80端口映射到宿主机的4000端口。

常见Dockerfile指令解释：

- FROM: 指定基础镜像，所有构建步骤将从这里开始。
- WORKDIR: 设置工作目录。
- COPY: 将文件或目录从构建上下文复制到镜像中。
- RUN: 在shell中执行命令并提交结果。
- CMD: 提供容器启动时默认执行的命令。
- EXPOSE: 声明运行时监听的端口。
- ENV: 设置环境变量。
- ENTRYPOINT: 配置容器启动时运行的可执行文件。
- VOLUME: 创建挂载点，用于从宿主机或其他容器挂载卷。
- USER: 指定运行镜像的用户。
- HEALTHCHECK: 配置容器健康检查。
- ARG: 定义构建参数。
- ONBUILD: 当所创建的镜像被用作其他Dockerfile的基础时，执行指令。
- LABEL: 为镜像添加元数据。

小贴士：

- 确保你的Dockerfile中没有语法错误。你可以通过运行`docker build`命令来自动检查这些错误。
- 使用`.dockerignore`文件来排除不需要复制到镜像中的文件，以加快构建过程。例如，你可以忽略`.git`目录或临时文件等。
- 每次修改Dockerfile后，重新运行`docker build`来更新你的镜像。确保使用相同的`your-image-name`标签以避免创建重复的镜像。

通过上述步骤和示例，你应该能够开始使用Dockerfile来构建自己的Docker镜像了。

## 如何编写docker-compose.yml
要编写一个`docker-compose.yml`文件，你需要定义服务（services）、网络（networks）以及卷（volumes），这些是Docker Compose的核心概念。下面是一个基本示例，展示了如何为一个简单的Web应用设置Docker Compose。

示例：一个包含Nginx和Node.js应用的`docker-compose.yml`

1. 文件结构

假设你的项目结构如下：

```
myapp/
  docker-compose.yml
  nginx/
    Dockerfile
  nodeapp/
    Dockerfile
    package.json
    app.js
```

2. `docker-compose.yml`文件内容

```yaml
version: '3.8'  使用Docker Compose的版本号

services:
  nginx:
    build: ./nginx  使用当前目录下的nginx文件夹中的Dockerfile构建镜像
    ports:
      - "8080:80"  将容器的80端口映射到主机的8080端口
    depends_on:
      - nodeapp  启动顺序依赖nodeapp服务
    networks:
      - mynetwork  使用mynetwork网络

  nodeapp:
    build: ./nodeapp  使用当前目录下的nodeapp文件夹中的Dockerfile构建镜像
    networks:
      - mynetwork  使用mynetwork网络
    volumes:
      - ./nodeapp:/usr/src/app  挂载当前目录下的nodeapp文件夹到容器的/usr/src/app目录

networks:
  mynetwork:  定义网络
    driver: bridge  使用bridge模式，这是默认的网络驱动
```

3. `nginx/Dockerfile`内容

```dockerfile
FROM nginx:latest
COPY ./default.conf /etc/nginx/conf.d/default.conf
```

假设`default.conf`文件内容如下，用于将流量代理到Node.js应用：

```nginx
server {
    listen 80;
    location / {
        proxy_pass http://nodeapp:3000;  将请求代理到nodeapp服务的3000端口
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
```

4. `nodeapp/Dockerfile`内容

```dockerfile
FROM node:14  使用Node.js 14的基础镜像
WORKDIR /usr/src/app  设置工作目录为/usr/src/app
COPY package*.json ./  复制package.json和package-lock.json到工作目录
RUN npm install  安装项目依赖
COPY . .  复制所有文件到工作目录
CMD ["node", "app.js"]  启动命令为node app.js
```

5. 使用Docker Compose启动服务

在项目根目录（包含`docker-compose.yml`的目录）下，运行以下命令来启动服务：

```bash
docker-compose up -d
```

这将会构建镜像，创建并启动服务，并使它们在后台运行。使用`docker-compose down`可以停止并移除这些服务。