Docker Concepts


Docker commands
Basics
Entering Interactive Mode
Deleting Images & Containers
Removing Stopped Containers Automatically
Inspecting Images
Copy Files Into & From A Container
Naming & Tagging Containers & Images
Docker Hub Configuration with Image Push & Pull
Docker Hub Image Tag
Volumes
Anonymous Volumes
Named Volumes
Bind Mounts
Read only Volumes
Nodemon
.dockerignore
Environment Variables & ".env" Files
Build Arguments(ARG)
Networks
multi-container
Installing Docker Compose on Linux
Utility Containers, Permissions & Linux


Docker commands
sudo docker build .	
sudo docker run -p 3000:3000 sha256:2447845036998e1bcc1e2682ff10fb2e7f86bc3f38e90f73fee2805ff499fe3f	
sudo docker ps	
sudo docker ps -a	
sudo docker stop affectionate_satoshi	
sudo docker start affectionate_satoshi	
sudo docker start -a affectionate_satoshi								# Attached Mode	
sudo docker run -p 3000:3000 -d sha256:2447845036998e1bcc1e2682ff10fb2e7f86bc3f38e90f73fee2805ff499fe3f	# Detached Mode	
sudo docker run -p 3000:3000 sha256:2447845036998e1bcc1e2682ff10fb2e7f86bc3f38e90f73fee2805ff499fe3f 	# Attached Mode		
sudo docker attach affectionate_satoshi									# Attached Mode	
sudo docker logs affectionate_satoshi	
sudo docker logs -–help	
sudo docker logs -f affectionate_satoshi	
sudo docker run –help	
sudo docker start -a -i awesome_lederberg	
sudo docker rm blissful_heisenberg vibrant_hofstadter	
sudo docker container prune	
sudo docker images	
sudo docker rmi 1c9634a15451 d9df6f303b2c	
sudo docker image prune	
sudo docker image inspect d9df6f303b2c	
sudo docker run -i -t sha256:2447845036998e1bcc1e2682ff10fb2e7f86bc3f38e90f73fee2805ff499fe3f	
sudo docker run -it sha256:2447845036998e1bcc1e2682ff10fb2e7f86bc3f38e90f73fee2805ff499fe3f	
sudo docker run -p 80:80 -d –rm sha256:2447845036998e1bcc1e2682ff10fb2e7f86bc3f38e90f73fee2805ff499fe3f	
sudo docker cp dummy/. affectionate_satoshi:/test	
sudo docker cp affectionate_satoshi:/test dummy	
sudo docker run -p 80:80 -d --rm --name kishoreapp d9df6f303b2c	
sudo docker build -t kishoreimage:latest .	
sudo docker image inspect kishoreimage	
sudo docker image prune -a										# -a Remove Including Tagged images
sudo docker run -p 80:80 -d --rm --name kishoreapp kishoreimage:14
sudo docker build -t thakishore/kishoreapp-node .
sudo docker login
sudo docker push thakishore/kishoreapp-node
sudo docker logout
sudo docker pull thakishore/kishoreapp-node
sudo docker tag node thakishore/kishoreapp-node
sudo docker run -p 80:80 -d --rm --name kishoreapp -v feedback:/app/feedback kishoreimage:14
sudo docker volume rm feedback
sudo docker volume prune
sudo docker run -p 80:80 -d --rm --name kishoreapp -v feedback:/app/feedback -v "/home/kishore/Desktop/docker/data-volumes-01-starting-setup:/app" -v /app/node_modules kishore-temp-image
sudo docker run -p 80:80 -d --name kishoreapp -v feedback:/app/feedback -v /app/node_modules -v "/home/kishore/Downloads/data-volumes-04-added-nodemon/data-volumes-04-added-nodemon:/app:ro" kishoreapp-image
sudo docker run -p 80:80 --env PORT=80 -d --name kishoreapp kishoreapp-image
sudo docker run -p 80:80 -env PORT=80 -d --name kishoreapp kishoreapp-image
sudo docker run -p 80:80 -env PORT=80 -env Name=kishore -d --name kishoreapp kishoreapp-image
sudo docker run -p 3000:8000 --env-file ./.env -d --rm --name kishoreapp kishoreapp-image
sudo docker build -t kishoreapp-image:web .
sudo docker build -t kishoreapp-image:dev --build-arg PORT=8000 .
sudo docker network create kishore-net
sudo docker network ls
sudo docker -d --name mongodb --network kishore-net mongo

docker exec -it kishoreapp npm init

sudo docker build -t node-util .
sudo docker run -it --name kishoreapp -v /home/kishore/Desktop/docker/UtilityContainer:/app node-util install express --save

Basics











Entering Interactive Mode
sudo docker run -i -t sha256:2447845036998e1bcc1e2682ff10fb2e7f86bc3f38e90f73fee2805ff499fe3f
sudo docker run -it sha256:2447845036998e1bcc1e2682ff10fb2e7f86bc3f38e90f73fee2805ff499fe3f
	


Deleting Images & Containers
sudo docker rm blissful_heisenberg vibrant_hofstadter
sudo docker container prune
sudo docker images
sudo docker rmi 1c9634a15451 d9df6f303b2c
sudo docker image prune


-
Removing Stopped Containers Automatically
sudo docker run -p 80:80 -d –rm sha256:2447845036998e1bcc1e2682ff10fb2e7f86bc3f38e90f73fee2805ff499fe3f


Inspecting Images
sudo docker image inspect d9df6f303b2c


Copy Files Into & From A Container
sudo docker cp dummy/. affectionate_satoshi:/test
sudo docker cp affectionate_satoshi:/test dummy
		

Naming & Tagging Containers & Images
sudo docker run -p 80:80 -d --rm --name kishoreapp d9df6f303b2c
sudo docker build -t kishoreimage:latest .
sudo docker image inspect kishoreimage
sudo docker run -p 80:80 -d --rm --name kishoreapp kishoreimage:14






Docker Hub Images Push & Pull
sudo docker build -t thakishore/kishoreapp-node .
sudo docker login
sudo docker push thakishore/kishoreapp-node
sudo docker logout
sudo docker pull thakishore/kishoreapp-node








Docker Hub Image Tag
sudo docker tag node thakishore/kishoreapp-node


Volumes
Anonymous Volumes : since you don't assign any name.
Named Volumes : since you do assign a name.
Bind Mounts : an absolute path to a folder on your host machine

docker run -v /app/data ...
docker run -v data:/app/data ...
docker run -v /path/to/code:/app/code ...

Anonymous Volumes

Anonymous Volumes can be used in 2 ways
1. Inside docker file 
EXPOSE 80
VOLUME ["/app/feedback"]
CMD ["node", "server.js"]

Check Volume : sudo docker volume ls
maybe~~~~~Temporary Application Data




With anonymous volumes, you create a volume which is kind of attached to a container. It's removed if the container is removed. It survives container shut down and restart, but if it's removed, it's gone and therefore if you use the --rm when you ran the container, of course the volume is all gone when you stop the container because stopping then basically also means removing the container. Therefore, since it is removed when the container is removed, you can't use anonymous volumes to share data across containers. And you also can't use it to save data across container destruction and recreation. But anonymous volumes either created with the volume instruction in the dockerfile or created with -v, * can be useful for locking in certain data which already exists in the container. They can be useful for avoiding that this data then gets overwritten by another module. And that's something where anonymous volumes can save the day. * In addition, anonymous volumes also still create a counterpart, a folder, on your host machine. Of course that's removed when the container's removed, but that exists as long as the container is running. And that of course means that docker doesn't have to store all the data inside of the container and doesn't have to manage all the data inside of this container read write layer. But that instead it can outsource certain data to your host machine file system. And this can also help with performance and efficiency. So that's why anonymous modules can be worth a closer look. Example: we could consider creating another anonymous volume, maybe inside of the docker file to mix things up for the temp folder. It's okay if we lose that folder when the container is removed, but for the reasons I just mentioned, Example for tiny performance improvements, it can be worth mapping this temp folder to an anonymous volume so the data managed in there is not managed in the docker container anymore, but actually well outsourced to the host file system, you could say. That could be useful and therefore it is something we can do here for sure. Removing Anonymous Volumes We saw, that anonymous volumes are removed automatically, when a container is removed. This happens when you start / run a container with the --rm option. If you start a container without that option, the anonymous volume would NOT be removed, even if you remove the container (with docker rm ...). Still, if you then re-create and re-run the container (i.e. you run docker run ... again), a new anonymous volume will be created. So even though the anonymous volume wasn't removed automatically, it'll also not be helpful because a different anonymous volume is attached the next time the container starts (i.e. you removed the old container and run a new one). Now you just start piling up a bunch of unused anonymous volumes - you can clear them via docker volume rm VOL_NAME or docker volume prune.

Named Volumes

sudo docker run -p 80:80 -d --rm --name kishoreapp -v feedback:/app/feedback kishoreimage:14



* Named volumes can not be created in the dockerfile, but instead you create them with the -v instruction when you run a container. * They are named because you assign a name in front of the colon. Now the great thing about named volumes is that they're created in general. They're not tied to any specific container. They do survive container shut down and also the removal of containers. If you want to remove a named volume, you can still do that, but you have to do it with a separate command built into the Docker CLI. * Now since they survived container removal, you can use named volumes to share data across multiple containers, * You could mount one of the same named module to multiple different containers and hence the data in there could be shared between containers. * We can also use them to store data across container shutdowns and removals.

Bind Mounts

Bind mounts serve a different purpose.
Here we know where data is stored on the host machine.
Bind mounts are also not tied to one specific container.
You can attach them to multiple containers and they do survive container shutdown and removal.
If you want to clear the data of a bind mount, you actually have to delete it on your host machine.

So here I would have to delete all the content here

in my project to also remove it in the container.

You can't delete it with a docker command.
And that makes a lot of sense,
because it is a folder on your system after all
and you don't want to accidentally delete this somehow.
Now of course you can share them across containers and you can also reuse them on one of the same container across restarts.

Read only Volumes
sudo docker run -p 80:80 -d --name kishoreapp -v feedback:/app/feedback -v /app/node_modules -v "/home/kishore/Downloads/data-volumes-04-added-nodemon/data-volumes-04-added-nodemon:/app:ro" kishoreapp-image

Nodemon


.dockerignore

Environment Variables & .env Files
sudo docker run -p 80:80 --env PORT=80 -d --name kishoreapp kishoreapp-image
sudo docker run -p 80:80 -env PORT=80 -d --name kishoreapp kishoreapp-image
sudo docker run -p 80:80 -env PORT=80 -env Name=kishore -d --name kishoreapp kishoreapp-image
sudo docker run -p 3000:8000 --env-file ./.env -d --rm --name kishoreapp kishoreapp-image





Build Arguments(ARG)
sudo docker build -t kishoreapp-image:web .
sudo docker build -t kishoreapp-image:dev --build-arg PORT=8000 .

Networks

Cheat-Sheet-Networks-Requests PDF
slides-networking PDF
networks-finished Project ZIP

Within One Network Domain Name Translation and All PORTs are opened internally, so No ports can be opened ex: -p not required to communicate internally in one network. 

Container to Container Communication - BY manually finding the IP Addresses or by using a network

sudo docker network create kishore-net
sudo docker network ls
sudo docker -d --name mongodb --network kishore-net mongo

None 	: mongoose.connect('mongodb://localhost:27017/swfavoties',....)
Host	: mongoose.connect('mongodb://host.docker.internal:27017/swfavoties',....) host.docker.internal Translated to local host ip address
Bridged	: mongoose.connect('mongodb://172.2.0.2:27017/swfavoties',....)	???	
Bridged	: mongoose.connect('mongodb://mongodb:27017/swfavoties',....) ??? Other Container Name Translated by Docker to IP address of Container

Condition ->	If Container name can be translated if -other container must be in same Network 
	

sudo docker run -d --name mongodb --network kishore-net mongo
sudo docker run -d --name kishoreapp --network kishore-net -p 3000:3000 --rm kishoreapp-image

Docker Network Drivers
Docker Networks actually support different kinds of "Drivers" which influence the behavior of the Network.

The default driver is the "bridge" driver - it provides the behavior shown in this module (i.e. Containers can find each other by name if they are in the same Network).

The driver can be set when a Network is created, simply by adding the --driver option.

docker network create --driver bridge my-net
Of course, if you want to use the "bridge" driver, you can simply omit the entire option since "bridge" is the default anyways.

Docker also supports these alternative drivers - though you will use the "bridge" driver in most cases:

host: For standalone containers, isolation between container and host system is removed (i.e. they share localhost as a network)

overlay: Multiple Docker daemons (i.e. Docker running on different machines) are able to connect with each other. Only works in "Swarm" mode which is a dated / almost deprecated way of connecting multiple containers

macvlan: You can set a custom MAC address to a container - this address can then be used for communication with that container

none: All networking is disabled.

Third-party plugins: You can install third-party plugins which then may add all kinds of behaviors and functionalities

As mentioned, the "bridge" driver makes most sense in the vast majority of scenarios.


multi-container


multi-01-starting-setup ZIP
slides-multi-container PDF
multi-02-finished ZIP

Installing Docker Compose on Linux
Installing Docker Compose on Linux


compose-01-starting-setup ZIP
slides-docker-compose PDF
Cheat-Sheet-Docker-Compose PDF
compose-02-finished ZIP

On macOS and Windows, you should already have Docker Compose installed - it's set up together with Docker there.

On Linux machines, you need to install it separately.

These steps should get you there:

1. sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

2. sudo chmod +x /usr/local/bin/docker-compose

3. sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

4. to verify: docker-compose --version

Also see: https://docs.docker.com/compose/install/


Utility Containers, Permissions & Linux
Utility Containers, Permissions & Linux

We can Read log files without interrupting the main process

Alpine - Slim and optimised node base image

slides-utility-containers PDF

When working with "Utility Containers" on Linux, I recommend that you also take a closer look at this very helpful thread in the Q&A section: https://www.udemy.com/course/docker-kubernetes-the-practical-guide/learn/#questions/12977214/

This thread discusses user permissions as set by Docker when working with "Utility Containers" and how you should tweak them.

docker exec -it kishoreapp npm init


sudo docker build -t node-util .
sudo docker run -it --name kishoreapp -v /home/kishore/Desktop/docker/UtilityContainer:/app node-util install express --save


sudo docker-compose --build  server
sudo docker-compose up -d --build server
sudo docker-compose down server php mysql