Home > OS >  NextJS environment variables not accessible in production build
NextJS environment variables not accessible in production build

Time:10-06

I have a NextJS application that accesses a database from the API.

When in development, I have a .env file that contains the host, port, username, password, and database. After running npm run dev, the API functionality works as expected. Even if I run npm run build and npm run start on my local machine, it works correctly.

The problem comes after I push to Github and have Github build the app and deploy it as a docker container. For some reason, the docker build does not accept my environment variables loaded through an attached .env file.

To further elaborate, the environment variables are either on the dev machine or attached to the docker container on the production server. They are mounted to the same place (the root directory of the project: /my-site/.env) but the production API does not work.

The environment variables are included in /lib/db.tsx:

import mysql from "mysql2/promise";

const executeQuery = async (query: string) => {
  try {
    const db = await mysql.createConnection({
      host: process.env.MYSQL_HOST,
      database: process.env.MYSQL_DATABASE,
      user: process.env.MYSQL_USER,
      password: process.env.MYSQL_PASSWORD,
    });

    const [results] = await db.execute(query, []);
    db.end();

    return results;
  } catch (error) {
    return { error };
  }
};

export default executeQuery;

This file is included in the API endpoints as: import executeQuery from "../../../../lib/db";

Again, since it works on the development computer, I think there is an issue is with the building of the docker container.

Here is my included Dockerfile:

FROM node:lts as dependencies
WORKDIR /my-site
COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

FROM node:lts as builder
WORKDIR /my-site
COPY . .
COPY --from=dependencies /my-site/node_modules ./node_modules
RUN yarn build

FROM node:lts as runner
WORKDIR /my-site
ENV NODE_ENV production
# If you are using a custom next.config.js file, uncomment this line.
# COPY --from=builder /my-site/next.config.js ./
COPY --from=builder /my-site/public ./public
COPY --from=builder /my-site/.next ./.next
COPY --from=builder /my-site/node_modules ./node_modules
COPY --from=builder /my-site/package.json ./package.json

EXPOSE 3000
CMD ["yarn", "start"]

Any and all assistance is greatly appreciated!

Edit: Other things I have attempted:

  • Add them as environment variables to the docker container in the docker compose file (under environment) and verified that they are accessible inside of the container using echo $MYSQL_USER.
  • Mounting the .env file inside of the .next folder
  • Mounting the .env file inside of the .next/server folder

CodePudding user response:

I ended up solving my own issue after hours of trying to figure it out.

My solution was to create a .env.production file and commit it to git.

I also adjusted my Dockerfile to include: COPY --from=builder /my-site/.env.production ./

I am not a fan of that solution, as it involves pushing secrets to a repo, but it works.

CodePudding user response:

You have to manually add your .env file to docker using --env-file ./.env command in docker-cli

  • Related