Next.js Discord

Discord Forum

Building image with docker & env variables (GitHub Actions)

Unanswered
Rampur Greyhound posted this in #help-forum
Open in Discord
Rampur GreyhoundOP
Hi everyone,

I'm currently facing an issue with my Next.js application and GitHub Actions, and I'm looking for some guidance or solutions to overcome it.

Here's the problem: I'm trying to build my Next.js application using GitHub Actions, and the build process is successful. However, I've noticed that my environment variables are being parsed into the output during the build. This is a concern for me because I want to securely pass these variables to the machine that will run the image, rather than having them exposed during the build process.

I'm looking for a way to prevent the environment variables from being included in the build output or to securely pass them at runtime rather than build time. This is crucial for maintaining the security of my application.

Has anyone else faced a similar issue or found a solution to this problem? I'd greatly appreciate any advice, best practices, or solutions that you can share. I'm open to alternative approaches or tools that might help me achieve the desired security for my environment variables.

Dockerfile:

FROM node:18-alpine AS base

# Install dependencies only when needed
FROM base 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

# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* ./
RUN \
    if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
    elif [ -f package-lock.json ]; then npm ci; \
    elif [ -f pnpm-lock.yaml ]; then yarn global add pnpm && pnpm i --frozen-lockfile; \
    else echo "Lockfile not found." && exit 1; \
    fi


# Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Generate Prisma Client
RUN npx prisma generate

# 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 during the build.
# ENV NEXT_TELEMETRY_DISABLED 1

# Re-install sentry cli
RUN npm install @sentry/nextjs

# If using npm comment out above and use below instead
RUN npm run build

# Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app

ENV NODE_ENV production
# Uncomment the following line in case you want to disable telemetry during runtime.
# ENV NEXT_TELEMETRY_DISABLED 1

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public

# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

# Custom entrypoint for env handling
COPY entrypoint.sh .
# If there is an .env.production, copy it 
COPY .env[.production] .

# Fix SSL issues
RUN apk add --no-cache ca-certificates openssl

# Execute script
RUN apk add --no-cache --upgrade bash
RUN ["chmod", "+x", "./entrypoint.sh"]
ENTRYPOINT ["./entrypoint.sh"]

WORKDIR /app

USER nextjs

EXPOSE 3000

ENV PORT 3000

CMD ["node", "server.js"]

2 Replies

Rampur GreyhoundOP
An example of accessing the environment variables in code, they are stuck on the values which are passed on the machine which builds the image and when new environment variables are passed (.env.production file for example) it won't adjust to the correct ones.

"use client";

import PusherClient from "pusher-js";

export const pusherClient = new PusherClient(
  process.env.NEXT_PUBLIC_PUSHER_KEY!,
  {
    wsHost: process.env.NEXT_PUBLIC_PUSHER_HOST!,
    wsPort: process.env.NEXT_PUBLIC_PUSHER_PORT! as any,
    forceTLS: false,
    disableStats: true,
    enabledTransports: ["ws", "wss"],
    cluster: process.env.NEXT_PUBLIC_PUSHER_CLUSTER!,
    userAuthentication: {
      endpoint: "/api/pusher/user/auth",
      transport: "ajax",
    },
    channelAuthorization: {
      endpoint: "/api/pusher/channel/auth",
      transport: "ajax",
    },
  },
);
American Fuzzy Lop
Did you get this working?