Try   HackMD
tags: self-taught

Get started with Docker

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

I. What is docker

I bet in your programming life, you might once said: "It works on my computer!".
The reason for that problem would be varied. It would either be one or more files are missing, or a software version mismatch, or different environment, …
Well, Docker was born, trying to solve that problem.

In short, Docker is used to pack your software to run it on any hardware. By this, your app can be built, run and shipped consistently.

II. Installing Docker

It is recommended to use Docker desktop because it gives you the vision of what container is running and their log, in case you want to debug.
https://www.docker.com/products/docker-desktop/

*You should also add Docker extension to your IDEA

III. Development workflow

Before we start dockerizing an app, there are 3 things you must know:

  • Dockerfile is a blueprint to build an IMAGE (like an instruction file so Docker knows how to setup the app).
  • IMAGE is a template to run a docker container.
  • Container is a running process.
  • Docker Hub is a service provided by Docker for finding and sharing container images with your team. It's basically github but for docker.

To dockerize an app:

1. add a Dockerfile to your app
It's a plain text file that has instruction to package the app into an IMAGE.

// start from a base image, here you're building node app, so we use node image, this image is in docker hub
FROM node:12
// add app source code, any instruction on docker will start from this directory
WORKDIR /app
// normally, we will get the source code and then install package, but in docker we will want to install dependencies first so it can be cached and the dependencies wont be reinstalled everytime we change our source code
// using the COPY command to put package.json to container root directory
COPY package*.json ./
// then install the dependencies
RUN npm install
// copy app source code but add .dockerignore so it wont copy the node_module
COPY . .
// set port
ENV PORT=8080
EXPOSE 8080
// finally the comand on how to run the application
CMD ["npm", "start"]

2. with Dockerfile we can build the docker image

// use -t to name image
doker build -t anyNameYouWant

When the build process was done, you can you docker push command to push this Image to dockerhub or any cloud service so others can use it too.
To run the container use docker run -p 9000:8080 imageID (9000 is the local port and 8080 is docker port, it means to expose the container to your local machine).
3. add volume
When we stop the container, all state and data will be lost, but in many situations, we'd want to keep the data and share it to other containers as well.
In that case, we can create Volume. Volumes are dedicated folder in host machine, use this to share data between container.
To create a volume, use docker volume create volumeName.
Then, when we run a docker, we can mount it to this shared volume using the –mount flag:
https://docs.docker.com/engine/reference/commandline/run/#add-bind-mounts-or-volumes-using-the–-mount-flag
4. Run multiple containers
Each container should run only 1 process, for example, beside the app running process, we also want to access mysql data base and run cache with redis.
To be able to do that, we can use docker-compose.yml.

version: '3'
// each key of services object represent the container that we want to run
services:
// we have web, to demonstrate the app running process
    web:
        build: //where is the dockerfile
        port:
            - "8080:8080"
// then we have db, to demonstrate the sql accessing process
    db:
        image: "mysql"
        environment:
            MYSQL_ROOT_PASSWORD: password
// mount the shared volume we created
        volumes:
            - db-data:where it locate
// last is the volumes to share data across multiple containers
volumes:
    db-data:

Finally, run docker-compose up to run all containers, instead of running one by one.

==> That's a wrap everyone. This is just an overview of Docker, you should take a look in theri documents for more complex cases.
https://docs.docker.com