193 lines
4.7 KiB
Markdown
193 lines
4.7 KiB
Markdown
![]() |
---
|
||
|
tags: [docker, containerization]
|
||
|
---
|
||
|
|
||
|
# Docker containers
|
||
|
|
||
|
## Launch a container
|
||
|
|
||
|
We launch a container by running, e.g
|
||
|
|
||
|
```sh
|
||
|
docker run hello-world
|
||
|
```
|
||
|
|
||
|
Docker looks for the `hello-world` image in order to start the container. If it
|
||
|
cannot find it, it will fetch the image from DockerHub.
|
||
|
|
||
|
(`docker run` assumes you are saying "run image in container" but you can
|
||
|
specify other Docker objects such as networks.)
|
||
|
|
||
|
The `docker run` command is actually a composite of the following two commands:
|
||
|
|
||
|
```sh
|
||
|
docker create --name [my_container_name] hello-world
|
||
|
docker start [my_container]
|
||
|
```
|
||
|
|
||
|
Here is an applied example:
|
||
|
|
||
|
```
|
||
|
docker run --name my-container debian /bin/echo "Hello, world"
|
||
|
```
|
||
|
|
||
|
This creates and runs a container from the Debian image and executes `/bin/echo`
|
||
|
inside of it. Once you have run the above line, if the process is successful it
|
||
|
will exit. The container will stop running but it will remain in memory. Nothing
|
||
|
will be output (no "Hello, world"), because when you run it, you are _outside_
|
||
|
of the container.
|
||
|
|
||
|
## Launch a container as a daemon
|
||
|
|
||
|
You can also run a container as a [daemon](). In this mode, the container will
|
||
|
run in the background and detach from the console. For example:
|
||
|
|
||
|
```sh
|
||
|
docker run -d debian /bin/sh -c /bin/sh -c "while true; do echo 'Hello!'; sleep 1; done"
|
||
|
```
|
||
|
|
||
|
Inside the container, this will echo "Hello!" every second in an infinite loop
|
||
|
whilst the daemon is active.
|
||
|
|
||
|
The above command will not actually output anything. Instead it wil ouput the
|
||
|
container ID, e.g:
|
||
|
|
||
|
```
|
||
|
2749d796cbd64e9cf57307329e792587c39d8244f2377e62d78f3f3f77eecdb4
|
||
|
```
|
||
|
|
||
|
You can use this to access the log for the container. When you do so, you will
|
||
|
then see the output:
|
||
|
|
||
|
```sh
|
||
|
docker log 2749
|
||
|
hello
|
||
|
hello
|
||
|
hello
|
||
|
...
|
||
|
```
|
||
|
|
||
|
(We could also use the container name to reference the container, if we launched
|
||
|
it with the `--name` param.)
|
||
|
|
||
|
## Stopping a container
|
||
|
|
||
|
```
|
||
|
docker stop 2749
|
||
|
```
|
||
|
|
||
|
There will be a delay because it shuts down gracefully. It sends a SIGINT to the
|
||
|
process in the container with PID 1 (i.e the root or parent process for the
|
||
|
container).
|
||
|
|
||
|
`stop` will keep the container in memory. This means you can still refer bak to
|
||
|
the logs and that it can be restarted.
|
||
|
|
||
|
Instead of `stop`, if you were to use:
|
||
|
|
||
|
```
|
||
|
docker rm 2749
|
||
|
```
|
||
|
|
||
|
The container will be stopped and deleted. The logs are deleted and the
|
||
|
container cannot be recovered.
|
||
|
|
||
|
We can also tell Docker to immediately remove a container after it exits:
|
||
|
|
||
|
```
|
||
|
docker run --rm [image]
|
||
|
```
|
||
|
|
||
|
## Interacting with containers
|
||
|
|
||
|
In the examples so far the container is a closed box. You don't have a terminal
|
||
|
through which you can interact with the container as you would with an OS. You
|
||
|
can only start the container and view its activities by accessing the logs.
|
||
|
|
||
|
For images that have an OS we can use `-i -t` to launch a terminal in
|
||
|
interactive mode.
|
||
|
|
||
|
```sh
|
||
|
docker run -i -t debian /bin/bash
|
||
|
root@0022da12f2f2:/# ls
|
||
|
bin boot dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
|
||
|
root@0022da12f2f2:/# whoami
|
||
|
root
|
||
|
root@0022da12f2f2:/# ls usr/
|
||
|
bin games include lib libexec local sbin share src
|
||
|
```
|
||
|
|
||
|
Note that it defaults to the root user.
|
||
|
|
||
|
Containers are lightweight and should only contain the minium environment needed
|
||
|
to run an application. For this reason OSs that are included in an image are
|
||
|
often very stripped-back and many programs and processes will not be there by
|
||
|
default. (Although you could install a package manager and install the commands
|
||
|
you need.)
|
||
|
|
||
|
The previous command launches the container and enters into it with a terminal.
|
||
|
If a container is already running, you can enter into it in terminal mode with
|
||
|
`exec`:
|
||
|
|
||
|
```
|
||
|
docker exec -i -t my_container bash
|
||
|
```
|
||
|
|
||
|
If a container is running in detached mode we can attach to the main process
|
||
|
with `docker attach`
|
||
|
|
||
|
```
|
||
|
docker attach my_container
|
||
|
```
|
||
|
|
||
|
## Container lifecycle
|
||
|
|
||
|

|
||
|
|
||
|
All containers have a lifecycle represented by five distinct states. Each state
|
||
|
has an associated command:
|
||
|
|
||
|
- created
|
||
|
- `docker create`, `docker run`
|
||
|
- running
|
||
|
- paused
|
||
|
- `docker pause`, `docker unpause`
|
||
|
- stopped
|
||
|
- `docker stop`, `docker kill`
|
||
|
- removed
|
||
|
- `docker rm`
|
||
|
|
||
|
## Main container commands
|
||
|
|
||
|
```sh
|
||
|
docker create # create container from image
|
||
|
docker run # create and start container from image
|
||
|
docker run --name # add custom name for container
|
||
|
docker ps # list currently active containers
|
||
|
docker ps -a # list all containers (inactive and active)
|
||
|
docker logs # display a container log
|
||
|
docker stop # stop a running container
|
||
|
docker start # starts a stopped (exited) container
|
||
|
docker rm # remove a stopped (exited) container
|
||
|
```
|
||
|
|
||
|
## Container troubleshooting
|
||
|
|
||
|
Lots of diagnostic output:
|
||
|
|
||
|
```
|
||
|
docker inspect container_name
|
||
|
```
|
||
|
|
||
|
List processes (from outside):
|
||
|
|
||
|
```
|
||
|
docker top container_name
|
||
|
```
|
||
|
|
||
|
View logs
|
||
|
|
||
|
```
|
||
|
docker logs container_name
|
||
|
```
|