Docker多阶段构建问题:如何从自定义构建容器拷贝文件到Nginx?
错误原因
Docker 的 COPY --from=<name> 指令是从本地镜像或镜像仓库中的镜像拷贝文件,而非从正在运行的容器。你指定的 builder_one 和 builder_two 是容器名称,不是本地已构建完成的镜像,因此 Docker 会默认去公共镜像仓库拉取同名镜像,自然找不到对应资源,从而触发权限验证失败/镜像不存在的错误。
正确实现方式
步骤1:先构建站点的 Builder 镜像
每个站点需要先构建出包含编译产物的本地镜像,以常见前端项目为例:
site_one 的 Dockerfile(示例)
# ./site_one/Dockerfile FROM node:18-alpine WORKDIR /usr/src/site_one COPY package*.json ./ RUN npm ci COPY . . RUN npm run build
执行构建命令,生成名为 builder_one 的本地镜像:
docker build -t builder_one ./site_one
site_two 的 Dockerfile(示例)
# ./site_two/Dockerfile FROM node:18-alpine WORKDIR /usr/src/site_two COPY package*.json ./ RUN npm ci COPY . . RUN npm run build
构建镜像:
docker build -t builder_two ./site_two
步骤2:修改并构建 Nginx 镜像
此时 builder_one 和 builder_two 是本地存在的镜像,你的 Nginx Dockerfile 可以正常执行拷贝操作:
FROM nginx:latest COPY ./conf.d/ /etc/nginx/conf.d/ # COPY 会自动创建不存在的目标目录,无需提前 RUN mkdir COPY --from=builder_one /usr/src/site_one/build/ /usr/share/nginx/html/site_one/ COPY --from=builder_two /usr/src/site_two/build/ /usr/share/nginx/html/site_two/
构建 Nginx 镜像:
docker build -t my_nginx ./nginx
其他替代方案
方案1:用 Docker Compose 统一编排
通过 docker-compose.yml 管理所有服务,确保 Nginx 构建依赖于两个 Builder 镜像的生成:
# docker-compose.yml version: '3.8' services: builder_one: build: ./site_one image: builder_one command: /bin/true # 仅构建镜像,无需运行容器 builder_two: build: ./site_two image: builder_two command: /bin/true nginx: build: ./nginx ports: - "80:80" depends_on: - builder_one - builder_two
执行 docker-compose build 即可按顺序完成所有镜像的构建。
方案2:本地拷贝/挂载(适合开发环境)
如果不想构建 Builder 镜像,可直接在本地生成编译产物,通过拷贝或挂载方式同步到 Nginx 容器:
- 拷贝到运行中的容器:
docker cp ./site_one/build/ 你的nginx容器名:/usr/share/nginx/html/site_one/ docker cp ./site_two/build/ 你的nginx容器名:/usr/share/nginx/html/site_two/
- 启动容器时挂载本地目录:
docker run -d -p 80:80 \ -v ./site_one/build/:/usr/share/nginx/html/site_one/ \ -v ./site_two/build/:/usr/share/nginx/html/site_two/ \ -v ./nginx/conf.d/:/etc/nginx/conf.d/ \ nginx:latest
这种方式适合开发阶段实时更新代码,但生产环境建议用镜像拷贝的方式,避免依赖本地文件。
内容的提问来源于stack exchange,提问作者Karolis
相关产品推荐
相关产品推荐

