#Docker with `import.meta.env`

1 messages · Page 1 of 1 (latest)

hidden briar
#

I have a vite project that works great locally but fails when deploying with Docker - and I know why but I don't know what to do about it.

Certain secrets (oauth) are defined in .env and referenced in code with import.meta.env. Running locally it reads .env no problem. Even building into a container works fine, except those secrets are baked into the container, which isn't great.

The vite documentation clearly explains that those values are baked in at build time.

I'd like to understand from the community what the general best practices are with import.meta.env. If I read it as "env vars at build time" then it fits into place. But I'd mistakenly thought it would "use build time after reading current env", which it absolutely does not do.

This article clearly explains one way to work around it, but that only worked for the SSR parts for me, not the client - can't figure out why.

I think the solution is to take this view, but I would love your input:

  • Use import.meta.env for values from .env at compile and build time
  • If you want to read the local env first, then do that in code, then fall back to import.meta.env.

Thoughts?

#1019670660856942652 #deploy #docker

vitejs

Next Generation Frontend Tooling

DEV Community

Introduction 1. The Problem with Vite and Environment Variables 2. The Concept: Build Once, Inject...

delicate island
#

Don't know if I agree with that article tbh

#

Why not just build for each environment, that'd be the pragmatic hack imo. This way you use docker to contain your whole app, including the secrets (that you already seem to have set-up) and so when you run npm run build inside the container it'd work. There's also something called multi-stage containers where you first make a container to build it and then use the output of the container to create a new one. Lastly, if you feel a single build should work across all containers, then you could look into avoiding import.meta.env since you'd be working against it since you've learned that it hardcodes those

hidden briar
#

thanks @delicate island
I think I'm still trying to get the 'zen' of the import.meta.env because I probably haven't been understanding it how it is intended.

Overall I am coming around to the way it works, but ... well, one thing that is hard to escape is that my organisation will flip out at the idea of any secrets embedded in a build, even if they are exposed to the public later. There is something to be said for placeholders in the container, replaced at container run startup with values from the host environment.

Pros and cons.

Anyone got real world insights and hard won lessons?

delicate island
#

the 'zen' of import meta is precisely that it can not change, and thus you are not exposing other secrets that might be in your environment "object". During development it just puts vite_import_meta at the top of the module and during build it replaces it in the code in a smart way. If you are only using client-side secrets (api keys, public keys) then those will be send over the wire so I'm not sure why you would be afraid of storing it in the build. If there are server secrets then you should double check your production client-side build to not contain those secrets, if so should change them immediately. If the code containing the secrets only runs on the server, then it's not a immediate concern BUT IF your image leaks all your secrets are in the code so you've to ask yourself why you did that? just use like whatever secret manager you use (docker secrets in your case has a node api https://daten-und-bass.io/blog/using-docker-secrets-with-nodejs/) or use process.env