Docker
Introduction
Provide light-weight virtual environment with suitable version for program to execute in order to run the program smoothly and prevent conflict due to version issue

Registry: the link that used to get docker image ,which is similar with git repository
Image: a template of docker for creating container
Container: a light-weight virtual environment that run the instance of docker image
Virtual Machine vs Docker

Virtual Machine
Initially, we need one physical server for one application, which is expensive and cannot make good use of all of the memory and CPU
After virtualization, several virtual machines is isolated from host operation system which contains their own guest operation system and share CPU and memory from the computer
Therefore, different operation system can be existed in a server to run multiple applications
Docker
Docker containers which creates a virtual environment can run at the same time by using the same host operation system
Therefore, the boot up time will be shorter and becomes light-weight compared with virtual machine
The image registry provides the portability, so that the image is easily to be reused across different machines
General Flow
Summary
Pull the Image from registry
Create new instance of container based on docker image
Start the instance
Execute the instance
Pull the image
Syntax
docker image pull (image-name):(version)
Example
docker image pull mysql:8.0
docker image pull mysql
docker image pull ubuntu
If the version is not defined, the default version will be latest
Result

Create New Instance
Syntax
-d means run in background
-p defines the port run in local
-v defines the location of volume to backup the data in local, so that the data can be shared between different containers
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Example
docker run -d -v /Users/petercheng/Desktop/Jenkins:/var/jenkins_home
-p 8080:8080 -p 50000:50000 --name my_jenkins_container jenkins/jenkins:lts
docker run --name=mysql_container -d -v
/Users/petercheng/Desktop/mysql:/var/lib/mysql
-p 3316:3306 --env MYSQL_ROOT_PASSWORD=1234 mysql/mysql-server
If the name is not defined, the name will be generated randomly
Result

From the list, we can see that there is 2 instances that we created with their name and container id
Remove the instance
Syntax
docker rm (container id)
Example
docker rm 0504
Result

Start the instance
Syntax
docker start (container id)/(container name)
Example
docker start 44ed
Result

Stop the instance
Syntax
docker stop (container id)/(container name)
Example
docker stop 44ed
Execute the instance
Syntax
docker exec -it (container id)/(container name)
Example
dokcer exec -it test bash
Result

Customize Image
Commit the container
docker commit (CONTAINER_ID)/(CONTAINER_NAME)
Check whether new image is created or not and its image id
docker image ls
Edit the name of new image
docker image tag <IMAGE_ID> <YOUR CUSTOM NAME>
Push / Pull Image
Register an account and create new repository on dockerHub

Login
docker login
Push
Change the name
docker tag <Your image> <account_name>/<repository_name>
Example
docker tag custom_ubuntu headshootcheng/test
Push to registry
docker push headshootcheng/test
Pull
docker pull headshootcheng/test
Result

Push image to GCP
Login to gcp
gcloud auth login
gcloud auth configure-docker
Change the name of image and push google cloud container registry
docker tag ${IMAGE_NAME} asia.gcr.io/${YOUR PROJECT ID}/${IMAGE_NAME}
docker push asia.gcr.io/${YOUR PROJECT ID}/${IMAGE_NAME}
Docker File
Introduction
Initially, we need to execute the container and then generate new image, which is inconvenient.
Instead, we can write a script on docker file in order to automatize the process
It is a material of making a template (docker image)

FROM : from the original source of image
RUN: execute the command
COPY: copy file to specific directory
WORKDIR: cd into specific directory
CMD: execute the program on container, such as: node index.js
Example
Edit Dockerfile
// Dockerfile
FROM ubuntu
RUN touch hello.txt
CMD ["bash"]
Create New Image by executing Dockerfile
docker image build -t custom_image
Create + Start + Execute the container , and then see the result

we can see that hello.txt is here
Entry Point vs CMD
ENTRYPOINT
should be defined when using the container as an executable.CMD
should be used as a way of defining default arguments for anENTRYPOINT
command or for executing an ad-hoc command in a container.CMD
will be overridden when running the container with alternative arguments.ENTRYPOINT can be changed using the
--entrypoint
flag, but this should rarely be necessary for container images being used in the way they were intended.
ENTRYPOINT ["/usr/bin/my-app"]
CMD ["help"]
# Executes /usr/bin/my-app help
$ docker run my-image:latest
# Executes /usr/bin/my-app version
$ docker run my-image:latest version
# Executes bash -c "ls /"
$ docker run --entrypoint bash my-image:latest -c "ls /"
No ENTRYPOINT
ENTRYPOINT exec_entry p1_entry
ENTRYPOINT ["exec_entry", "p1_entry"]
No CMD
error, not allowed
/bin/sh -c exec_entry p1_entry
exec_entry p1_entry
CMD ["exec_cmd", "p1_cmd"]
exec_cmd p1_cmd
/bin/sh -c exec_entry p1_entry
exec_entry p1_entry exec_cmd p1_cmd
CMD exec_cmd p1_cmd
/bin/sh -c exec_cmd p1_cmd
/bin/sh -c exec_entry p1_entry
exec_entry p1_entry /bin/sh -c exec_cmd p1_cmd
Docker Compose
Introduction
In a big scale, we may need to execute several containers, it is time-wasting to create and start them one by one.
By writing a script docker-compose.yml, the process can be executed automatically
Example
Writing docker-compose.yml
version: "3"
services:
sql:
restart: always
image: "headshootcheng/keungsql"
volumes:
- "./config.conf:/etc/my.cnf"
environment:
MYSQL_ROOT_PASSWORD: "1234"
ports:
- "3316:3306"
container_name: keungsql
ubuntu:
image: "headshootcheng/test"
tty: true
container_name: keungUbuntu
Execute the command
# Start
docker-compose up (-d)
# Stop
docker compose stop
# Trace log
docker compose logs <name>
Result


2 instances of container with 2 different images are created and started
Volume

When creating volume, the folder will be created on the machine to host the data
docker volume create --name db-data
docker volume ls
Attach the volume to connect with path declared on the containerized environment
docker run -v db-data:/db/data -it ubuntu ls -la /db/data
docker run -v db-data:/db/data -it ubuntu touch /db/data/file
docker run -v db-data:/db/data -it ubuntu ls -la /db/data
The same volume is shared among the above commands, so the result

Debug
Create a docker file with meaningless entry point, so that we can execute the container to debug
# ...
ENTRYPOINT ["tail", "-f", "/dev/null"]
Reference
Last updated
Was this helpful?