#node.js #docker #next.js
Вопрос:
При тестировании и использовании моего приложения NextJS с .env.local все работает отлично. Однако, когда я выполняю производственную сборку для развертывания, она не может найти значения .env.production (хотя на данный момент это точная копия .env.local). Когда я добавил конечную точку, которая выполняет console.log(process.env), ни одно из значений .env.production не присутствует.
Вот мой Dockerfile
# Install dependencies only when needed
FROM node:alpine AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile
# Rebuild the source code only when needed
FROM node:alpine AS builder
WORKDIR /app
COPY . .
COPY --from=deps /app/node_modules ./node_modules
RUN yarn build amp;amp; yarn install --production --ignore-scripts --prefer-offline
# Production image, copy all the files and run next
FROM node:alpine AS runner
WORKDIR /app
ENV NODE_ENV production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
# You only need to copy next.config.js if you are NOT using the default configuration
# COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
USER nextjs
EXPOSE 3000
# Next.js collects completely anonymous telemetry data about general usage.
# Learn more here: https://nextjs.org/telemetry
# Uncomment the following line in case you want to disable telemetry.
# ENV NEXT_TELEMETRY_DISABLED 1
CMD ["yarn", "start"]
и я создаю образ с помощью этой команды:
docker build -t my-next-project .
При выполнении сборки вручную:
next build
это написано в консоли:
info - Loaded env from /Users/name/source/my-next-project/.env.local
info - Loaded env from /Users/name/source/my-next-project/.env.production
Таким образом, он находит два файла .env…не уверен, что здесь не работает.
Редактировать:
Вот журнал выполнения моей команды сборки docker docker build -t app-container .
[ ] Building 140.1s (14/21)
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/node:alpine 1.4s
=> [auth] library/node:pull token for registry-1.docker.io 0.0s
[ ] Building 140.2s (14/21)
=> => transferring context: 290.52MB 17.2s
=> [deps 1/5] FROM docker.io/library/node:alpine@sha256:f372a9ffcec27159dc9623bad29997a1b61eafbb145dbf4f7a64568be2f59b99 0.0s
=> CACHED [deps 2/5] RUN apk add --no-cache libc6-compat 0.0s
=> CACHED [deps 3/5] WORKDIR /app 0.0s
=> [deps 4/5] COPY package.json yarn.lock ./ 0.4s
[ ] Building 140.4s (14/21)
=> [deps 1/5] FROM docker.io/library/node:alpine@sha256:f372a9ffcec27159dc9623bad29997a1b61eafbb145dbf4f7a64568be2f59b99 0.0s
[ ] Building 140.5s (14/21)
=> CACHED [deps 3/5] WORKDIR /app 0.0s
[ ] Building 152.6s (22/22) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/node:alpine 1.4s
=> [auth] library/node:pull token for registry-1.docker.io 0.0s
=> [internal] load build context 17.6s
=> => transferring context: 290.52MB 17.2s
=> [deps 1/5] FROM docker.io/library/node:alpine@sha256:f372a9ffcec27159dc9623bad29997a1b61eafbb145dbf4f7a64568be2f59b99 0.0s
=> CACHED [deps 2/5] RUN apk add --no-cache libc6-compat 0.0s
=> CACHED [deps 3/5] WORKDIR /app 0.0s
=> [deps 4/5] COPY package.json yarn.lock ./ 0.4s
=> CACHED [builder 2/6] WORKDIR /app 0.0s
=> [builder 3/6] COPY . . 10.6s
=> [deps 5/5] RUN yarn install --frozen-lockfile 33.0s
=> [builder 4/6] ADD ./.env.production ./.env.production 0.1s
=> [builder 5/6] COPY --from=deps /app/node_modules ./node_modules 3.0s
=> [builder 6/6] RUN NODE_ENV=production yarn build amp;amp; yarn install --production --ignore-scripts --prefer-offline 89.7s
=> CACHED [runner 3/8] RUN addgroup -g 1001 -S nodejs 0.0s
=> CACHED [runner 4/8] RUN adduser -S nextjs -u 1001 0.0s
=> [runner 5/8] COPY --from=builder /app/public ./public 0.1s
=> [runner 6/8] COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next 0.4s
=> [runner 7/8] COPY --from=builder /app/node_modules ./node_modules 1.8s
=> [runner 8/8] COPY --from=builder /app/package.json ./package.json 0.0s
=> exporting to image 1.9s
=> => exporting layers 1.9s
=> => writing image sha256:0e529630769589eefbdb0871e7024ea7f296db978c45102e7804e489d6d2f712 0.0s
=> => naming to docker.io/library/app-container
Комментарии:
1. попробуй это
ENV NODE_ENV = production
2. @Джером, это не имело никакого значения.
3. вместо того, чтобы использовать конечную точку для проверки, я бы вошел в работающий контейнер и проверил текущий env. Получите имя ваших запущенных контейнеров
docker container ls
, войдите в свой контейнерdocker exec -it containerName sh
, проверьте переменные envenv
4. Я получаю ответ, что NODE_ENV=производство
5. так что все в порядке…
Ответ №1:
Если вы НЕ используете конфигурацию по умолчанию, вам необходимо раскомментировать:
COPY --from=builder /app/next.config.js ./
в этой части вы должны скопировать все ваши рабочие файлы в контейнер, подобный вашим .env
файлам, из builder
like:
COPY --from=builder /app/.env.production ./
Ответ №2:
Поскольку React генерирует/компилирует файлы для производственных проектов и проектов react, выполняемых на стороне клиента, заданные вами переменные среды применимы только для серверной среды, а не для приложения, запущенного в браузере. Вы должны указать свои переменные во время сборки, чтобы конструктор заменил/сохранил их в сгенерированных файлах.
Итак, используйте параметрический файл Dockerfile для ваших сборок в качестве:
Докерфайл:
...
FROM abc-image
ARG VARIABLE_NAME="Default value(may be for your local development)" # after FROM
...
...
ENV VARIABLE_NAME_IN_REACT=$VARIABLE_NAME # at step just before the build
# (I have not tried but single name might be enough as both arg and
# variable name)
...
В вашем конвейере, где ваша строка «сборка докера» :
...
docker build --build-arg VARIABLE_NAME="Value of the variable"
...
Ответ №3:
По моему опыту, NextJS, похоже, читает файлы .env при запуске. Таким образом, .env.production
необходимо присутствовать при yarn start
. Но в вашем текущем Dockerfile
он не скопирован на вашем этапе бегуна. Поэтому добавьте следующую строку в свой этап бегуна:
COPY --from=builder /app/.env.production ./
Комментарии:
1. В документах говорится, что встраивание переменной среды происходит во время сборки. nextjs.org/docs/basic-features/environment-variables
2. @ckeeney да, это так. Но в разделе только для переменных среды браузера 😉