Study

Learn Docker in 7 Easy Steps - Beginner’s Tutorial by Fireship.io

Credits / Notes taken from:

Resources:

Table of Contents:


Docker is just a way to package software (applications) so it can run on any hardware. So the app will work on every machine (eg. the Docker container will take care of every dependency that the app is using, either Node libraries with specific versions, or even Linux libraries with a specific version).

Docker is an open source software platform to create, deploy and manage virtualized application containers on a common operating system (definition by techtarget).

Note: Images can be uploaded to the cloud in public or private registries (just like GitHub repos). Then, every developer can pull the image down from the Docker cloud to create a container (container = a running process of that image).

Docker Beginner's Tutorial by Fireship


Installation

For Windows, install Docker Desktop. This will install everything needed for the command line (CLI) and also a GUI to inspect the running containers, logs and more.


For Linux (Debian/Ubuntu) follow the steps mentioned here https://docs.docker.com/desktop/install/ubuntu/ (also available for Fedora/Arch).



Some Docker commands:

docker --help

# or to see help for specific docker command
docker image --help
docker container --help
docker volume --help
docker ps
# Remove unused images
docker image prune

# Remove all stopped containers
docker container prune

# Remove unused local volumes
docker volume prune


Docker commands cheat sheets:


Dockerfile

In the app’s project folder (eg. for a Node.js application like this one here, or my angular app from Traversy Media crash course), create a Dockerfile file (without any file extension).


For our Angular App from this angular-crash-course repository, the Dockerfile will look like this:

FROM node:16

WORKDIR /app

COPY package*.json ./

RUN npm install

RUN npm install -g @angular/cli

COPY . .

ENV PORT=4200

EXPOSE 4200

CMD ["ng", "serve", "--host=0.0.0.0"]

Docker Beginner's Tutorial




🔵 Note that we will run the development server for this Angular app, not the production one (that involves the npm build command and COPYing the files from the dist folder to the conetainer, like in this article)!


Useful other resources / notes:


Build a Docker image

(Saturday, August 27, 2022)

To build a Docker image, we need to run the docker build command.

docker build -t myusername/angularapp:1.0 .


We can check the image that has been build within Docker Desktop application:

Docker Beginner's Tutorial by Fireship


Run Container locally

We can run the image that has been build with the docker run with the image id or the tagname as parameter.

# View images IDs
docker image ls

# Run container
docker run 9ceabb5cffa5

If we do not encounter any errors, we should see our container running:

Docker Beginner's Tutorial by Fireship


Port forwarding

🟠 However, if we open up the browser and go to http://localhost:4200 (our exposed port), we can’t reach that site => we need to add some more arguments the docker run command, by using the -p flag to implement port forwarding from the docker container to our local machine:

docker run -p 4200:4200 9ceabb5cffa5

# or if we want to forward multiple ports, just use -p multiple times
docker run -p 4200:4200 -p 5000:5000 9ceabb5cffa5


docker run --name angular_app_container -p 4200:4200 9ceabb5cffa5


Here’s all of our commands so far:

Docker Beginner's Tutorial

Now, in our case, we can see our Angular App running (on development server), on http://localhost:4200:

Docker Beginner's Tutorial




🔵 Note, to stop the previous running container:

# View list of running containers
docker ps

# Copy the container id (or the first digits)

# Stop the container
docker stop 2794cfc4435a

# Remove the container
docker rm 2794cfc4435a

Docker Beginner's Tutorial


🔵 Note, when we open http://localhost:4200/, we might encounter localhost didn’t send any data. ERR_EMPTY_RESPONSE error. For this, we would need to actually serve our node app to 0.0.0.0 address instead of 127.0.0.1 (localhost) => so the command for Dockerfile will be CMD ["ng", "serve", "--host=0.0.0.0"] . More details here.

Docker Beginner's Tutorial


Also note that for external node server (such as dummy pre-made back-end service (REST API), like JSON Server npm - a full fake REST API with zero coding in less than 30 seconds), we also need to add --host 0.0.0.0 in the command for that service (in order to fully expose the service port from Docker to our local machine):

{
  "name": "angular-crash-course",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "server": "json-server --watch db.json --port 5000 --host 0.0.0.0"
  }
}


Useful other resources / notes:


Docker debugging

# View running containers
docker ps

# Copy the docker id, eg. aaa5c96fd2

# View logs from that container (with -f from follow)
docker logs -f aaa5c96fd2


# docker exec <containerId> COMMAND
docker exec aaa5c96fd2 ls

Docker Beginner's Tutorial

docker exec -it aaa5c96fd2 /bin/sh

# Run Linux commands
pwd
ls

# Type exit to exit
exit

Docker Beginner's Tutorial


Docker Beginner's Tutorial


Docker compose

Docker only allows us to have one process per container. If our app runs multiple services (on multiple ports, eg. 4200 and 5000), with only one Docker container we can’t run all of the services.

For example, if our entire Application has a back-end (exposed on port 5000) and a front-end (exposed on port 4200), we need to use create and configure a docker-compose.yml file to run multiple Docker containers at the same time.

Another application example that needs docker-compose: a SpringBoot app as a REST API (as one service) that also needs a MySQL database to store the data (as another service).

Docker Beginner's Tutorial


Maybe useful link: Dockerize a Node.js Application for development with docker-compose.


docker-compose.yml

Let’s create a docker-compose.yml file in the root of our project.


Finally:

FROM node:16

WORKDIR /app

COPY package*.json ./

RUN npm install

RUN npm install -g @angular/cli

COPY . .

ENV PORT=4200

EXPOSE 4200

CMD ["sh", "-c", "ng serve --host=0.0.0.0"]
FROM node:16

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

ENV PORT=5000

EXPOSE 5000

CMD ["npm", "run", "server"]
version: "3"
services:
  angular_app:
    build: .
    ports:
      - "4200:4200"
  json_server:
    build:
      context: .
      dockerfile: Dockerfile.json_server
    ports:
      - "5000:5000"

Docker Beginner's Tutorial


Docker-compose commands

Finally, we can start all the containers at once by running docker-compose up command.

docker compose up

🔵 Note: you can also use docker compose up (newer version) instead of docker-compose up (old version). See more here.

Docker Beginner's Tutorial

And we can see our “services” running (namely our front-end app on http://localhost:4200/ and our back-end JSON server on http://localhost:5000/)!

Docker Beginner's Tutorial


Unlike docker run command, here (in the terminal that we ran docker compose up) if we press CTRL+C we will actually stop all docker containers. However, this command will not remove those containers (will be still be kept in memory), so we need to run docker-compose down.

docker compose down

If we had any volumes associated with these containers, we add -v (volumes) command.

docker compose down -v

To remove both built Docker images via command line

# View images and their IDs
docker images -a

# Remove both images by their IDs
docker rmi <angular_appImageID>
docker rmi <json_serverImageID>