Docker build passed env value displaying as undefined in Chrome

Good day, I use the following to build and deploy my container:

docker build . -t image --build-arg APP_VERSION="0.0.1.beta"
docker run -p 80:3000 image

When I connect to http://localhost, I see an undefined where that MY_APP_VERSION value should go in my file app.js. I use Vite to build the Vue app and have the envPrefix set as: MY_
Any ideas or tips would greatly appreciated, thanks!

Dockerfile:

FROM ubuntu:22.04
ARG NODE_ENV=production
ENV NODE_ENV $NODE_ENV

ARG APP_VERSION
ENV MY_APP_VERSION=$APP_VERSION

WORKDIR /app/client/

COPY ./client/package.json ./client/package-lock.json .
RUN npm ci

WORKDIR /app/server/

COPY ./server/package.json ./server/package-lock.json .
RUN npm ci

COPY . /app/

EXPOSE 3000

CMD ["npm", "run", "start"]

index.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <link rel="icon" href="/favIcon.ico" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title></title>
    </head>
    <body>
        <div id="app"></div>
        <script type="module" src="app.js"></script>
    </body>
</html>

app.js:

document.title = import.meta.env.MY_APP_VERSION

I don’t know vue.js, but can you see the value from bash?

docker exec -it containername sh -c 'env | grep MY_APP_VERSION'

Of course, you could just “echo” the variable, but the above command can avoid accidentally interpreting the variable on the host and therefore showing you nothing.

If the output is empty, make sure you use the build command with the correct parameters

Thanks for the quick reply and I can see the value just fine. That’s the weird thing, the docker container, when I open a terminal in it shows the ENV as being set. How to use it now is the question.

If you can see the variable set in the container, then it is probably a vue.js or nodejs question and I can’t help you with that, because I don’t use them.

On the other hand, you can still try something to make sure this is not a Docker issue. Run an interactive container and run npm manually inside that container. Than open the app from the browser. If it works, then the problem could be the CMD instruction, but I don’t see any problem with that now.

docker run --rm -it IMAGENAME sh

Then run

npm run start

An other idea is to delete the definition of the ARG and the ENV from the Dockerfile:

ARG APP_VERSION
ENV MY_APP_VERSION=$APP_VERSION

and manually write it back. Sometimes an invisible character is accidentally written in the file (wrong copy paste, hotkeys) and you don’t see that the variable is not what you wanted so you can’t access it. If you can list all the variables in the application, you can rule that out.

Thanks for the quick reply. I’ve been busy reading the docs and trying things out and found a solution that works but it seems backwards. Here’s what I did to not get that undefined value:

  • Added key pair of MY_APP_VERSION="0.0.1.beta" to the .env, file and ran npm run build in VS Code.
  • Built image and started container and accessed the app at http://localhost

Here’s the weird thing, I tried the above solution using the Dockerfile and using commands and it doesn’t work. Here’s how I tried that:

  • Added key pair of MY_APP_VERSION="0.0.1.beta" to .env with Dockerfile command RUN echo -e '\nMY_APP_VERSION="0.0.1.beta"\n' >> /app/client/.env. Built the image, ran the container and accessed http://localhost. Got the dreaded undefined.

So my question is, since I can add key pairs to the .env file and run the npm builder and do the docker magic to get it running, is that possible to imitate in a Dockerfile?

Current Dockerfile:

FROM ubuntu:22.04
ARG NODE_ENV=production
ENV NODE_ENV $NODE_ENV

ARG APP_VERSION
ENV MY_APP_VERSION=$APP_VERSION

WORKDIR /app/client/
COPY ./client/package.json ./client/package-lock.json .
RUN npm ci

WORKDIR /app/server/
COPY ./server/package.json ./server/package-lock.json .
RUN npm ci
RUN echo -e '\nMY_APP_VERSION="$APP_VERSION"\n' >> /app/client/.env
/* Tried to set a hard value of MY_APP_VERSION="$0.0.1.beta" as well and it was undefined*/

COPY . /app/
EXPOSE 3000
CMD ["npm", "run", "start"]

Appreciate all the help so far btw, rounds on me at the next conference meetup :slight_smile:

Is that .env file used by nodejs? We are back to the fact that I don’t know nodejs enough, but the build-arg should work. Thet argument only available during the build, but you set it as an environment variable, so the value of MY_APP_VERSION should not be empty. If npm run build means you run docker build with it, try it with only the docker command from the terminal without npm. The only case when I don’t have value in MY_APP_VERSION in my test Dockerfile is when I don’t set --build-arg

FROM ubuntu:22.04

ARG APP_VERSION
ENV MY_APP_VERSION=$APP_VERSION
docker build . --build-arg APP_VERSION=1.1 -t localhost/test
docker run --rm -it localhost/test bash -c 'env | grep MY_APP_VERSION'
MY_APP_VERSION=1.1

Yeah I get the same result, Docker has that env variable when running but it’s undefined in my import.meta.env.MY_APP_VERSION

Appreciate all the help so far btw, thank you! I’ll keep at it and see what I find out

Oh… sorry. I completely forgot about that. Then yes, if nodejs uses that .env file, you can try to generate one. But if you can share a small package.json that I can use to reproduce the issue where a nodejs app only prints variables, I can try that.