Env variables from fly.toml and github vars not available in Nuxt config (process.env)

Hi there! :smiley:

I’m new to using fly.io and I managed very smoothly to launch and deploy my Nuxt 2 application yesterday from my local machine, with only a Dockerfile (with no mentions of my env variables) and fly.toml, where I’ve set my env variables in the [env] section. Everything works perfectly! :rocket:

Today I’ve tried to implement a github workflow for deploy (and deploy review app) and now a few hours later I feel like I’m banging my head into a wall. I can’t seem to get the env variables to have it’s values that I’ve set in the fly.toml file.

I’ve tried to also set them via github env variables and secrets, and if I echo them during my build it has the correct values… Although coming in to my nuxt.config.js if I console log for example the process.env.API_ENDPOINT variable it is undefined.

From all I’ve read today it seems that setting my variables in [build.args] instead of [env] in fly.toml could be a solution, and then change my Dockerfile to set the args as env variables. How would that work with secrets then? What do I have to change in the workflow? I’m posting my code below.

If someone out there could help me shine som light on this topic it would be very much appreciated :smiling_face_with_three_hearts: I’m confused about why it would make a difference running the build and deploy via workflow when it uses the same fly.toml and Dockerfile

This is my fly-review.yml where I’ve tried to set the env variables both up and then also pass them as secrets below (for testing)

name: Fly Deploy Review App
on:
  # Run this workflow on every PR event. Existing review apps will be updated when the PR is updated.
  pull_request:
    types: [opened, reopened, synchronize, closed]

env:
  FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
  FLY_REGION: lhr
  FLY_ORG: personal
  API_KEY: ${{ secrets.API_KEY }}
  API_ENDPOINT: ${{ vars.API_ENDPOINT }}
  AUTH_ENDPOINT: ${{ vars.AUTH_ENDPOINT }}
  BASE_URL: ${{ vars.BASE_URL }}
  DEFAULT_LOCALE: ${{ vars.DEFAULT_LOCALE }}
  FALLBACK_CHANNEL_ID: ${{ vars.FALLBACK_CHANNEL_ID }}
  FALLBACK_MARKET_ALIAS: ${{ vars.FALLBACK_MARKET_ALIAS }}
  IMAGE_SERVER: ${{ vars.IMAGE_SERVER }}
  SIGN_ENDPOINT: ${{ vars.SIGN_ENDPOINT }}
  RALPH_ENV: dev

jobs:
  review_app:
    runs-on: ubuntu-latest
    outputs:
      url: ${{ steps.deploy.outputs.url }}
    # Only run one deployment at a time per PR.
    concurrency:
      group: pr-${{ github.event.number }}

    # Deploying apps with this "review" environment allows the URL for the app to be displayed in the PR UI.
    # Feel free to change the name of this environment.
    environment:
      name: review
      # The script in the `deploy` sets the URL output for each review app.
      url: ${{ steps.deploy.outputs.url }}

    steps:
      - name: Get code
        uses: actions/checkout@v4

      - name: Examine env variables
        run: env

      - name: Deploy PR app to Fly.io
        id: deploy
        uses: superfly/fly-pr-review-apps@1.2.0
        with:
          secrets: API_KEY=${{ secrets.API_KEY }} API_ENDPOINT=${{ vars.API_ENDPOINT }} AUTH_ENDPOINT=${{ vars.AUTH_ENDPOINT }} BASE_URL=${{ vars.BASE_URL }} DEFAULT_LOCALE=${{ vars.DEFAULT_LOCALE }} FALLBACK_CHANNEL_ID=${{ vars.FALLBACK_CHANNEL_ID }} FALLBACK_MARKET_ALIAS=${{ vars.FALLBACK_MARKET_ALIAS }} IMAGE_SERVER=${{ vars.IMAGE_SERVER }} SIGN_ENDPOINT=${{ vars.SIGN_ENDPOINT }} RALPH_ENV=dev

This is my fly.toml file

app = 'name'
primary_region = 'lhr'

[build]
  dockerfile = 'Dockerfile.fly'

[env]
  API_ENDPOINT = '***'
  AUTH_ENDPOINT = '***'
  BASE_URL = '***'
  DEFAULT_LOCALE = '***'
  FALLBACK_CHANNEL_ID = '***'
  FALLBACK_MARKET_ALIAS = '***'
  IMAGE_SERVER = '***'
  RALPH_ENV = '***'
  SIGN_ENDPOINT = '***'

[http_service]
  internal_port = 3000
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0
  processes = ['app']

[[vm]]
  memory = '1gb'
  cpu_kind = 'shared'
  cpus = 1

and this is my Dockerfile

# syntax = docker/dockerfile:1

ARG NODE_VERSION=16.20.0
FROM node:${NODE_VERSION}-slim as base

LABEL fly_launch_runtime="Nuxt"

# Nuxt app lives here
WORKDIR /app

# Set production environment
ENV NODE_ENV="production"

# Throw-away build stage to reduce size of final image
FROM base as build

# Install packages needed to build node modules
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python

# Install node modules
COPY --link .npmrc package-lock.json package.json ./
RUN npm ci --include=dev

# Copy application code
COPY --link . .

RUN npm install -g node-prune

# Build application
RUN npm run build \
    && node-prune \
    && mkdir output \
    && cp -r package.json nuxt.config.js node_modules .nuxt static scripts config output

# Remove development dependencies
RUN npm prune --omit=dev

# Final stage for app image
FROM base

# Copy built application
COPY --from=build ./app/output ./

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
ENV HOST=0
ENV NUXT_HOST=0.0.0.0
CMD ["npm", "run", "start"]

Hi O11an

Sorry about the slow reply, I think you’re onto it with the build args. I the part which is confusing to me is how you built the image locally without the required args.

How were you building/deploying locally fly deploy? Is it possibly the env vars were passed in to the build from you local environment somehow?

Locally I just used the fly.toml and Dockerfile from above and used fly launch and then fly deploy and it was enough to have the env-variables in the [env] section for them to be available in process.env when building the nuxt.config. Super easy and smooth.

For it to work with both local and github workflow deployments now though I changed [env] to [build.args] and added this to my Dockerfile:

# Arguments
ARG API_KEY
ARG API_ENDPOINT
ARG IMAGE_SERVER
ARG AUTH_ENDPOINT
ARG SIGN_ENDPOINT
ARG BASE_URL
ARG FALLBACK_CHANNEL_ID
ARG FALLBACK_MARKET_ALIAS
ARG DOMAINS
ARG DEFAULT_LOCALE
ARG RALPH_ENV

# Set environment variables
ENV API_KEY=${API_KEY}
ENV API_ENDPOINT=${API_ENDPOINT}
ENV IMAGE_SERVER=${IMAGE_SERVER}
ENV AUTH_ENDPOINT=${AUTH_ENDPOINT}
ENV SIGN_ENDPOINT=${SIGN_ENDPOINT}
ENV BASE_URL=${BASE_URL}
ENV FALLBACK_CHANNEL_ID=${FALLBACK_CHANNEL_ID}
ENV FALLBACK_MARKET_ALIAS=${FALLBACK_MARKET_ALIAS}
ENV DOMAINS=${DOMAINS}
ENV DEFAULT_LOCALE=${DEFAULT_LOCALE}
ENV RALPH_ENV=${RALPH_ENV}

A little bit more code, but now it works with both fly deploy and with my GitHub action workflow, without declaring any of my env variables in the workflow files.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.