<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jon Koops</title>
    <description>The latest articles on DEV Community by Jon Koops (@jonkoops).</description>
    <link>https://dev.to/jonkoops</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F501489%2Fc9d73581-f39e-485d-ae4d-40d2e546c936.jpeg</url>
      <title>DEV Community: Jon Koops</title>
      <link>https://dev.to/jonkoops</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jonkoops"/>
    <language>en</language>
    <item>
      <title>Building portable front-end applications with Docker</title>
      <dc:creator>Jon Koops</dc:creator>
      <pubDate>Thu, 29 Oct 2020 10:40:17 +0000</pubDate>
      <link>https://dev.to/jonkoops/building-portable-front-end-applications-with-docker-2cpm</link>
      <guid>https://dev.to/jonkoops/building-portable-front-end-applications-with-docker-2cpm</guid>
      <description>&lt;p&gt;A likely scenario you will run into in your career as a front-end developer is that you will want to have your application deployed to multiple environments. Although these environments are mostly the same your application might have to behave slightly differently in each one of them.&lt;/p&gt;

&lt;p&gt;For example, an application running on a staging environment might have to make calls to the API server running on the staging domain, or your whitelabel application might have to show a different brand based on which environment it is deployed.&lt;/p&gt;

&lt;p&gt;This is where environment variables can help out. You can provide an environment file and build your application for each environment on which your application can possibly run. This is actually a very common approach that is used by tools like &lt;a href="https://angular.io/guide/build#configuring-application-environments" rel="noopener noreferrer"&gt;Angular CLI&lt;/a&gt;, &lt;a href="https://create-react-app.dev/docs/adding-custom-environment-variables/" rel="noopener noreferrer"&gt;Create React App&lt;/a&gt; and &lt;a href="https://cli.vuejs.org/guide/mode-and-env.html#environment-variables" rel="noopener noreferrer"&gt;Vue CLI&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Although this is a great solution, it has a couple of downsides when your application continues to grow in complexity:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multiple builds&lt;/strong&gt;&lt;br&gt;
If you have set up a CI/CD pipeline, your build server will have to build your whole application for each environment. The more complex your application becomes the longer you will have to wait and waste precious resources and time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Less portable&lt;/strong&gt;&lt;br&gt;
Besides complicating your build, you will also have to deploy the end result to the correct environment. The downside of this is that the code can only run on that specific environment and nowhere else.&lt;/p&gt;

&lt;p&gt;To solve the issues mentioned above we can take a note from what our fellow developers do with applications that run on the server, which is to provide these environment variables at the moment our application boots up. This is easier said than done since we’re deploying our applications as static files, and thus we have no code running on the server itself.&lt;/p&gt;

&lt;p&gt;Since Docker has become the industry standard for shipping applications, we’ll be using it here to make a new application deployable and to provide environment variables dynamically to it. If you have no prior experience with Docker it is recommended to &lt;a href="https://docs.docker.com/get-started/" rel="noopener noreferrer"&gt;read up on this topic first&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; We’re creating a new application here but the steps outlined below can also be applied to any existing front-end application, compiled or not.&lt;/p&gt;

&lt;p&gt;Let’s start by creating a simple boilerplate for our application with an &lt;code&gt;index.html&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;My awesome application&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"main.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’re using a script element here to directly load our JavaScript. This is done to keep this tutorial as simple as possible but you can use whatever tooling you prefer, such as WebPack or the built-in CLI tools of your framework of choice to build your application.&lt;/p&gt;

&lt;p&gt;Let’s add the &lt;code&gt;main.js&lt;/code&gt; file and use it to add some content to the page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all goes well you should be seeing the 'Hello World!' message displayed in your browser when opening the &lt;code&gt;index.html&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7dyzttmylt46hqihak03.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7dyzttmylt46hqihak03.png" alt="The 'Hello World!' message displayed on the page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; You can start a simple HTTP server for local development by running &lt;code&gt;npx http-server .&lt;/code&gt; in your working directory.&lt;/p&gt;

&lt;p&gt;Now that we have our application up and running we can start putting it in a Docker image so that it can be easily shared and deployed. Let’s start off by placing the newly created files in a directory called &lt;code&gt;src&lt;/code&gt;. This is where we will keep our application code that will end up as static files in the Docker image. In case you are compiling your application, this will likely be your &lt;code&gt;dist&lt;/code&gt; or &lt;code&gt;build&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;To serve the files we’re going to need an HTTP server. Let’s create a new file called &lt;code&gt;Dockerfile&lt;/code&gt; in the root of our working directory and add the following content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; nginx:latest&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /usr/share/nginx/html/&lt;span class="k"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./src/ /usr/share/nginx/html/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we’re using the latest version of NGINX as our server, and the files that are used by NGINX to show the default splash page are removed and replaced with the contents of our own application. Now that we have a &lt;code&gt;Dockerfile&lt;/code&gt; let’s build a Docker image for our application by running the following command in the working directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;--tag&lt;/span&gt; frontend &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will build a new Docker image tagged with the label 'frontend', which we can run in combination with the docker run command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--detach&lt;/span&gt; &lt;span class="nt"&gt;--publish&lt;/span&gt; 8080:80 &lt;span class="nt"&gt;--name&lt;/span&gt; server frontend:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you run this command and navigate to &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt; you should now see the same page we saw before but now served from NGINX using Docker!&lt;/p&gt;

&lt;p&gt;To hold our default environment variables in the project we’re going to create a new file called &lt;code&gt;environment.js&lt;/code&gt; and add it to the &lt;code&gt;src&lt;/code&gt; directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaultEnvironment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;APP_TITLE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello Docker!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;defaultEnvironment&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We want to use our new &lt;code&gt;APP_TITLE&lt;/code&gt; variable and display it on our page, so let’s update &lt;code&gt;main.js&lt;/code&gt; to reflect this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./environment.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="nx"&gt;root&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;h1&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;APP_TITLE&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/h1&amp;gt;`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, now let’s see if these changes are working correctly. Stop the Docker container that is running with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;--force&lt;/span&gt; server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run the previous commands again to re-build and run the Docker container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;--tag&lt;/span&gt; frontend &lt;span class="nb"&gt;.&lt;/span&gt;
docker run &lt;span class="nt"&gt;--detach&lt;/span&gt; &lt;span class="nt"&gt;--publish&lt;/span&gt; 8080:80 &lt;span class="nt"&gt;--name&lt;/span&gt; server frontend:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If all is well we should now see our &lt;code&gt;APP_TITLE&lt;/code&gt; variable displayed as expected:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdkb83zi20yn5i1w2tjtb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdkb83zi20yn5i1w2tjtb.png" alt="The 'Hello Docker!' message displayed on the page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ok, so far so good. We have a separate file for our environment variables and our application is running in Docker. However our &lt;code&gt;APP_TITLE&lt;/code&gt; variable will always be the same no matter where we run our container. To truly make our application portable, we’ll need some way to provide the environment variables to the application when we are starting our Docker container.&lt;/p&gt;

&lt;p&gt;To do this we’re going to use another common practice in front-end frameworks when transferring state from a server-side rendered application, which is to put the state into a script element when the &lt;code&gt;index.html&lt;/code&gt; is rendered. Let’s add the following code to our &lt;code&gt;index.html&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"environment"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;$FRONTEND_ENV&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are adding a placeholder called &lt;code&gt;FRONTEND_ENV&lt;/code&gt; that we’re going to replace with some JSON data when our Docker container boots up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; It is recommended to include this script element conditionally for your production builds to prevent issues when parsing it's contents as JSON during development.&lt;/p&gt;

&lt;p&gt;Add the following lines to the end your &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ./startup.sh /app/startup.sh&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; sh /app/startup.sh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docker provides us with the &lt;code&gt;CMD&lt;/code&gt; instruction, this allows us to run a specific command the moment the container starts up. In this case we are copying the &lt;code&gt;startup.sh&lt;/code&gt; script into our Docker image and we run it directly once the container starts. Let’s take a look at what this script looks like and add it to the root of the working directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="nv"&gt;basePath&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/share/nginx/html
&lt;span class="nv"&gt;fileName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;basePath&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/index.html
envsubst &amp;lt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;fileName&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;basePath&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/index.env.html
&lt;span class="nb"&gt;mv&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;basePath&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/index.env.html &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;fileName&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
nginx &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="s1"&gt;'daemon off;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a lot going on in this file but the most important line is the one that runs the &lt;a href="https://www.gnu.org/software/gettext/manual/html_node/envsubst-Invocation.html" rel="noopener noreferrer"&gt;envsubst&lt;/a&gt; command. This utility is provided by the GNU gettext utilities, which are part of almost all Linux distributions and thus also our Docker container. It reads the contents of our &lt;code&gt;index.html&lt;/code&gt; file and replaces all text prefixed with a dollar sign (such as our &lt;code&gt;FRONTEND_ENV&lt;/code&gt;) with the equivalent environment variable provided to the Docker container.&lt;/p&gt;

&lt;p&gt;We’re almost there so let’s see if our code is working properly so far. We’ll have to build a new version of our Docker image and start it with our new environment variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;--force&lt;/span&gt; server
docker build &lt;span class="nt"&gt;--tag&lt;/span&gt; frontend &lt;span class="nb"&gt;.&lt;/span&gt;
docker run &lt;span class="nt"&gt;--publish&lt;/span&gt; 8080:80 &lt;span class="nt"&gt;--name&lt;/span&gt; server &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;FRONTEND_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'{ "APP_TITLE": "Hello Environment!" }'&lt;/span&gt; frontend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you can see that we are providing the &lt;code&gt;FRONTEND_ENV&lt;/code&gt; as JSON text to our Docker container. Now if we open up our page at &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt; and look at our source we can see the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!doctype html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"utf-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;My awesome application&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"main.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"environment"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/json"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;APP_TITLE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello Environment!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;index.html&lt;/code&gt; now has our environment variables inside as expected. This means that we now only have to build a single Docker image and we can deploy it to any environment simply by providing it with different environment variables. No need to build your application multiple times!&lt;/p&gt;

&lt;p&gt;This is great, but we still need to read this JSON data and overwrite our default environment variables so let’s add some code to &lt;code&gt;environment.js&lt;/code&gt; to do just that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;defaultEnvironment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;APP_TITLE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello Docker!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getEnvironmentVariables&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;environment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unable to parse environment variables.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;defaultEnvironment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nf"&gt;getEnvironmentVariables&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have a new function that will get our element containing the environment variables and parse its contents as JSON if it exists and contains a non-empty value. When we export our default environment, we overwrite it with the environment variables that are obtained from the &lt;code&gt;index.html&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now if we rebuild our image and start it with the same &lt;code&gt;FRONTEND_ENV&lt;/code&gt; environment variable as before, now we can see that our custom title shows up:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcgrfhmomgipe0vq6ilbv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcgrfhmomgipe0vq6ilbv.png" alt="The 'Hello Environment!' message displayed on the page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.giphy.com%2Fmedia%2F5Yl08OSg4AckeNHpDc%2Fgiphy-downsized-medium.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia1.giphy.com%2Fmedia%2F5Yl08OSg4AckeNHpDc%2Fgiphy-downsized-medium.gif" alt="A man throwing around confetti in celebration."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s it! We now have a nice and portable Docker image that we can use for our application. If you want to view the full code used in this post you can find it on &lt;a href="https://github.com/jonkoops/portable-frontend" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
