probablyjassin
probablyjassin

Reputation: 1

Nuxt 3 in Docker: environment variables accessible everywhere but not in nuxt.config.ts

I'm trying to move a nuxt 3 app to using docker-compose. I read in the documentation that .env files are not read by nuxt in production. So I'm trying to add them to the environment directive in my docker-compose.yml. This works for most parts of my app, like on the server. But specifically in my nuxt.config.ts where I need to specify my google client id for oauth, it does not work.

// nuxt.config.ts

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
    devtools: { enabled: false },
    ssr: true,
    modules: ["nuxt-vue3-google-signin"],
    compatibilityDate: "2024-09-04",

    googleSignIn: {
        clientId: process.env.NUXT_GOOGLE_CLIENT_ID, 
// This is not recognized in production, the app fails to initialize with the 500 error that the clientID is missing
// I also tried leaving it as empty string and using "NUXT_GOOGLE_SIGN_IN_GOOGLE_CLIENT_ID" in my docker-compose.yml under environment
// and I tried using `import "dotenv/config";` and `require("dotenv").config();` at the top of this file as suggested by a similar problem someone had
    },

    css: ["~/assets/css/main.css"],
    postcss: {
        plugins: {
            tailwindcss: {},
            autoprefixer: {},
        },
    },
});

# docker-compose.yml

services:
  my-nuxt-app:
    image: ghcr.io/me/my-nuxt-app:latest
    container_name: my-nuxt-app
    restart: unless-stopped
    ports:
      - "6000:6000"
    env_file: ".env"
    environment:
      - NUXT_GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID}

// server/api/some-endpoint.ts

export default defineEventHandler(async (event) => {
    console.log(process.env.NUXT_GOOGLE_CLIENT_ID) // this works as expected
});

Upvotes: 0

Views: 38

Answers (2)

Chris Wong
Chris Wong

Reputation: 592

Another alternative is using vue3-google-login instead:

nuxt.config.ts

export default defineNuxtConfig({
  compatibilityDate: '2024-11-01',
  devtools: { enabled: true },
  runtimeConfig: {
    public: {
      googleClientId: process.env.NUXT_PUBLIC_GOOGLE_CLIENT_ID
    }
  }
})

plugins/vue3-goolge-login.client.ts

import vue3GoogleLogin from "vue3-google-login";

export default defineNuxtPlugin((nuxtApp) => {
  const runtimeConfig = useRuntimeConfig();
  const { googleClientId: NUXT_PUBLIC_GOOGLE_CLIENT_ID } = runtimeConfig.public;

  nuxtApp.vueApp.use(vue3GoogleLogin, {
    clientId: NUXT_PUBLIC_GOOGLE_CLIENT_ID,
  });
});

app.vue

<template>
  <div>
    <ClientOnly>
      <GoogleLogin :callback="callback" />
    </ClientOnly>
  </div>
</template>

<script setup>
const callback = (response) => {
  console.log(response);
};
</script>

Upvotes: 0

Chris Wong
Chris Wong

Reputation: 592

Can try to set environment variable when build the image: Dockerfile

ARG NODE_VERSION=20.14.0

# Create build stage
FROM node:${NODE_VERSION}-slim AS build

# Set the working directory inside the container
WORKDIR /app

ARG NUXT_PUBLIC_GOOGLE_CLIENT_ID

ENV NUXT_PUBLIC_GOOGLE_CLIENT_ID=$NUXT_PUBLIC_GOOGLE_CLIENT_ID

# Copy package.json and pnpm-lock.yaml files to the working directory
COPY ./package.json /app/

# Copy the rest of the application files to the working directory
COPY . ./

RUN npm install
# Build the application
RUN npm run build

# Create a new stage for the production image
FROM node:${NODE_VERSION}-slim

# Set the working directory inside the container
WORKDIR /app

# Copy the output from the build stage to the working directory
COPY --from=build /app/.output ./

# Define environment variables
ENV HOST=0.0.0.0 NODE_ENV=production
ENV NODE_ENV=production

# Expose the port the application will run on
EXPOSE 3000

# Start the application
CMD ["node","/app/server/index.mjs"]
docker build --build-arg \
  NUXT_PUBLIC_GOOGLE_CLIENT_ID=${NUXT_PUBLIC_GOOGLE_CLIENT_ID} \
  -t my-nuxt-app .

GitHub

Upvotes: 0

Related Questions