如何从零搭建新开发Docker环境?相关实操问题咨询
问题解答与实践建议
1. bind mount时是否需要COPY init.sh?为什么找不到脚本?
- 如果是将宿主机项目根目录绑定挂载到容器的工作目录,不需要用COPY指令复制脚本——只要宿主机根目录下存在
init.sh,容器内就能通过挂载路径访问到它。 - 找不到脚本的常见原因:
- 宿主机挂载目录下压根没有
init.sh(首次运行前要确保脚本已经创建在宿主机对应位置); - 容器内执行脚本的路径错误(比如用相对路径但工作目录不对,建议直接用绝对路径执行,比如
/app/init.sh); - 挂载操作覆盖了容器内原本的脚本位置(比如你先把脚本COPY到容器的
/app,然后把宿主机的空目录挂载到/app,脚本就被覆盖没了)。
- 宿主机挂载目录下压根没有
2. 绑定整个项目是否合理?
合理,这是开发环境实现代码热更新的常规操作,但要注意几个细节:
- 用
.dockerignore排除冗余文件(比如node_modules、.git、dist),避免挂载不必要的内容拖慢性能; - 处理权限问题:容器内的用户UID/GID和宿主机不一致时,创建的文件会出现权限异常,可在
docker-compose.yml里添加user: "${UID}:${GID}"同步宿主机用户权限; - 隔离依赖:通过额外的匿名volume覆盖容器内的
node_modules(比如- /app/backend/node_modules),防止宿主机的依赖包干扰容器环境。
3. 有没有办法让源码直接位于根目录?
可以,但不建议把宿主机根目录直接挂载到容器根目录(会覆盖容器系统文件,导致异常)。更安全的实现方式:
- 修改
init.sh里的项目创建命令,直接在容器工作目录(对应宿主机根目录)生成NestJS项目:
这样宿主机根目录就是NestJS项目的源码目录,无需单独的nest new . --non-interactive --skip-git --package-manager npmbackend文件夹。不过这种方式会让根目录充满项目文件,后续扩展前端项目时容易混乱,更推荐用单独的backend/frontend目录区分。
从零开始的完整流程实践
1. 初始目录结构
./ ├── docker-compose.yml ├── dockerfiles/ │ └── backend.Dockerfile ├── init.sh └── .dockerignore
2. 编写.dockerignore
node_modules dist .git .gitignore .env
3. 编写init.sh(解决nest new交互式问题)
#!/bin/sh # 检查是否已存在NestJS项目 if [ ! -f "./backend/package.json" ]; then # 非交互式创建NestJS项目到backend目录 nest new backend --non-interactive --skip-git --package-manager npm elif [ ! -d "./backend/node_modules" ]; then # 已有项目但无依赖,自动安装 cd backend && npm install fi # 启动开发服务 cd backend && npm run start:dev
4. 编写backend.Dockerfile
FROM node:18-alpine # 安装NestJS CLI RUN npm install -g @nestjs/cli # 设置工作目录 WORKDIR /app # 赋予脚本执行权限(也可以在宿主机先执行chmod +x init.sh) RUN chmod +x /app/init.sh EXPOSE 3000 # 执行初始化脚本 CMD ["/bin/sh", "/app/init.sh"]
5. 编写docker-compose.yml
version: '3.8' services: backend: build: context: . dockerfile: dockerfiles/backend.Dockerfile ports: - "3000:3000" volumes: # 绑定宿主机当前目录到容器工作目录 - ./:/app # 隔离容器内的node_modules - /app/backend/node_modules # 同步宿主机用户权限,避免文件权限问题 user: "${UID}:${GID}" environment: - NODE_ENV=development
6. 首次运行
在宿主机根目录执行:
chmod +x init.sh docker-compose up --build
第一次运行会自动创建NestJS项目并安装依赖,后续启动直接拉起服务,修改宿主机代码会自动同步到容器实现热更新。
内容的提问来源于stack exchange,提问作者H3lltronik
相关产品推荐
相关产品推荐

