Angular in production using Docker

Preparing an Angular App for Production in Docker (Part 10)

In this article, you’ll learn how to prepare an Angular app for production deployment using Docker.

This post is part of the Dockerized Django Back-end API with Angular Front-end Tutorial. Check out all the parts of the tutorial there.

In the last part of the tutorial, we’ve learned how to prepare a Django DRF API for production in Docker. In this blog post, we’ll learn how to prepare our Angular app for deployment in a production environment using Docker.

To get the code to where we left off in the last blog post, use:

$ git checkout v1.15

Environment Files and Variables in Angular

First of all, I want to talk (OK, write) a bit about the idea of environments. When developing an app, you should have a minimum of two environments, such as one for development and one for production.

The Angular CLI supports the concept of environments.

When you create a new app, you’ll find under the src directory an environments directory. By default, two environment files are created:

  • environment.ts – used for development (within it, the production variable is set to false)
  • environment.prod.ts – used for production (within it, the production variable is set to true)

Now, do you remember how our Angular app accesses the Django API? It’s using the ApiService service found in angular/angular-app/src/api.service.ts.

In this file, we store the API URL that’s served by the Django back-end:

API_URL = 'http://localhost/api';

For development, this URL is fine, but in a production setting we need to point the URL to a domain name or IP address instead of localhost.

Therefore, let’s add a new apiUrl variable in our environment files to specify the API URL for our development and production cases, respectively.

Edit src/environments/environment.ts and add the apiUrl variable as follows:

Next, do the same for the production environment file src/environments/environment.prod.ts, but also add the auth variable:

Here you should replace <YOUR-DOMAIN-OR-IP-ADDRESS> with the corresponding location where you’ll host the API. I will replace this with the IP address of the Google Cloud Platform instance on which we’ll deploy our stack in a future post.

Using Environment Variables in Angular

Next, we’ll see how we can use the apiUrl variable in our Angular code.

Edit the angular-app/src/api.service.ts file as follows:

Wherever we want to use environment variables, we import the environment file in our code. The Angular CLI will know how to select the correct environment file when we build the app.

Building the Angular App in a Production Configuration

We’re now ready to actually build the Angular app for deployment.

To do this, you can simply build the app with the production configuration:

$ ng build --prod

The production flag --prod has a few important functions such as merging your application files in a few bundles, removing comments and excess whitespace, and rewriting the code to use short, cryptic variable and function names.

Also, the production flag will tell Angular to use the production environment file, so API_URL will resolve to http://<YOUR-DOMAIN-OR-IP-ADDRESS>/api when building with --prod.

Building the Angular app in Docker

We don’t really want to just use ng build --prod blindly as we’re not keeping track of the build environment in which we’re setting up the app.

To make sure that build environments are reproducible, we want to use Docker.

Let’s go to our angular/Dockerfile file we’ve created way back in part 3 of the tutorial and change the build step as follows:

Here, we’re using configuration as a build-time variable using the ARG instruction.

As you can see, configuration is set to production by default.

Next, we pass the configuration variable to our npm run build command. This will build the app using the provided configuration.

The nice thing about ARG variables is that you can pass different values when you’re building the Docker image from the command-line using the --build-arg option like so:

$ docker build --build-arg some_variable_name=the_given_value

Therefore, if you want to build the app in the production configuration, you’d use:

docker build --build-arg configuration=production

If you want to build the app in the development configuration, you can just pass an empty value like so:

docker build --build-arg configuration=""

Lastly, you can also supply these variables using docker-compose.

Copying the Angular Files Locally

Now that we can build the Angular app in the Docker container, let’s also copy the built files from the container to our local filesystem.

To do this, we can use the command docker cp that has the following format:

docker cp <containerId>:/file/path/within/container /host/path/target

If you now start the containers using docker-compose up, you can copy the Angular files locally using something like:

$ docker cp ng:/usr/share/nginx/html/. /Users/dragos/static_angular

Here, we’re getting the files from the ng container, namely from NGINX’s HTML directory where the app files are found, and we’re copying them to a directory on the host, in the above example to /Users/dragos/static_angular.

The next step would be to upload these files to a server.

In a later blog post we’ll see how we can serve these files from a Google Cloud Storage bucket.

Bonus: Adding a Staging Environment

I thought it would be useful to also include information on how to add a staging environment.

To include a new environment, open the angular-app/angular.json file. In the configurations key, you can see the default production configuration.

Now, you can just replicate the production configuration with a new configuration such as one named staging:

Next, in the environments directory, create a environment.staging.ts file with the contents similar to environment.prod.ts:

Lastly, to build the app using the staging configuration just use:

$ ng build --configuration=staging

And that’s it!

To get the code to this stage, see my git commit or use:

$ git checkout v1.16

Just so you know, I haven’t included the extra staging configuration in the repository, so follow the steps above if you want that configuration.

Summary

In this part of the tutorial, we’ve learned how to prepare an Angular app for deployment in a production environment using Docker. We’ve covered the Angular CLI’s environment files and we’ve seen how to build the app for production in a reproducible manner using Docker.

In the next part of the tutorial, we’ll start working on deploying our Docker container on Google Cloud Platform.

Credit: For this tutorial, I’ve used the following resources:

About the Author Dragos Stanciu

follow me on:

Subscribe

Like this article? Stay updated by subscribing to my weekly newsletter:

Leave a Comment: