Video link - https://www.youtube.com/watch?v=p28piYY_wv8&t=2869s
- Docker is a tool for running applications in an isolated enviornment
- It is similar to virtual mahine
- Standard for software deployment
- If you create a package in docker it is sure to work in any system
- Containers are an abstraction at the app layer that packages 'code' and 'dependencies' together. Multiple containers can run on the same machine and share the OS kernel with other containers, each running as isolated processes in user space.
- A container does not require a full os it just shares the underlying os with other containers.
- Image -
- Image is a template for creating an enviornment of your choice.
- Image has everything needed to run your Apps.
- OS, Software, App Code
- Container is a running instance of image
- Volume:- allows sharing data between host and container, and also between containers
- If we add files and folders in this volume in host - they will show up in containers and vice versa
- Dockerfile :- allows us to build a new image, contains list of steps on how to create images
- .dockerignore:- when we are doing ADD . ., it will add all the files in the docker. We can exclude some files by editing .dockerignore
- Caching and layers:- The image building step might take much time everytime we change something like adding more data in node.js
- To avoid this the docker uses cache, this takes less time as same things need not to be done again
- Tags and version:- allows you to control version, avoids breaking changes (eg. if you build your software using node:latest and the latest version chages from 8 to 9 breaking your code)
- Docker Registries:-
- server side application that stores and lets you distribute docker images
- can use docker registris for CD/CI piplines
- Can run parts of our application
- We use docker push/pull
1. Pulling and running docker images
- We go to docker hub and explore images
- Here we download ngnix image using :- docker pull nginx
- Check the image using :- docker images
- Run the image using :- (docker run nginx:latest) here 'latest' is a tag - can be 1.0, 2.0 etc.
- Check the container using the command - (docker ps) in other container
- run in detached mode :- refer command 2.1
2. Exploring ports
- We notice the port name as - '80/tcp' in docker ps
- We want to map the port 8080 of our local host to the port 80 of the container :- refer command 8.
- We verify by going on browser and typing localhost:8080
- We map another port to the port 'tcp' refer command 3.1
- we verify by typing both ports on browser
3. Managing containers
- The old container does not get deleted after stopping, we can do 'docker start <containername/id>' to start the container
- The container will automatically get a random name everytime unless you specify it
- We can delete all containers at once :- refer cmd 2.8 and 2.9
- we can delete containers forcefully if they are running or some other issue shows up refer cmd 2.7
- We can name a container while starting using cmd 2.10
- We write a big command using all the things mentioned earlier as - docker run --name website -d -p 3000:80 -p 8080:80 nginx:latest :-
- '-d' for detached mode
- '-p' for port
- '--name' for name
- 'ngnix:latest: image name and tag
- Create the FORMAT variable in bashrc and give it a column format to make it easy to see
- We can use the command (docker ps --format=FORMAT) to see the container info in better format
4. Volumes :- refer theory 9 to 10
- Now we have created a folder called website in the directory
- Create index.html inside the folder and mount the folder as a volume in /usr/share/nginx/html
- We use the command :- docker run --name website -v $(pwd):/usr/share/nginx/html:ro -d -p 8080:80 nginx :- refer cmd 4.1:- dont use the 'ro' flag if you wish to modify the directory, pwd :- gives the address of current directory (e.g.- /home/tejas/study/learning_docker)
- We go on browser and do localhost:8080 and see the html page that we created
- We do docker exec -it website bash to go inside container
- We remove the ro flag while running the container again and we go inside the html folder in address mentioned at 23. and touch a about.html file
- The last step creates a file also at host refer theory 10
- search for a theme on bootstrap single page template, download, copy the content and paste in the website folder and delete all old files
- run docker and check the website on localhost:8080
5. Sharing volumes between containers
- using command :- docker run --name website_2 --volumes-from website -d -p 8000:80 nginx :- refer cmd 4.2
- We create new container called website_2 and mount the volume from the container website into website_2.
- We give it a different port no. and check if the website is running
6. Dockerfile :- refer theory 11
- We create a docker file with the base image nginx, we add the files from the website folder in the container adresss :- /usr/share/nginx/html, and this is not a volume mount, its static content
- refer Dockerfile for comments
- build the image using :- docker build -t website:latest .
- The comments should be placed on newline in Dockerfile
- Run the container using new image:-docker run --name website -p 8080:80 -d website:latest
- check if website is running
7. Node.js and express
- Install node.js and express
- Create a dir. called user_service_api and do npm init
- copy the helloworld example from the getting started page of express.js and create index.js
- Run the file and check output in browser
- Modify the file to send a json object and check on browser check commits
- Modify to return json array
- We have created a simple API!
- Now we have to dockerize this api
- Create a Dockerfile in user_service_api folder, refer comments in the file
- Run docker using :- docker run --name user-api -d -p 3000:3000 usr-service-api:latest
- Express js listens to port 3000 by default, we map port 3000 of host to port 3000 of docker
8. Dockerignore
- .dockerignore:- when we are doing ADD . ., it will add all the files in the docker. We can exclude some files by editing .dockerignore
- In this case we do not need to add node_modules as they will be installed in docker due to 'npm install' commands
- Create the .dockerignore file and delete & create the image again
9. Caching and layers
- The image building step might take much time everytime we change something like adding more data in node.js
- To avoid this the docker uses cache, this takes less time as same things need not to be done again
- In our case the 1st 4 steps are :- Step 1/6 : FROM node:latest ---> c71adfc6ec58 Step 2/6 : WORKDIR /app ---> Using cache ---> 5ba5e764db30 Step 3/6 : ADD . . ---> 3c7ac8cfbfeb Step 4/6 : RUN npm install -g npm ---> Running in 3e88b6855c8f
- The 4th step is heavy and 5th step is npm install which is also heavy, these steps are not using cache as the step befor them - ADD . . is changing due to the small change we made in index.js
- We need the package.json file for installing the node dependencies. Therefore we will add a json file first then run install and then ADD . ., see commit
- build the image then change the index.js file and then build the image again
- In first build it will download all dependencies and in second build it will use chace improving the speed
10. Alpine
- alpine is small in size and efficent, every image has a alpine tag eg. - alpine linux
- Lets try pulling alpine version of node:- docker pull node:lts-alpine :- lts stands for latest
- The alpine version is jsut 167 mb and latest version of node is 995 MB
- Now we change the base image in our Dockerfile to node:alpine and also in other Dockerfile to nginx:alpine
- user-service-api images has reduced to 187 MB from 1GB
11. Dangling images
- The old images are overwritten everytime we do docker build for same image, they are known as dangling images
- remove dangling images using docker rmi $(docker images -f'dangling=true' -q)
12. Tagging and versioning :- refer theory 15
1. change nginx version in websites's dockerfile from alpine to 1.17.2 - alpine and user-service-api dockerfile to 10.16.1-alpine 2. Build image and run containers 3. tag a already existing node:latest image using:- docker tag node:alpine node:1 refer cmd 1.9 4. modify something, create image and then tag as version 2 instead of 112. Repositories:- refer theory 16
- sign in on docker hub
- create a public repository called website
- Docker command given by website:- docker push takalkartejastt/website:tagname
- do:- docker tag website:latest takalkartejastt/website:1
- login using:- docker login
- docker push takalkartejastt/website:1
- should add overview so that people can understand the image
- delete the image from pc
- Do:- docker pull takalkartejastt/website:1
- Note that the latest version should be pushed to dockerhub as it will pull the latest version if no tag is used while pulling.
13. Docker inspect, log and exec
- Run a container and do :- docker inspect [container name/id]
- returns a json file:- shows volume mounts, env variables like path and dependcies, image, port mapping,
- docker log:- returns log , requests form firefox. also shows messege in console.log from program
- docker pull [imageName]
- docker images :- see the list of images
- docker image rm: delete image
- docker rmi:- delete image
- docker images -f'dangling=true' :- gives all dangling images that has tag [none] which means they have been overwritten by other image
- docker images -f'dangling=true' -q :- give only the image id of dangling images
- docker rmi $(docker images -f'dangling=true' -q) :- delete all dangling images
- docker build -t [name]:[tag] [locationOfDockerFile] :- build image using DockerFile
- docker tag [image name]:[tag] [image name]:[new tag]
- docker run [imagename]:[tag]
- docker container ls :- docker ps
- docker run -d [imageName] :- run in detached mode
- docker stop [containerID/containername]
- docker ps -a:- to show all the containers alongside that had stopped
- docker rm [containername/id]
- docker rm -f [containerid/name] : delete forcefully
- docker ps -aq :- give only ids of all the containers
- docker rm $(docker ps -aq) :- delete the things given by this command
- docker run --name [containerName] [imageName]:- we can manually name container instead of the random name given by pc
- sudo docker run –it [container_name]:[tag] /bin/sh :- run container in interactive mode
- docker ps --format=$FORMAT :- to see the container info in better format
- docker inspect [container name/id]:- gives a json file with all container related info
- docker log [containerName/id]:- returns log , requests form firefox. also shows messege in console.log from program
- docker run -d -p 8080:80 [imageName] :- 80/TCP is the port no. of the container which can be seen in the docker ps, here we map the localhost 8080 to the port 80 of the container
- We can access the image on webpage by entering localhost:8080
- docker run -d -p 8080:80 -p 3000:80 [imageName] :- can map multiple ports
- docker run -v [addressOfTheFolderInHOST]:[addressOfTheFolderInDocker] [imageName] - mount the volume while running the images
- docker run --name [toBeCreatedContainerName] --volumes-from [containerNameWhoseVolumeWeNeed] [image_name] :- to mount the volumes from one container to other
- docker exec -it website bash:- to execute in interactive mode
- pwd :- gives the address of current directory (e.g.- /home/tejas/study/learning_docker)
-
docker container prune -f
docker image prune -f
docker volume prune -f
docker container prune -f && docker image prune -f && docker volume prune -f
Reclaim lost memory to unused dockers or imagesdocker system prune -f
- docker login