本地开发环境:用 mise + direnv 还是用 docker compose

起因

新项目要装:PostgreSQL 16 + Redis 7 + Node 20 + Python 3.12 + ImageMagick +
ffmpeg。同事的机器版本各异,"在我机器上能跑"频繁出现。
两种主流策略:

A. mise + direnv 安装到 host
B. docker compose 把依赖装容器

我俩都试过几次,下面记录适用场景 + 优缺点。

方案 A:mise + direnv(本地原生)

.tool-versions

python 3.12.5
nodejs 20.10.0
go 1.22.1
postgres 16.4
redis 7.4.0

.envrc

use mise
dotenv .env
PATH_add ./bin
export DATABASE_URL=postgresql://localhost/myapp
cd myapp
mise install     # 装 Python 3.12.5 + Node 20.10 + Go ...
# 第一次几分钟,之后秒级

DB / Redis 还是装 host:

brew install postgresql@16 redis
brew services start postgresql@16 redis

或者 host 上跑 docker 单独管 DB:

docker run -d --name pg -p 5432:5432 -v pg-data:/var/lib/postgresql/data \
  -e POSTGRES_PASSWORD=dev postgres:16
docker run -d --name redis -p 6379:6379 redis:7

优点

  • IDE 直接看到源码 + linter / 跳定义 / debugger 都丝滑
  • 启动快(mise install 几秒;之后开机即可用)
  • 不依赖 docker daemon(笔记本 RAM 友好)
  • 测试 / lint / build 直接跑 host CPU 速度

缺点

  • ImageMagick / ffmpeg 之类系统依赖每个 OS 装法不同
  • C 扩展可能因 OS / glibc 版本兼容问题
  • 多个项目用不同 Node 版本时偶尔切版本(mise 自动)

方案 B:docker compose(容器化)

docker-compose.yml

services:
  web:
    build: .
    volumes:
      - .:/app
      - node-modules:/app/node_modules    # 不让 host 的覆盖
    ports: ["3000:3000"]
    environment:
      DATABASE_URL: postgresql://app:dev@db/myapp
      REDIS_URL: redis://redis:6379
    depends_on:
      - db
      - redis

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: dev
      POSTGRES_DB: myapp
    volumes:
      - pg-data:/var/lib/postgresql/data
    ports: ["5432:5432"]

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

volumes:
  pg-data:
  redis-data:
  node-modules:

Dockerfile

FROM node:20-slim
RUN apt update && apt install -y python3 build-essential libpq-dev \
  ffmpeg imagemagick
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["npm", "run", "dev"]
docker compose up

优点

  • 跨 OS 完全一致(Mac / Linux / Windows 同结果)
  • 系统依赖 (ffmpeg 等) 在 Dockerfile,新人 onboarding docker compose up
    完事
  • 接近生产环境
  • 多项目隔离(每个项目自己一组 service)

缺点

  • 启动慢(image build 几分钟;首次 download image 几 GB)
  • IDE 集成稍复杂(要让 IDE 知道 venv 在容器里)
  • Mac / Windows 上 docker desktop 占内存(默认 4-8 GB)
  • 文件系统 bind mount 在 macOS 上有性能损失(npm install / build 慢 3-5x)

我的选择矩阵

场景 推荐
个人项目 + Linux 桌面 mise + direnv
个人项目 + Mac/Win mise + Docker for DB only
团队多人多 OS docker compose
复杂多服务(5+ container) docker compose(基本必须)
需要 IDE 强 debug mise(host 跑 Python/Node 直 debug)
onboarding 时间宝贵 docker compose
CI 跑测试 docker compose 镜像 + GitHub Action

混合方案(我个人用)

主要业务代码跑 host(mise 装好 Node/Python),仅 DB / Redis /
LocalStack 等 service 跑 docker。

docker-compose.dev.yml

services:
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: dev
      POSTGRES_DB: myapp
    ports: ["127.0.0.1:5432:5432"]
    volumes: [pg-data:/var/lib/postgresql/data]

  redis:
    image: redis:7-alpine
    ports: ["127.0.0.1:6379:6379"]

volumes:
  pg-data:
docker compose -f docker-compose.dev.yml up -d
mise install
direnv allow
npm run dev    # 跑 host

两者优点结合:IDE debug 顺滑 + 数据库环境一致。

痛点解决

Mac docker 文件慢

volumes:
  - .:/app:delegated   # macOS 优化(让容器写少同步给 host)

或用 mutagen-compose:rsync 风格双向同步代替 bind mount,
性能 10x。

node_modules 不同步

volumes:
  - .:/app
  - /app/node_modules    # named volume 让容器内的 node_modules 不被 host 空目录覆盖

多项目端口冲突

每个项目用不同端口:

ports: ["127.0.0.1:5433:5432"]   # 项目 A
ports: ["127.0.0.1:5434:5432"]   # 项目 B

或者用 Traefik 共享一个反代(前面有篇)。

完全云端 dev:Codespaces / Gitpod

// .devcontainer/devcontainer.json
{
  "image": "mcr.microsoft.com/devcontainers/python:3.12",
  "features": {
    "ghcr.io/devcontainers/features/node:1": { "version": "20" },
    "ghcr.io/devcontainers/features/docker-in-docker:2": {}
  },
  "postCreateCommand": "uv sync"
}

GitHub Codespaces 一键起一个云端 VSCode(已配齐所有依赖)。新人 30 秒
能 contribute,不需要本地装任何东西。

效果

我们团队(5 人,Mac/Linux 混用)现在用"混合方案":

  • 新人 onboarding 从 2 天 → 30 分钟(mise install + docker compose up)
  • IDE 调试体验保持原生
  • 数据库版本统一(postgres 16)跨所有人无差异
  • CI 用同样 docker image 测试 → 部署
  • "我机器能跑" 类问题归零

踩过的坑

  1. mise 装的 Python 链接 libssl 失败:openssl 升级后老 Python
    坏。mise reshim 重新链接,或 mise uninstall python && mise install

  2. docker compose volume 跨用户权限:root 跑了 docker,host
    非 root 用户读不了 volume 文件。改 docker-compose user: "1000:1000"
    或 chown。

  3. .env 进 git:永远 .env.example 进 git,.env 进 gitignore。

  4. 依赖装到全局:用 mise 跑 npm install -g 会装到 mise 管的
    Node 里。换 Node 版本就丢。改 npx some-tool 或本地 dev dep。

  5. VSCode 用错 venv.vscode/settings.json 指明
    "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python"

精确评价 共 0 人评价
可复现性
可复现 · 0 不可复现 · 0
文风
文风流畅 · 0 文风晦涩 · 0
立场
支持 · 0 反对 · 0

登录后即可对本帖作出评价。

评论区 0 条 · 所有人可在此交流

登录后参与评论。

还没有评论,来说两句。