Stuff You Should Know
ONLY ONE!
- Docker containers are designed to run only one process.
Ephemeral (lasting for a very short time)
- Docker containers are meant to be ephemeral, once their process completes the container goes to sleep, and it's memories about anything that happened while it was running go with it!
No persisting data!
Because docker containers are ephemeral, any stored data are ephemeral as well!
But there is always a workaround, right?
Docker command structure
docker command [-options] [arguments]
Images Management
How to display all the images you have locally?
docker images
How to remove an image?
# docker rmi <image_name/id>
docker rmi ubuntu
To remove an image. All containers running or stopped must first be removed!
How to download (pull) New Images from DockerHub
# docker pull <image_name>
docker pull hello-world
docker pull by default pulls from the DockerHub registry
How to pull from other registries?
# docker pull <registry>/<image_name>
docker pull ctfd/ctfd
this will pull ctfd image from ctfd registry
How to build a new image?
# change your directory to the place containing your Dockerfile
cd project
docker build -t tag .
How to push images to Dockerhub?
docker login
# then enter your docker-hub username and password
# docker push <image_name/id>
docker push todo-flask-v2
Containers Management
How to run a container!
# docker run <image_name/id>
docker run ubuntu
So what happened when we executed the above command? nothing?!!
as we said earlier docker containers are ephemeral so the container ran and exited once it's process exits!
How to display all running containers?
docker ps
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 131cf4b3c0f6 todo-flask-v2 "python3 -m flask ru…" 13 seconds ago Up 9 seconds ecstatic_cori
Container ID
- Each container has a unique ID, you can reference the container using it's ID
Image
- The image name of the container is an instance of
Command
- The running command on the container
Created
- When was the container created
Status
- What is the status of the container ( running - paused - exited )
Ports
- Exposed ports
Name
- Each container gets a unique random name unless you specified a unique name when running it
How to display all containers?
docker ps -a
# CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 69702cf6c516 todo-flask-v2 "python3 -m flask ru…" 6 hours ago Exited (0) 6 hours ago ecstatic_lewin
# 6ae1e6519b0f todo-flask-v2 "python3 -m flask ru…" 7 hours ago Exited (0) 6 hours ago priceless_elion
# 114bfd201f11 be7f076f4fb1 "/bin/sh -c 'pip ins…" 7 hours ago Exited (2) 7 hours ago sad_cohen
# c7fd7173cf09 ubuntu "/bin/bash" 44 hours ago Exited (0) 43 hours ago amazing_thompson
Docker Inspect
Docker inspect will provide all information about your docker container in JSON format.
# docker inspect <container_id>
# docker inspect <container_name>
docker inspect 6970 # we can use the first few characters that makes the container id unique instade of using the whole id
and the list of info goes on, and on...
Let this file be a little human-readable
# if you don't have jq install it using
sudo apt install jq
docker inspect amazing_thompson | jp
How do we keep it keep running?
The process that the container starts with MUST be one that can run indefinitely
docker run -it ubuntu /bin/bash
-i, --interactive Keep STDIN open even if not
-t, --tty Allocate a pseudo-TTY
-d, --detach Run container in the background
Containers Controlling
Create
# docker create <image_name/id>
docker create ubuntu
# 82b7efdb8b21753776208011090b033b0842257fa56169f65d0de597df00b1d9
creates the docker container from the given image, but does not run it!
Start
# docker start <container_id/name>
docker start 82b7ef
this will actually start the container.
Run
# docker run <image_name/id>
docker run ubuntu
docker run
command is something like an alias for
docker start $(docker create ubuntu)
Pause
# docker pause <container_id/name>
docker pause 82b7ef
This will stop a running container but will not make it exit i.e. change its state from up to paused
Unpause
# docker pause <container_id/name>
docker unpause 82b7ef
This will start a paused container i.e. change it's state from paused to up
Stop
# docker stop <container_id/name>
docker stop 82b7ef
This will stop a running container i.e. change it's state from up to exited
stop is the gentle way of stopping a container, it's like asking the container politely "Can you exit please?", it's the same as pressing Ctrl+C
The main process inside the container will receive SIGTERM
Kill
# docker kill <container_id/name>
docker kill 82b7ef
This will force a running container to exit i.e. change its state from up to exited
Remember saying about the stop command it's the polite way? well, kill is the un-respectful one.
The main process inside the container will receive SIGKILL
Delete a Container
Guess the command name!
YES, you guessed it right, rm!
# docker rm <container_id>
docker rm 82b7ef
Why should we delete a container?
Stopped containers remain on the system and take up space. You can remove these.
TO REMOVE A CONTAINER IT MUST BE STOPPED.
here is a trick to remove all containers in a one-liner
docker rm $(docker ps -aq --filter "status=exited")
# $() starts a sub-shell
# -a means all the containers
# -q means quite mode -> outputs only the containers ids
# -f, --filter "key=value filter" -> filters the containers based on the filter
# "status=exited" -> apply ( get only the exited containers ) as the filter for --filter
Mapping Exposed Ports
let's say the web application you're trying to dockerize uses port 80, how will you be able to preview the web app if the container is completely isolated from the host system?
Mapping ports are the answer!
We will map the port from the container to the host port we want
The Flask web app runs on port 5000 so because I have nothing running on port 5000 I will map it to the same port, but I could map it to any other unused port
# docker run -p <host_port>:<container_port> <image_name/id>
# maps these specific ports to each other
docker run -p 5000:5000 todo-flask-v2
let's say my app uses a lot of ports, so I want to map all of them at once!
# docker run -P <image_name/id>
docker run -P todo-flask-v2
this will map all exposed ports in the container to random unused ports in the host machine
Docker Exec
we can execute commands against a container using the exec command
# docker exec <conatiner_id/name> command
docker exec -it inspiring_dirac ls
this will execute the command ls inside the container inspiring_dirac and print the output in STDOUT
So can we log into a container?
Well yes, but not really!
think about it, now we can execute commands inside the container, and /bin/bash is a command, right? So we can get a shell session and walk around inside the container!
for example
# lets run an ubuntu container
docker run -itd ubuntu
# c7fd7173cf0921af911bfceacd074ff47b9f8c3bbe90823114570088bd9034da
docker exec -it 6aeb /bin/bash # or we can simply use bash
docker exec -it <container_id/name> <command>
TASK
Play around with docker images and container
pull some images Ubuntu image for example or Nginx
display all images
choose an image and run it (try to detach it once and once don't)
run any image, Ubuntu for example
make it last ( execute a command that will keep the container up and running )
login into the container in the interactive mode
play around
exit the container
display all running containers
stop your container using its id
display all containers
remove your container using it's name