DEV Community

Cover image for You probably don't need dotenv
Amin
Amin

Posted on

You probably don't need dotenv

If you are a Docker Compose user, then this article is for you. You probably know it already, but Docker Compose is actually able to read your .env file and expose these variables to your services.

Today I'm going to show you how to use Docker Compose to expose environment variables through your Node.js script.

1. Create a new project

$ mkdir project
$ cd project
Enter fullscreen mode Exit fullscreen mode

I'm going to use GNU/Linux commands in this article. Unfortunately, I won't cover Windows due to my lack of knowledge about Powershell commands, but you'll find equivalent commands on the internet for sure.

2. Environment

$ vim .env
Enter fullscreen mode Exit fullscreen mode

And here is the content of our environment file.

APP_ENV=local
Enter fullscreen mode Exit fullscreen mode

I'm using vim here as my text editor of choice. Replace vim as your favorite text editor's command-line program.

3. Docker Compose configuration

$ vim docker-compose.yaml
Enter fullscreen mode Exit fullscreen mode

And here is the configuration.

version: "3"

services:
  node:
    image: node
    user: node
    working_dir: /home/node
    entrypoint: node
    env_file:
      - .env
    volumes:
      - .:/home/node
Enter fullscreen mode Exit fullscreen mode

5. Node script

$ vim main.mjs
Enter fullscreen mode Exit fullscreen mode

And here is the script.

import { platform } from "os";

const env = process.env.APP_ENV || "notfound";

console.log(`[${env}] platform is ${platform()}`);
Enter fullscreen mode Exit fullscreen mode

6. Run

$ docker-compose run --rm node main.mjs
[local] platform is linux
Enter fullscreen mode Exit fullscreen mode

Conclusions

Voilà! We have accessed our APP_ENV variable which had the local value and we didn't install dotenv for that matter.

Unfortunately, this solution comes with some drawbacks.

This solution does require you to use Docker Compose. Docker alone also supports dynamic environment file handling by the way. And if you don't use Docker, this solution won't work. But fear not! There are some alternative ways (if you are using a UNIX shell).

You may have been dependent on DotEnv, there is no shame in that, I have been too, even after using Docker Compose. The project in itself has nothing wrong, and it has some more features like runtime environment parsing (which is situational but can be really helpful if you are building dynamic environment variables).

But this also comes with some advantages.

Having one less dependency is always appreciated. This speeds up installing your project on a new machine. Not the speed gain of the year of course, but still.

It can be super quick to prototype a project leveraging environment variables using these simple steps. Not having to download a library for that matter also means that you can work offline, which is appreciated.

This works with any programming languages that support process environment variables! This means that sharing environments variables with your PHP ($_ENV), Ruby (ENV["..."]), or even C++ (getEnv("...")) services becomes trivial!

Feedback

I am now using this technique over all of my recent projects, whether it is back-end or front-end projects. You can even use Webpack or Rollup to do this. Webpack has a plugin called webpack.DefinePlugin which helps you replace environment variables for your client scripts. The same thing goes for Rollup with @rollup/plugin-replace.

Do you have any more advantages/drawbacks to submit? I'll be happy to add them to this article!

And if you want to know more, here is the official Docker Compose reference for the env_file option.

Top comments (4)

Collapse
 
patarapolw profile image
Pacharapol Withayasakpunt

But, should I use Docker in development?

  • Vue CLI == Webpack dev server + proxy, which can already read .env by default, anyway
  • Node.js web server (Fastify). Cannot read .env by default.
Collapse
 
aminnairi profile image
Amin

If you are using Vue CLI on Windows and I am using it on Linux, we might come into issues with the underlying Node.js version we are using. This can cause mismatch behaviors in the way Node.js is handling things under the hood like file watching for instance (which is the common culprit among users of different operating system working together).

However, if you are working alone, you don't need Docker. Still, I continue using it even on my side-projects and my libraries because it is so much relieving not to worry about the version of Node.js that is installed on my operating system at the current moment and the Node.js version I used to develop my library at that specific time. If I really need to keep an outdated version of Node.js because I'm using a library that forced me to not upgrade Node.js, I can easily do that and keep working on my library for years. And I can upgrade the Node.js version simply by updating a file.

Infrastructure-as-code has many more advantages but I can't list them in a single comment, if you want me to write an article about it I'll be gladly off doing that and share opinions with you as well!

Collapse
 
mgce profile image
Mateusz Gajda

If you are writting client side, than you don't need docker. But if you are writting server side and use some external services, than you should think about a docker. It gives you an abiliity to connect to external services by hostname, and thanks to that you can emulate production environment on your local computer. What is more docker and docker-compose is powerfull tool which can gives you a lot of benefits if know hot to use it correct.

Collapse
 
aminnairi profile image
Amin • Edited

Hi Pacharapol, thanks for your answer.

I guess, from the context you provided, that you already have the necessary tools to deal with your environment just fine. Adding Docker on top of all that would be overkill in my opinion. Don't you think?