我们正在服务器上切换到 Docker 容器,以便我们可以轻松地扩展和缩小服务器实例。
我们能够在产品上运行实例,一切都很好,但是存在外部问题阻止该切换。然而,在我们的功能分支上,构建全部失败。
# syntax=docker/dockerfile:1
# Client web
ARG NODE_VERSION=18.20.1
ARG PNPM_VERSION=8.6.10
################################################################################
# Use node image for base image for all stages.
FROM node:${NODE_VERSION}-alpine as base
# Set working directory for all build stages.
WORKDIR /usr/src/app
# Install pnpm.
RUN npm install -g pnpm@${PNPM_VERSION}
################################################################################
# Create a stage for installing production dependencies.
FROM base as deps
# Copy package manager configuration and lock files first to leverage Docker caching
COPY .npmrc .npmrc
COPY package.json pnpm-lock.yaml ./
# Install dependencies
RUN pnpm install --prod --frozen-lockfile
# Remove .npmrc after installation to secure
RUN rm -f .npmrc
################################################################################
# Create a stage for building the application.
FROM deps as build
# Copy package manager configuration and lock files first to leverage Docker caching
COPY package.json pnpm-lock.yaml ./
# Install development dependencies
# RUN pnpm install --frozen-lockfile
# Copy the rest of the source files into the image.
COPY . .
# Run the build script.
RUN pnpm run build
################################################################################
# Create a new stage to run the application with minimal runtime dependencies
# where the necessary files are copied from the build stage.
FROM base as final
# Set environment variables.
ARG NODE_ENV=production
ARG ENV=production
ARG PORT=8020
ARG CLIENT=client1
ARG API_ENV=prod
ARG CURRENT_RELEASE_TAG=fallback-tag
# Use production node environment by default.
ENV NODE_ENV=${NODE_ENV} \
ENV=${ENV} \
PORT=${PORT} \
FEED_SOURCE=https://${CLIENT}-api-${API_ENV}.example.co.uk \
CURRENT_RELEASE_TAG=${CURRENT_RELEASE_TAG}
# Run the application as a non-root user.
USER node
# Copy package.json so that package manager commands can be used.
COPY package.json .
# Copy the environment file.
RUN ls -la
COPY .env .env
# Copy the production dependencies from the deps stage and also
# the built application from the build stage into the image
COPY --from=deps --chown=node:node /usr/src/app/node_modules ./node_modules
COPY --from=build --chown=node:node /usr/src/app/ ./
# Expose the port that the application listens on.
EXPOSE 8020
# Run the application.
CMD pnpm start
这是我们在 Jenkins 上遇到的错误:
#12 [final 3/5] COPY .env .env
#12 ERROR: failed to calculate checksum of ref b8dc9192-ad6a-45e2-b47b-b9c0625a2478::tnrbpv5dx0dd8lja68zz6akz2: "/.env": not found
------
> [final 3/5] COPY .env .env:
------
dockerfile:74
--------------------
72 | # Copy the environment file.
73 | RUN ls -la
74 | >>> COPY .env .env
75 |
76 | # Copy the production dependencies from the deps stage and also
--------------------
ERROR: failed to solve: failed to compute cache key: failed to calculate checksum of ref b8dc9192-ad6a-45e2-b47b-b9c0625a2478::tnrbpv5dx0dd8lja68zz6akz2: "/.env": not found
我们尝试了以下命令:
COPY .env[t] .env
印象中它会读取 .env.defaults 或 .env.preview 文件,但事实并非如此。
.env 不在 dockerignore 中
我们最初假设
copy . .
也会负责复制 .env 文件。
需要做什么才能在我们的功能分支上 dockerfile 读取 .env.defaults?
通过从 docker 端删除 .env 的副本并通过 Jenkins 设置文件设置相关的 .env 变量解决了这个问题。