Docker
Table of contents
- Docker overview
- The Docker platform
- Docker architecture
- The underlying technology
- Docker Commands, Help & Tips
- Working With Containers
- Create an run a container in foreground
- Create an run a container in background
- Shorthand
- Naming Containers
- Tip: What Run Did
- List running containers
- List all containers (Even if not running)
- Stop container
- Stop all running containers
- Remove container (Can not remove running containers, must stop first)
- To remove a running container use force(-f)
- Remove multiple containers
- Remove all containers
- Get logs (Use name or ID)
- List processes running in container
- Image Commands
- List the images we have pulled
- We can also just pull down images
- Remove image
- Remove all images
- Some sample container creation
- Container Info
- Accessing Containers
- Networking
- Image Tagging & Pushing To Dockerhub
- Extending Dockerfile
- Volumes
- Volume - Makes special location outside of container UFS. Used for databases
- Bind Mount -Link container path to host path
- Check volumes
- Cleanup unused volumes
- Pull down mysql image to test
- Inspect and see volume
- Run container
- Inspect and see volume in container
- Check volumes
- Named volumes (Add -v command)(the name here is mysql-db which could be anything)
- Inspect new named volume
- Bind Mounts
- Docker Compose
- Reference Links
Docker overview
Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production.
The Docker platform
Docker provides the ability to package and run an application in a loosely isolated environment called a container. The isolation and security allow you to run many containers simultaneously on a given host. Containers are lightweight and contain everything needed to run the application, so you do not need to rely on what is currently installed on the host. You can easily share containers while you work, and be sure that everyone you share with gets the same container that works in the same way.
Docker provides tooling and a platform to manage the lifecycle of your containers:
- Develop your application and its supporting components using containers.
- The container becomes the unit for distributing and testing your application.
- When you’re ready, deploy your application into your production environment, as a container or an orchestrated service. This works the same whether your production environment is a local data center, a cloud provider, or a hybrid of the two.
Docker architecture
Docker uses a client-server architecture. The Docker client talks to the Docker daemon, which does the heavy lifting of building, running, and distributing your Docker containers. The Docker client and daemon can run on the same system, or you can connect a Docker client to a remote Docker daemon. The Docker client and daemon communicate using a REST API, over UNIX sockets or a network interface. Another Docker client is Docker Compose, that lets you work with applications consisting of a set of containers.
The Docker daemon
The Docker daemon (dockerd) listens for Docker API requests and manages Docker objects such as images, containers, networks, and volumes. A daemon can also communicate with other daemons to manage Docker services.
The Docker client
The Docker client (docker) is the primary way that many Docker users interact with Docker. When you use commands such as docker run, the client sends these commands to dockerd, which carries them out. The docker command uses the Docker API. The Docker client can communicate with more than one daemon.
Docker Desktop
Docker Desktop is an easy-to-install application for your Mac or Windows environment that enables you to build and share containerized applications and microservices. Docker Desktop includes the Docker daemon (dockerd), the Docker client (docker), Docker Compose, Docker Content Trust, Kubernetes, and Credential Helper. For more information, see Docker Desktop.
Docker registries
A Docker registry stores Docker images. Docker Hub is a public registry that anyone can use, and Docker is configured to look for images on Docker Hub by default. You can even run your own private registry.
When you use the docker pull or docker run commands, the required images are pulled from your configured registry. When you use the docker push command, your image is pushed to your configured registry.
Docker objects
When you use Docker, you are creating and using images, containers, networks, volumes, plugins, and other objects. This section is a brief overview of some of those objects.
Images
An image is a read-only template with instructions for creating a Docker container. Often, an image is based on another image, with some additional customization. For example, you may build an image which is based on the ubuntu image, but installs the Apache web server and your application, as well as the configuration details needed to make your application run.
You might create your own images or you might only use those created by others and published in a registry. To build your own image, you create a Dockerfile with a simple syntax for defining the steps needed to create the image and run it. Each instruction in a Dockerfile creates a layer in the image. When you change the Dockerfile and rebuild the image, only those layers which have changed are rebuilt. This is part of what makes images so lightweight, small, and fast, when compared to other virtualization technologies.
Containers
A container is a runnable instance of an image. You can create, start, stop, move, or delete a container using the Docker API or CLI. You can connect a container to one or more networks, attach storage to it, or even create a new image based on its current state.
By default, a container is relatively well isolated from other containers and its host machine. You can control how isolated a container’s network, storage, or other underlying subsystems are from other containers or from the host machine.
A container is defined by its image as well as any configuration options you provide to it when you create or start it. When a container is removed, any changes to its state that are not stored in persistent storage disappear.
To summarize, a container:
- is a runnable instance of an image. You can create, start, stop, move, or delete a container using the DockerAPI or CLI.
- can be run on local machines, virtual machines or deployed to the cloud.
- is portable (can be run on any OS)
- Containers are isolated from each other and run their own software, binaries, and configurations.
Example docker run command
The following command runs an ubuntu container, attaches interactively to your local command-line session, and runs /bin/bash.
$ docker run -i -t ubuntu /bin/bash
When you run this command, the following happens (assuming you are using the default registry configuration):
If you do not have the ubuntu image locally, Docker pulls it from your configured registry, as though you had run docker pull ubuntu manually.
Docker creates a new container, as though you had run a docker container create command manually.
Docker allocates a read-write filesystem to the container, as its final layer. This allows a running container to create or modify files and directories in its local filesystem.
Docker creates a network interface to connect the container to the default network, since you did not specify any networking options. This includes assigning an IP address to the container. By default, containers can connect to external networks using the host machine’s network connection.
Docker starts the container and executes /bin/bash. Because the container is running interactively and attached to your terminal (due to the -i and -t flags), you can provide input using your keyboard while the output is logged to your terminal.
When you type exit to terminate the /bin/bash command, the container stops but is not removed. You can start it again or remove it.
The underlying technology
Docker is written in the Go programming language and takes advantage of several features of the Linux kernel to deliver its functionality. Docker uses a technology called namespaces to provide the isolated workspace called the container. When you run a container, Docker creates a set of namespaces for that container.
These namespaces provide a layer of isolation. Each aspect of a container runs in a separate namespace and its access is limited to that namespace.
Docker Commands, Help & Tips
Show commands & management commands
$ docker
Docker version info
$ docker version
Show info like number of containers, etc
$ docker info
Working With Containers
Create an run a container in foreground
$ docker container run -it -p 80:80 nginx
Create an run a container in background
$ docker container run -d -p 80:80 nginx
Shorthand
$ docker container run -d -p 80:80 nginx
Naming Containers
$ docker container run -d -p 80:80 --name nginx-server nginx
Tip: What Run Did
- Looked for image called nginx in image cache
- If not found in cache, it looks to the default image repo on Dockerhub
- Pulled it down (latest version), stored in the image cache
- Started it in a new container
- We specified to take port 80- on the host and forward to port 80 on the container
- We could do “$ docker container run –publish 8000:80 –detach nginx” to use port 8000
- We can specify versions like “nginx:1.09”
List running containers
$ docker container ls
OR
$ docker ps
List all containers (Even if not running)
$ docker container ls -a
Stop container
$ docker container stop [ID]
Stop all running containers
$ docker stop $(docker ps -aq)
Remove container (Can not remove running containers, must stop first)
$ docker container rm [ID]
To remove a running container use force(-f)
$ docker container rm -f [ID]
Remove multiple containers
$ docker container rm [ID] [ID] [ID]
Remove all containers
$ docker rm $(docker ps -aq)
Get logs (Use name or ID)
$ docker container logs [NAME]
List processes running in container
$ docker container top [NAME]
Tip: About Containers
Docker containers are often compared to virtual machines but they are actually just processes running on your host os. In Windows/Mac, Docker runs in a mini-VM so to see the processes youll need to connect directly to that. On Linux however you can run “ps aux” and see the processes directly
Image Commands
List the images we have pulled
$ docker image ls
We can also just pull down images
$ docker pull [IMAGE]
Remove image
$ docker image rm [IMAGE]
Remove all images
$ docker rmi $(docker images -a -q)
Tip: About Images
- Images are app bianaries and dependencies with meta data about the image data and how to run the image
- Images are no a complete OS. No kernel, kernel modules (drivers)
- Host provides the kernel, big difference between VM
Some sample container creation
NGINX:
$ docker container run -d -p 80:80 --name nginx nginx (-p 80:80 is optional as it runs on 80 by default)
APACHE:
$ docker container run -d -p 8080:80 --name apache httpd
MONGODB:
$ docker container run -d -p 27017:27017 --name mongo mongo
MYSQL:
$ docker container run -d -p 3306:3306 --name mysql --env MYSQL_ROOT_PASSWORD=123456 mysql
Container Info
View info on container
$ docker container inspect [NAME]
Specific property (–format)
$ docker container inspect --format '' [NAME]
Performance stats (cpu, mem, network, disk, etc)
$ docker container stats [NAME]
Accessing Containers
Create new nginx container and bash into
$ docker container run -it --name [NAME] nginx bash
- i = interactive Keep STDIN open if not attached
- t = tty - Open prompt
For Git Bash, use “winpty”
$ winpty docker container run -it --name [NAME] nginx bash
Run/Create Ubuntu container
$ docker container run -it --name ubuntu ubuntu
(no bash because ubuntu uses bash by default)
You can also make it so when you exit the container does not stay by using the -rm flag
$ docker container run --rm -it --name [NAME] ubuntu
Access an already created container, start with -ai
$ docker container start -ai ubuntu
Use exec to edit config, etc
$ docker container exec -it mysql bash
Alpine is a very small Linux distro good for docker
$ docker container run -it alpine sh
(use sh because it does not include bash) (alpine uses apk for its package manager - can install bash if you want)
Networking
“bridge” or “docker0” is the default network
Get port
$ docker container port [NAME]
List networks
$ docker network ls
Inspect network
$ docker network inspect [NETWORK_NAME]
("bridge" is default)
Create network
$ docker network create [NETWORK_NAME]
Create container on network
$ docker container run -d --name [NAME] --network [NETWORK_NAME] nginx
Connect existing container to network
$ docker network connect [NETWORK_NAME] [CONTAINER_NAME]
Disconnect container from network
$ docker network disconnect [NETWORK_NAME] [CONTAINER_NAME]
Detach network from container
$ docker network disconnect
Image Tagging & Pushing To Dockerhub
tags are labels that point ot an image ID
$ docker image ls
Youll see that each image has a tag
Retag existing image
$ docker image tag nginx btraversy/nginx
Upload to dockerhub
$ docker image push bradtraversy/nginx
If denied, do
$ docker login
Add tag to new image
$ docker image tag bradtraversy/nginx bradtraversy/nginx:testing
Dockerfile Parts
- FROM - The os used. Common is alpine, debian, ubuntu
- ENV - Environment variables
- RUN - Run commands/shell scripts, etc
- EXPOSE - Ports to expose
- CMD - Final command run when you launch a new container from image
- WORKDIR - Sets working directory (also could use ‘RUN cd /some/path’)
- COPY # Copies files from host to container
Build image from dockerfile (reponame can be whatever)
From the same directory as Dockerfile
$ docker image build -t [REPONAME] .
Tip: Cache & Order
- If you re-run the build, it will be quick because everythging is cached.
- If you change one line and re-run, that line and everything after will not be cached
- Keep things that change the most toward the bottom of the Dockerfile
Extending Dockerfile
Custom Dockerfile for html paqge with nginx
FROM nginx:latest # Extends nginx so everything included in that image is included here
WORKDIR /usr/share/nginx/html
COPY index.html index.html
Build image from Dockerfile
$ docker image build -t nginx-website
Running it
$ docker container run -p 80:80 --rm nginx-website
Tag and push to Dockerhub
$ docker image tag nginx-website:latest btraversy/nginx-website:latest
$ docker image push bradtraversy/nginx-website
Volumes
Volume - Makes special location outside of container UFS. Used for databases
Bind Mount -Link container path to host path
Check volumes
$ docker volume ls
Cleanup unused volumes
$ docker volume prune
Pull down mysql image to test
$ docker pull mysql
Inspect and see volume
$ docker image inspect mysql
Run container
$ docker container run -d --name mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=True mysql
Inspect and see volume in container
$ docker container inspect mysql
TIP: Mounts
- You will also see the volume under mounts
- Container gets its own uniqe location on the host to store that data
- Source: xxx is where it lives on the host
Check volumes
$ docker volume ls
There is no way to tell volumes apart for instance with 2 mysql containers, so we used named volumes
Named volumes (Add -v command)(the name here is mysql-db which could be anything)
$ docker container run -d --name mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=True -v mysql-db:/var/lib/mysql mysql
Inspect new named volume
docker volume inspect mysql-db
Bind Mounts
- Can not use in Dockerfile, specified at run time (uses -v as well)
- … run -v /Users/brad/stuff:/path/container (mac/linux)
- … run -v //c/Users/brad/stuff:/path/container (windows)
TIP: Instead of typing out local path, for working directory use $(pwd):/path/container - On windows may not work unless you are in your users folder
Run and be able to edit index.html file (local dir should have the Dockerfile and the index.html)
$ docker container run -p 80:80 -v $(pwd):/usr/share/nginx/html nginx
Go into the container and check
$ docker container exec -it nginx bash
$ cd /usr/share/nginx/html
$ ls -al
You could create a file in the container and it will exiost on the host as well
$ touch test.txt
Docker Compose
- Configure relationships between containers
- Save our docker container run settings in easy to read file
- 2 Parts: YAML File (docker.compose.yml) + CLI tool (docker-compose)
1. docker.compose.yml - Describes solutions for
- containers
- networks
- volumes
2. docker-compose CLI - used for local dev/test automation with YAML files
Sample compose file (From Bret Fishers course)
version: '2'
# same as
# docker run -p 80:4000 -v $(pwd):/site bretfisher/jekyll-serve
services:
jekyll:
image: bretfisher/jekyll-serve
volumes:
- .:/site
ports:
- '80:4000'
To run
docker-compose up
You can run in background with
docker-compose up -d
To cleanup
docker-compose down