Your Angular apps as Docker containers
In this article, I will show you how to create a Docker image from your Angular application, publish and consume it from the Docker Hub.
EDIT: You can find updated version of this article on my new blog here: https://denys.dev/2018-03-02/your-angular-apps-as-docker-containers/
Creating new Angular application
Creating a Docker image from your Angular application is easy.
You can use images for internal purposes, for example, testing on different machines, operating systems and browsers.
You can also use Docker images for external use. It becomes possible to try your application without installing node.js, running
npm install to “download entire internet”, or avoid troubleshooting environment setup.
Before we start, let’s generate a new application using the following Angular CLI command:
ng new my-angular-app
Try running the application to ensure it compiles correctly and displays in the browser:
ng serve --open
By default, the browser should open with the “http://localhost:4200" address. Note the port 4200; later in the article, we are going to use port 3000 to ensure we are running from the Docker container and not the local folder.
Creating a Docker Image
Now as we got the base application up and running, let’s create a new Dockerfile to build an image.
In this article, I am going to use Nginx to serve the compiled application. To get a minimal output let’s take the “alpine” version:
As you can see from the example above, we are going to copy the “dist” folder inside the image, together with the
nginx.conf configuration file.
A straightforward configuration implementation can look like in the next example:
Next, we need to get the “dist” folder, containing the compiled application. It can be either development or production build. Let’s create the optimised production one:
ng build --prod
Never try to run
npm install or
yarn install inside the image. When it comes to scaling and creating multiple containers, the last thing you want is hundreds of images downloading lots of data at startup. You should always aim to serve the final production builds inside your Docker images.
Now, let’s build the image and call it
docker image build -t my-angular-app .
The Docker should produce an output similar to the following one but with different hash codes:
Sending build context to Docker daemon 313.8MB
Step 1/4 : FROM nginx:alpine
Step 2/4 : COPY nginx.conf /etc/nginx/nginx.conf
---> Using cache
Step 3/4 : WORKDIR /usr/share/nginx/html
---> Using cache
Step 4/4 : COPY dist/ .
Successfully built b24c9dfec8a7
Successfully tagged my-angular-app:latest
The process should be relatively fast. Once it is complete, feel free to test the image is there, by running the next command:
docker image ls
You should see a list of available images, including the “my-angular-app” one with the tag “latest” and about 18 MB size.
It is now time to test the image. Run the command below to create a container and map it to the port 3000:
docker run -p 3000:80 --rm my-angular-app
If you now navigate to the “http://localhost:3000", you should get your initial Angular application up and running there. Moreover, the Nginx logs are redirected to your console output, so that you can see what’s happening inside the container:
That is all you need to build an image on your local machine! Let’s now proceed to provide support for multi-container Docker setup.
At some point, you will most probably end up with multiple containers each serving a particular need, for example, a separate backend server, a database server and so forth.
Here’s a simple
docker-compose.yml file you can prepare as a template for your Angular application:
build entry provided for development purposes. That means we are always going to build the local image if it is not available. You can remove this line later on once you start publishing images to Docker Hub.
Now use the next command to build the image and run it in a container:
As before, navigate to “http://localhost:3000" to ensure the application runs as expected.
Once you are done playing with the application, you can clean up everything using the next command:
If you want to remove everything, including the image created earlier, use the following command:
docker-compose down --rmi all
Next time when you run the
docker-compose up command, you may see the following message:
WARNING: Image for service app was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
That is a proof that Docker tool automatically builds a new image if it is not available.
Now, let’s try to publish our image to Docker Hub so that other users can use it.
Publishing to Docker Hub
You should have a Docker Hub account to publish images. The account is free, and you can create it here: https://hub.docker.com/
Once you have an account, run the login command in the terminal app and fill the username and password to be able publishing images:
Publishing your image is easy. Just run the following command in the root folder of your project, and replace the
account value with your Docker Hub username.
docker image build -t account/my-angular-app:1.0 .
That creates a new image, ready to be deployed for your account. Use the next command to publish it, and don’t forget to use your Docker Hub username instead of the
docker push account/my-angular-app:1.0
The process should be high-speed, and in a few seconds, your image is going to be public and available for use.
Running from Docker Hub
Now, as you project is published, you or any other person can run it locally by utilising the following command:
docker run -p 3000:80 account/my-angular-app:1.0
To quickly test the container and automatically clean everything up once it got stopped, you can add the
docker run -p 3000:80 --rm account/my-angular-app:1.0
Finally, to use the
docker-compose.yml file with your published image, just remove the “build” option and point the image value to the published version:
Running your Angular applications with Docker containers can significantly reduce your development and testing efforts, especially if you intend frequently sharing your application either internally or with external users.
One of the most excellent benefits is that people who test or use your application do not need to use development tools to compile your project from the source code or configure a web server to run the compiled output. Everything comes with a container and runs on all operating systems without extra overhead.
You can find the source code for the article in the following GitHub repository: