#.env file in docker dont working

88 messages · Page 1 of 1 (latest)

gray flame
#

I'm having an issue with the apis in my docker and apis. in my confg i have
adapter: node({
mode: "standalone",
output: "server",

I have the .env file in the docker compose files. for example im using umami for analytics in a file called umami.astro. i've added this to the main layout. i also have a livechat with using the same approach


const UMAMI_ANALYTICS_KEY = import.meta.env.UMAMI_ANALYTICS_KEY;
const PUBLIC_UMAMI_URL = import.meta.env.PUBLIC_UMAMI_URL;

<script type="text/partytown" src={PUBLIC_UMAMI_URL} data-website-id={UMAMI_ANALYTICS_KEY}></script>


const PUBLIC_TIDIO_KEY = import.meta.env.PUBLIC_TIDIO_KEY;

<script src="//code.tidio.co/{PUBLIC_TIDIO_KEY}.js" async></script>

Then i have both google autofill for addresses and web3forms for forms

const { GOOGLE_AUTOFILL, WEB_3_FORMS_ACCESS_KEY } = import.meta.env;

<form
action="https://api.web3forms.com/submit"
method="POST"
id="form"
class="needs-validation"
data-astro-reload
novalidate>

<input type="hidden" name="access_key" value={import.meta.env.WEB_3_FORMS_ACCESS_KEY} />

I've tried everything to get this to work and it shows in the docker image that those variables have been added but nothing is working...

cerulean cliff
#

is the .env file available at build-time?

#

for context, neither astro not node automatically read .env files at runtime

gray flame
#

Base stage for shared environment setup

FROM node:lts-slim as base

Set the working directory

WORKDIR /app

RUN mkdir -p /app/src

Install essential tools

RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

COPY package.json package-lock.json ./

Install dependencies, then remove unnecessary packages to keep the image slim

FROM base as dependencies
RUN npm install && npm cache clean --force
RUN npx <@&1055234544183287879>/upgrade

Dependencies installation for production

FROM base AS prod-deps
RUN npm install --production

Building the application

FROM base AS build
COPY . .
RUN npm install
RUN npm run build

Final stage for the production environment

FROM node:lts-slim as runtime
WORKDIR /app

Copy production dependencies

COPY --from=prod-deps /app/node_modules ./node_modules

Copy built files necessary for running the application

COPY --from=build /app/dist ./dist

Copy the config.yaml file to the expected location within the Docker image

COPY src/config.yaml /app/src/config.yaml

Set environment variables for the host and port, if necessary

ENV HOST=0.0.0.0
ENV PORT=4321

Expose the port the app runs on

EXPOSE 4321

Command to run the application

CMD ["node", "./dist/server/entry.mjs"]

#

I dont think so?

cerulean cliff
#

the only treatment files named .env is where all occurrences of import.meta.env.X are replaced in the compiled code with the value of X in that file

#

so you would have to make sure that it is abailable to astro at compile-time

gray flame
#

how do i do this

#

im sorry im so confused about the whole process

#

im new to astro

#

i spent the better half of two weeks developing the site and now this is the final issue haha

cerulean cliff
#

how are copying the .env file into the docker image now?

gray flame
#

i use docker compose

#

version: '3.8'

services:
web:
restart: always
container_name: web
image: ghcr.io/devkolt/epw-web:latest
ports:
- "4321:4321"
env_file:
- .env
labels:
- com.centurylinklabs.watchtower.enable=true
networks:
- cloudflared_tunnel

networks:
cloudflared_tunnel:
external: true

cerulean cliff
#

at what stage (prod-deps, build, final) is it copied in?

gray flame
#

final

cerulean cliff
#

it would have to be build

gray flame
#

build

#

but then it would be in the docker image?

#

i thought this was during the docker compose stage

cerulean cliff
#

yes, if you want the variables to be read from the file at runtime and only during runtime, you will use node's --env-file flag

#

and refer to the variable using process.env instead of import.met.env

gray flame
#

oh

#

so ill i do is switch the import.met.env to process.env and keep everything else the same

cerulean cliff
#

code-wise, yes

#

build-script-wise, you also add the flag to node cli i mentioned earlier

gray flame
#

in the dockerfile?

cerulean cliff
#

.env files are not read by node by default

cerulean cliff
gray flame
#

just after this? ENV HOST=0.0.0.0
ENV PORT=4321

cerulean cliff
#

no, a couple of lines after it, inside the CMD line

gray flame
#

do i need to flag the actual .env with api values or create an example

cerulean cliff
gray flame
#

kk

#

thx!!

cerulean cliff
#

good luck!

gray flame
#

import path from "path";
import { fileURLToPath } from "url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));

/** */
export const getProjectRootDir = (): string => {
const mode = import.meta.env.MODE;

return mode === "production"
? path.join(__dirname, "../")
: path.join(__dirname, "../../");
};

const __srcFolder = path.join(getProjectRootDir(), "/src");

/** */
export const getRelativeUrlByFilePath = (filepath: string): string => {
return filepath.replace(__srcFolder, "");
};
do i need to add or change the import.meta.env from this file directories.ts to process.env

#

and should i be installing dotenv

cerulean cliff
gray flame
#

okay

cerulean cliff
#

if you have a recent version of node, dotenv is no longer necessary

gray flame
#

okay okay

#

so for the docker file i changed it to # Set environment variables for the host and port, if necessary
ENV HOST=0.0.0.0
ENV PORT=4321

Expose the port the app runs on

EXPOSE 4321

Command to run the application

CMD ["node", "--env-file=.env", "app.js"]

FROM

#

Expose the port the app runs on

EXPOSE 4321

Command to run the application

CMD ["node", "./dist/server/entry.mjs"]

#

And i changed the files to ---
const UMAMI_ANALYTICS_KEY = process.env.UMAMI_ANALYTICS_KEY;
const PUBLIC_UMAMI_URL = process.env.PUBLIC_UMAMI_URL;

<script type="text/partytown" src={PUBLIC_UMAMI_URL} data-website-id={UMAMI_ANALYTICS_KEY}></script>

cerulean cliff
gray flame
#

?

#

im so confused sorry

cerulean cliff
#

you pasted two dockerfiles

#

one that runs app.js

#

another that runs dist server entry.mjs (astro's compiled code)

#

you had the flag in the first dockerfile but not in the second

#

im guessing you would need the variables from .env file in both, not just the first

gray flame
#

this is the current one

#

Base stage for shared environment setup

FROM node:lts-slim as base

Set the working directory

WORKDIR /app

RUN mkdir -p /app/src

Install essential tools

RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

COPY package.json package-lock.json ./

Install dependencies, then remove unnecessary packages to keep the image slim

FROM base as dependencies
RUN npm install && npm cache clean --force
RUN npx <@&1055234544183287879>/upgrade

Dependencies installation for production

FROM base AS prod-deps
RUN npm install --production

Building the application

FROM base AS build
COPY . .
RUN npm install
RUN npm run build

Final stage for the production environment

FROM node:lts-slim as runtime
WORKDIR /app

Copy production dependencies

COPY --from=prod-deps /app/node_modules ./node_modules

Copy built files necessary for running the application

COPY --from=build /app/dist ./dist

Copy the config.yaml file to the expected location within the Docker image

COPY src/config.yaml /app/src/config.yaml

Set environment variables for the host and port, if necessary

ENV HOST=0.0.0.0
ENV PORT=4321

Expose the port the app runs on

EXPOSE 4321

Command to run the application

CMD ["node", "--env-file=.env", "./dist/server/entry.mjs"]

#

i changed it to entry.mjs because it was not working in docker-compose after

#

docker is saying docker run --env-file .env.production -p 4321:4321 web:latest
node: .env: not found

cerulean cliff
#

that means the env file (wherever it was) was not copied into the container

#

or maybe copied into a differnet folder

gray flame
#

if i copy it to the container does that not mean the file could be compromised?

#

do i need to add something to this line # Copy built files necessary for running the application
COPY --from=build /app/dist ./dist

cerulean cliff
#

because no matter how much you lock down the env file, ultimatelet it goes onto process.env and if theres a vulnerability process.env could itself become accessible

gray flame
#

Do you know what needs to change specifically in the dockerfile because i asked gpt and its not going me a correct answer

cerulean cliff
#

the typical way it is handled is by not putting it in the part of image

#

but by putting it inside the container everytime it is started

gray flame
#

right, so usually i have it in the same directory as the docker compose file

cerulean cliff
#

that could be done through a virtual mount (docker cli's -v flag) for example

gray flame
#

but again its not reading the files correctly

#

So i've changed the dockerfile now but its not building correct

cerulean cliff
#

i cant say about how it would be done docker compose, i havent used it

gray flame
#

Okay

#

i'll try a few things

echo wasp
#

Hi everybody ! Let me ask, does anyone know clearly about the partytown issue to optimize GTM loading?
But https://tagmanager.google.com/ preview mode cannot track datalayer

coral eagle
#

This should be more documented... I'm also new to Astro and having the same issues with Docker and ENV variables. I managed to deploy the Astro with docker and Kamal, but the ENV variables are missing...

#

docker run --detach --restart unless-stopped --name docker_image --hostname 10.x.x.x-f9658aad28a4 -e --env-file .env
The docker file runs with the --env-file

blazing zephyr
#

I think the --env-file flag is only available in Node 20+ right? Is there an alternative method when one is stuck on v18?
Also, how would this work exactly when running Astro in dev mode (npm run dev)?

blazing zephyr
coral eagle
#

The ENV variables worked fine in development but still I'm still struggling to make them available during the build process. If I run printenv in the docker container, I can see the ENV variables are pushed inside the container.

#

I added these inside the Dockerfile

ENV API_KEY=$(cat /run/secrets/API_KEY) <----
ENV PASS=$(cat /run/secrets/PASS) <----
ENV HOST=0.0.0.0
ENV PORT=3000

EXPOSE 3000
CMD ["node", "$API_KEY", "$PASS", "./dist/server/entry.mjs"]

However, I'm getting this error:

ERROR: failed to solve: Syntax error - can't find = in "/run/secrets/API_KEY)". Must be of the form: name=value
coral eagle
#

That didn't worked so I'm trying this...

RUN --mount=type=secret,id=API_KEY \
  API_KEY=$(cat /run/secrets/API_KEY)

RUN --mount=type=secret,id=PASS \
  PASS=$(cat /run/secrets/PASS)

ENV HOST=0.0.0.0
ENV PORT=3000

EXPOSE 3000
CMD ["node", "API_KEY=$API_KEY", "PASS=$PASS", "./dist/server/entry.mjs"]
Running docker buildx build --push --platform linux/amd64,linux/arm64 --builder 
  kamal-astro-multiarch -t registry.redacted.com/redacted/astro:redacted -t 
  registry.redacted.com/redacted/astro:latest 
  --label service="astro" --secret id="API_KEY" --secret id="PASS" --file Dockerfile . as user@localhost

#

The container is unhealthy with these settings... but the build was sucessfull

#

This worked. The secrets are pushed at build with docker secrets:
https://docs.docker.com/build/building/secrets/

FROM node:lts-alpine AS base
WORKDIR /app

# By copying only the package.json and package-lock.json here, we ensure that the following `-deps` steps are independent of the source code.
# Therefore, the `-deps` steps will be skipped if only the source code changes.
COPY package.json yarn.lock ./

RUN apk add --no-cache curl

FROM base AS prod-deps
RUN npm install --omit=dev

FROM base AS build-deps
RUN npm install

FROM build-deps AS build
COPY . .
RUN npm run build

FROM base AS runtime
COPY --from=prod-deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist

RUN --mount=type=secret,id=API_KEY \
  API_KEY=$(cat /run/secrets/API_KEY)

RUN --mount=type=secret,id=PASS \
  PASS=$(cat /run/secrets/PASS)

ENV HOST=0.0.0.0
ENV PORT=3000

EXPOSE 3000
CMD API_KEY=$API_KEY PASS=$PASS node ./dist/server/entry.mjs
coral eagle
#

pages/contact.astro

 const email = new Email({
      apiKey: process.env.API_KEY || import.meta.env.API_KEY,
      apiSecret:  process.env.PASS || import.meta.env.PASS,
 });
#

Everything works now... 🙂

turbid wagon