Quick Start Guide for Docker with Angular on Windows
For Development
Recently I had to create an angular web application for one of my projects and I thought of dockerizing it, so my team mates will run into absolutely no issues while contributing to it. What is docker and what it does is out of the scope of this article but if you want to get a quick understanding I can summarize it as follows.
Docker is a tool designed to make it easier to create, deploy, and run applications by using containers. Containers allow a developer to package up an application with all of the parts it needs, such as libraries and other dependencies, and ship it all out as one package.
To follow this post, you should belong to either one of these categories,
- You are going to start a new Angular project or
- You have an existing Angular project that you want to dockerize.
There are many tutorials on the web and on YouTube to walk you through, but at the end I found there’s always something missing and my docker image is failing in live reloading; whenever I change source code of the angular app, the changes are not visible on the browser like it usually does when you are developing the application without docker. At the end thanks to many StackOverflow posts, I am proud to present this fix, and with that included I.m writing this blog post. Let’s get started.
Follow official Angular documentation and create a new project if you don’t have a project.
npm install -g @angular/cli
ng new my-app
Now we need two files on the root directory of the project. A Dockerfile and docker-compose.yml file.
Oh wait!. You need to have Docker installed first. Head over to https://www.docker.com/products/docker-desktop and download the setup, and install. I’m on windows but if you are on some other OS you can follow along too. After you have installed docker and restarted your computer, go to Services(on windows, by searching it on search bar) and see if the service is running.
You do not need to verify that, docker will tell you if it can’t run the service with an error message. Just know that you need docker service running to do the next steps. Let’s move on.
Create two files using the IDE that you are using on the root directory of the project (root directory is the folder where your package.json file is in.)
File no 1 — Dockerfile (with no extensions)
File no 2 — docker-compose.yml
Tip: Use powershell terminal (on windows) to type commands, some commands may not work on cmd.
Copy and paste following content to Dockerfile.
Copy and paste following content to docker-compose.yml
These files should be on the root directory of the project, and remember to change line 3 (dashboard
)to whatever the name you want your docker container to be named.
Let’s go through each line of the Dockerfile and see what it does.
FROM node:10.16.3-alpine
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 4200 49153
CMD npm run start
First line sets the node version to use in the docker image, locally I have the same node version so I put 10.16.3 as my image node version (check by running node -v
on the terminal and use your version), and alpine is the Linux image that our compact environment is based on. Derick Bailey has a complete description about this, do give it a read.
Next we set the directory or folder that we will be working on that environment (inside the docker image.) I have chosen /app
for simplicity. Hereafter the .(period) will denote this folder.
So the next line is self explanatory right? copy package.json
to .
Then we run npm install
to install all the packages to that environment. Copy all the files from this folder (`.`) to that folder (`.`), exposing two ports 4200
because Angular development server runs on that port, 49153
because it is the Angular live-reload port. These ports need to be accessed from outside the image so we can run our project on our browser. Next we are executing ng serve
using npm. If you look inside package.json, under scripts section, you can see that start
command calls ng serve
.
While we are here, let’s modify the start
command a little bit.
"start": "ng serve --host 0.0.0.0 --poll 500"
--poll
is telling the client to check every 500 milliseconds if there are any new changes made. This is the fix that I was talking about (for Windows). Terns out without this, live reloading do not work. Some say it’s because host OS is windows and image is Linux, whatever the cause is now it should work. --host
says to listen on all incoming connections for requests.
Now we need to tell docker to forward port 4200 and 49153 to the same ports in the host OS, Windows in my case. This is where the docker-compose.yml comes in. That’s what the ports
section does.
ports:
- "4200:4200"
- "49153:49153"
In addition to that we need to tell docker to map everything that we have locally to the /app
folder on the image (volume mapping). So every change we do will be immediately sent to the /app
folder. volumes
section is doing that.
volumes:
- "/app/node_modules"
- ".:/app"
All set.
Now open terminal where the Dockerfile is located and run docker-compose up
. If the docker service is not running you will get an error like this. If this is the case search for docker and open the docker desktop application.
Now run docker-compose up
again.
If everything is okay, you will see docker following every step one after the other, creating the image, creating a container using that image, building your application and finally compiling your application. It will take a minute or two to complete the process on first time.
My application name is dashboard
, hence the image name is dashboard_1. You can change this on docker-compose.yml
3rd line, where it says dashboard.
Change it to the name you want.
Open your browser at http://localhost:4200/ and test the live reloading. Press Ctrl + c
to stop the container. Every time you want to develop this application, navigate here using terminal and run docker-compose up
and docker will start the container built previously. You can run docker-compose build
before running up
command to build the docker image again, if changed Dockerfile
or docker-compose.yml
docker ps -a
command will list all the containers up(see status) or inactive.
docker images -all
will list all images on your computer.
To remove all containers, you can use docker rm $(docker ps -a -q)
and to remove all images, run docker rmi $(docker images -q)
Note: This is for development purposes. If you want to deploy your Angular application as a container, well, that’s another topic for a later day. Until then, happy coding!