Docker获取Node.js版本的来源解析及指定版本与实际部署版本不一致问题排查
咱们来一步步拆解你遇到的这个问题:
Docker是从哪里获取Node.js版本的?
Docker构建镜像时,会按照你Dockerfile里FROM指令指定的镜像,先检查本地有没有缓存这个镜像;如果没有,就去默认的镜像仓库(Docker Hub的docker.io/library)拉取对应的镜像元数据和文件。比如你指定的node:14.17.6-alpine3.13,Docker会精准匹配这个标签对应的镜像(只要标签本身是固定的)。
为什么会出现版本不一致的问题?
从你的日志和配置来看,最可能的原因有两个:
- Docker构建缓存复用:之前你可能构建过使用
node:16.13.2-alpine的镜像,Docker的构建缓存会自动复用之前的镜像层,导致这次构建没有重新拉取你指定的14.x版本,直接用了旧的缓存层。 - 构建上下文或Dockerfile不匹配:你
docker-compose.yml里指定的构建上下文是../angular-frontend,要确认这个路径下的Dockerfile确实是你贴的这个——有没有可能这个目录下的Dockerfile被误修改成了node:16.13.2-alpine,或者你不小心用了其他目录的Dockerfile?
补充一句:你指定的node:14.17.6-alpine3.13是固定版本标签,不会出现标签指向变更的问题(那种情况一般是用latest或者alpine这种浮动标签才会发生),所以可以排除这个因素。
该如何修改解决?
针对上面的原因,你可以按以下步骤尝试修复:
1. 强制清理缓存重新构建
直接让Docker跳过缓存,重新拉取你指定的Node.js镜像,执行这个命令:
docker-compose build --no-cache angular-frontend
这个命令会强制重新构建整个angular-frontend服务的镜像,不会复用任何之前的缓存层,确保拉取的是你Dockerfile里指定的node:14.17.6-alpine3.13。
2. 确认构建上下文和Dockerfile的正确性
去../angular-frontend目录下打开Dockerfile,检查第一行的FROM指令是不是确实写的node:14.17.6-alpine3.13。有时候可能因为文件同步问题、误修改,导致实际使用的Dockerfile和你以为的不一样。
3. 用镜像SHA哈希值彻底锁定版本(更稳妥的方案)
为了从根源避免这类版本不一致问题,你可以去Docker Hub找到node:14.17.6-alpine3.13对应的镜像SHA256哈希值,然后把Dockerfile里的FROM指令改成:
FROM node:14.17.6-alpine3.13@sha256:xxxxxxxxx AS development
(把xxxxxxxxx替换成实际的哈希值)这样Docker只会拉取这个哈希对应的镜像,完全不会出现标签匹配错误或者缓存复用的问题,是生产环境里推荐的做法。
附:你提供的相关配置与日志
Docker Compose部署日志
[+] Building 20.1s (11/17) => [docker_nestjs-backend internal] load build definition from Dockerfile 0.6s => => transferring dockerfile: 32B 0.0s => [docker_angular-frontend internal] load build definition from Dockerfile 0.7s => => transferring dockerfile: 32B 0.0s => [docker_nestjs-backend internal] load .dockerignore 0.9s => => transferring context: 2B 0.0s => [docker_angular-frontend internal] load .dockerignore 1.1s => => transferring context: 2B 0.0s // 此处 => [docker_angular-frontend internal] load metadata for docker.io/library/node:16.13.2-alpine 11.8s // ^ 该行显示Docker加载了16.13.2-alpine版本的元数据,但Dockerfile中指定的是node:14.17.6-alpine3.13 => CANCELED [docker_nestjs-backend internal] load build context 6.9s => => transferring context: 113.92MB 6.3s => [docker_angular-frontend development 1/6] FROM docker.io/library/node:16.13.2-alpine@sha256:2f50f4a428f8b5280817c9d4d896 0.0s => CACHED [docker_angular-frontend development 2/6] WORKDIR /usr/src/app 0.0s => [docker_angular-frontend internal] load build context 0.4s => => transferring context: 19.58kB 0.0s => [docker_angular-frontend development 3/6] COPY package*.json ./ 0.6s => ERROR [docker_angular-frontend development 4/6] RUN npm ci 5.6s
Dockerfile内容
# ----------------------------------------------- # 开发环境 # ----------------------------------------------- FROM node:14.17.6-alpine3.13 AS development WORKDIR /usr/src/app RUN npm install -g @angular/cli@12.2.6 COPY package*.json ./ RUN npm ci COPY . . RUN npm run build # ----------------------------------------------- # 生产环境 # ----------------------------------------------- FROM httpd:2.4 ENV TZ=Europe/Zurich RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone COPY ./docker/copy-source/httpd.conf /usr/local/apache2/conf/httpd.conf COPY --from=development /usr/src/app/dist /usr/local/apache2/htdocs/ ENTRYPOINT apachectl -DFOREGROUND
docker-compose.yml内容
version: '3.8' services: # ----------------------------------------------- # Angular前端服务 # ----------------------------------------------- angular-frontend: build: dockerfile: Dockerfile context: ../angular-frontend target: development container_name: angular-frontend command: npm run start links: - nestjs-backend ports: - "4200:4200" restart: on-failure volumes: - ./angular-frontend:/usr/src/app
内容的提问来源于Stack Exchange,提问作者dreikäsehoch2

