docker配置入门知识

153 阅读5分钟

1. ${NODE_ENV:-production} 语法解释

这是Docker Compose的环境变量替换语法:

  • ${NODE_ENV:-production} 表示:如果环境变量 NODE_ENV 存在且不为空,则使用 NODE_ENV 的值;否则使用默认值 production
  • :- 是默认值操作符
  • 等价于:NODE_ENV=${NODE_ENV:-production}

示例:

# 如果 .env 文件中有 NODE_ENV=development
# 则实际值为 development

# 如果 .env 文件中没有 NODE_ENV 或为空
# 则使用默认值 production

2. Docker服务重启和更新

Docker不会自动监听文件变化,需要手动重启:

修改docker-compose.yaml后:

# 停止所有服务
docker-compose down

# 强制重新构建镜像
docker-compose build --no-cache app

# 强制重启所有服务
docker-compose up -d

# 重新构建并启动所有服务
docker-compose up --build -d <service_name>

# 或者只重启特定服务
docker-compose restart app
# docker-compose 进入容器(交互式)
docker compose exec <service_name> bash
docker compose exec <service_name> sh

# docker-compose 进入容器并执行命令(直接执行命令)
docker compose exec <service_name> <command>

# 直接执行命令
docker compose exec backend sh -c "npm run build"
docker compose exec backend sh -c "cd /app && node index.js"

# 创建临时容器执行命令
docker compose run --rm <service_name> <command>

3. restart: unless-stopped 含义

这是Docker容器的重启策略:

策略说明
no不自动重启(默认)
always总是重启,无论退出状态如何
on-failure只在非零退出状态时重启
unless-stopped总是重启,除非手动停止

unless-stopped 的优势:

  • 容器异常退出时自动重启
  • 系统重启后自动启动容器
  • 手动停止后不会自动重启(避免干扰调试)

4. 完整的重启流程示例

# 1. 停止所有服务
docker-compose down

# 2. 查看当前状态
docker-compose ps

# 3. 重新构建并启动
docker-compose up --build -d

# 4. 查看日志
docker-compose logs -f app

# 5. 检查服务状态
docker-compose ps

5. 开发环境建议

对于开发环境,建议使用卷挂载来避免频繁重建:

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - .:/app                    # 代码同步
      - /app/node_modules         # 避免覆盖依赖
    command: pnpm run start:dev   # 开发模式,支持热重载

这样代码修改后,只需要重启应用进程,不需要重新构建镜像。

6.修改配置

非常好的问题 👍,你这个担心是非常现实的 ——

在 docker-compose 项目中执行 up -d --build 确实会重新构建所有 build 声明的服务镜像,但默认情况下 不会自动清除已有的数据卷(volumes)或数据库数据,除非你显式删除了容器或卷。

不过,让我们来非常清晰地分辨几种情况👇


🧱 一、

docker-compose up -d --build

实际做了什么?

执行:

docker-compose up -d --build

Compose 会:

  1. 检查哪些服务定义了 build:;
  2. 对这些服务重新构建镜像;
  3. 停止并重启依赖该镜像的容器;
  4. 保留挂载的卷(volumes)内容;
  5. 不会删除数据卷;
  6. 不会影响使用外部镜像(如 image: mysql:8.0)的服务。

✅ 举个例子:

version: '3.8'
services:
  app:
    build: .
    ports:
      - "8080:8080"
    volumes:
      - ./app:/usr/src/app

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    volumes:
      - mysql_data:/var/lib/mysql

  redis:
    image: redis:7
    volumes:
      - redis_data:/data

volumes:
  mysql_data:
  redis_data:

执行:

docker-compose up -d --build

结果:****

  • ✅ app 会被重新 build;
  • 🚫 mysql 和 redis 不会被重新构建;
  • ✅ 数据卷 mysql_data / redis_data 不会丢失。

⚙️ 二、只重建(build + restart)某一个服务

你可以只 rebuild 某个服务,而不动其他的服务:

docker-compose up -d --build app

或者如果你只想重新 build 但暂不运行容器:

docker-compose build app

再启动:

docker-compose up -d app

👉 这不会动 mysql、redis,也不会影响数据卷。


🧩 三、如果你真的删除了容器,会不会丢数据?

这取决于是否挂了 volume:

情况数据是否丢失
使用了命名卷(volumes:)❌ 不会丢
使用了匿名卷(未命名)⚠️ 会丢
用了 bind 挂载(./mysql_data:/var/lib/mysql)❌ 不会丢(在宿主机文件夹中)
手动执行了 docker-compose down -v❌ 会清除所有卷

🧠 四、正确的安全更新姿势(推荐)

✅ 推荐方式 1:只重建目标服务

docker-compose up -d --build app

✅ 推荐方式 2:重建但不影响数据库

docker-compose up -d --no-deps --build app

--no-deps 表示不重启依赖的容器,比如数据库。

✅ 推荐方式 3:手动重建镜像

docker-compose build app
docker-compose restart app

💣 五、注意哪些操作会真的清空数据库数据

命令说明
docker-compose down -v❌ 删除容器 + 数据卷(会清空数据)
docker-compose rm -f mysql❌ 删除容器,如果卷是匿名的,会丢数据
docker volume prune❌ 删除所有未使用的卷(危险)
docker system prune -a⚠️ 会清空所有未运行容器和未挂载卷

✅ 六、最佳实践总结

目的命令说明
只重建某个服务docker-compose up -d --build app推荐方式
不重启依赖容器docker-compose up -d --no-deps --build app更稳妥
只编译镜像,不运行docker-compose build app手动控制启动
检查卷挂载情况docker volume ls确认数据安全
恢复卷数据使用命名卷或宿主机挂载永远别用匿名卷保存数据

一句话总结:****

修改了 Dockerfile,只想让该服务重建而不影响数据库:

docker-compose up -d --no-deps --build app

💡 数据卷不会丢失,MySQL / Redis 会继续使用原数据。


是否要我帮你生成一个“多服务项目安全更新模板”,

包含 Makefile + docker-compose 的命令脚本(支持一键安全更新应用服务但不动数据库)?