<style>
.present {
text-align: left;
}
</style>
# Docker Container CLI
## Week 19 Day 2
---
## Lecture Videos 1 (15 minutes)
Watch:
- Container Intro (12:00)
---
### `docker container run` ([Official documentation](https://docs.docker.com/engine/reference/commandline/container_run/))
Usage:
```shell
docker container run [OPTIONS] image-name [COMMAND] [ARG...]
```
- You always need to specify the image—__every container is based on an image__.
- The optional "OPTIONS" are specified with a flag.
- Any options you include will come before the image name
- Each image has a default command—that will be replaced if you specify a new command (after the image-name)
---
#### Commonly used flags for `docker container run`:
| flag | purpose | example usage |
| -------- | -------- | -------- |
| `--name` | specify a name for the container | `--name hello` |
| `-p` / `--publish` | expose a port to localhost (externalport:internalport) | `-p 8080:80` |
| `-d` | detached session (runs in background) | `-d` |
| `--rm` | automatically remove container once stopped | `--rm` |
| `-it` | use an interactive session (e.g. bash) | `-it` / `-i -t` |
---
### Pop quiz
1. Let's run a container based on the *nginx* image, in detached mode. We want to publish the contents of that container's internal port 80, to my localhost at port 8080.
2. Let's run a container based on the *alpine* image and name it "juice". We want to run it with an interactive terminal, and use the command `sh`.
3. Let's run a container based on the *ubuntu* image and name it "greet_doggo". We want the container to be removed automatically once it is stopped. Let's have it use the command `echo hi juice`.
---
### Pop quiz (answer key)
1.
```bash
docker container run -p 8080:80 -d nginx
```
2.
```bash
docker container run -it --name juice alpine sh
```
3.
```bash
docker container run --name greet_doggo --rm ubuntu echo hi juice
```
---
### `docker container ls` ([Official documentation](https://docs.docker.com/engine/reference/commandline/container_ls/))
Purpose: list containers (can be used interchangeably with `docker ps`)
- `-a` flag includes stopped containers
Usage:
```bash
docker container ls [OPTIONS]
```
---
### `docker container stop` ([Official documentation](https://docs.docker.com/engine/reference/commandline/container_stop/))
Purpose: stop a container (or containers) that is currently running.
Usage:
```bash
docker container stop [OPTIONS] CONTAINER [CONTAINER...]
```
---
### `docker container start` ([Official documentation](https://docs.docker.com/engine/reference/commandline/container_start/))
Purpose: start a stopped container (or containers)
- this will not create a new container, the container must already exist
Usage:
```bash
docker container start [OPTIONS] CONTAINER [CONTAINER...]
```
---
### `docker container rm` ([Official documentation](https://docs.docker.com/engine/reference/commandline/container_rm/))
Purpose: remove a container
- by default you can only remove stopped containers
- `-f` flag forces removal even if container is running
Usage:
```
docker container rm [OPTIONS] CONTAINER [CONTAINER...]
```
---
### `docker container prune` ([Official documentation](https://docs.docker.com/engine/reference/commandline/container_prune/))
Purpose: remove all stopped containers
Usage:
```
docker container prune [OPTIONS]
```
---
### `docker container exec` ([Official documentation](https://docs.docker.com/engine/reference/commandline/exec/))
Purpose: execute a command within a running container
- often useful for opening interactive shell (uses same `-it` flag as container run)
```
docker container exec [OPTIONS] CONTAINER COMMAND [ARG...]
```
---
## Lecture Videos 2 (10 minutes)
Watch:
- Docker Networking (8:30)
---
### Docker networks
Networks allow containers to communicate with each other, whether or not they are exposing ports to the host.
[Official documentation](https://docs.docker.com/network/)
---
### What _is_ a network?
---
### Networking with Docker
By default, containers are connected to the "bridge" network.
However, that network won't allow containers to communicate with one another—by default, containers are isolated.
---
### Creating custom networks ([Official documentation](https://docs.docker.com/engine/reference/commandline/network_create/))
Creating a custom network will allow the containers on that network to interact with each other.
```bash
docker network create [OPTIONS] network-name
```
```bash
docker network ls
```
---
### Networking demo [1/2]
Let's create a network, and attach containers to it so we can see how networked containers communicate.
For comparison, we'll use two containers that are on the default network.
```bash
# create a network based on the bridge driver, called "test-network"
docker network create --driver bridge test-network
# create two images on that network
docker container run -d --name c1 --network test-network nginx:alpine
docker container run -d --name c2 --network test-network nginx:alpine
# create two more images, without specifying a network
docker container run -d --name c3 nginx:alpine
docker container run -d --name c4 nginx:alpine
```
---
### Networking demo [1/2]
```bash
# access the shell on one of our two networked containers
docker container exec -it c1 ash
# ping a container that is not on the network
ping -c 2 c3
# ping a container that is on the network
ping -c 2 c2
docker container exec -it c3 ash
ping -c 2 c1
ping -c 2 c4
```
---
## Lecture videos 3 (20 minutes)
Watch:
- Persistant Data in Docker: Bind Mounts (9:00)
- Persistant Data in Docker: Volumes (8:30)
---
### Docker volumes/bind mounts
Using bind mounts and volumes allows data to persist even after a container is gone.
Bind mounts directly mount the contents of a folder on your filesystem into your container.
Volumes are managed by Docker—so you wouldn't directly access the files, but can be accessed and modified from within a container.
---
### Options for creating volumes/bind mounts
There are two different types of syntax you can use with `docker container run` to establish volumes and bind mounts. Both flags can create either volumes or bind mounts.
- `-v` and `--mount` flags have the same purpose.
- `--mount` is typically preferred as it is considered to be clearer.
```bash
docker container run -v ...
docker container run --mount ...
```
---
### `-v`/`--volume` syntax
- Pass in the fields separated by a colon
- Order matters
- Docker will infer whether you want to use a bind mount or a volume based on whether the first field is a path or not
---
### `-v`/`--volume` syntax
#### For bind mounts
- First field is the path to the file or directory on the host machine.
- Second field is the path to where it is mounted in the container.
- Third field for additional options.
```
-v absolute/path:/absolute/path/in/container
```
---
### `-v`/`--volume` syntax
#### For volumes
- First field is name of the volume (can be skipped for an anonymous volume)
- Second field is the path to where it is mounted in the container
- Third field for additional options.
```
-v name:/absolute/path/in/container
```
---
### `--mount` syntax
Pass in a series of `<key>=<value>` pairs in any order, separated by a comma.
Type must be "bind" for bind mounts, or "volume" for volumes
---
### `--mount` syntax
#### for bind mounts
```
--mount type=bind,source=/absolute/path,target=/absolute/path/in/container
```
#### for volumes
```
--mount type=volume,source=name_of_volume,target=/absolute/path/in/container
```
---
### Bind mounts
[Official documentation](https://docs.docker.com/storage/bind-mounts/)
- Bind mounts connect a folder in your file system to a folder on your container
- Convenience in simple cases—any changes made in one place will change what's present in the other
---
### Demo: Serve a Website [1/2]
First, create a folder called __app__ in your current directory, and make an empty __index.html__ file inside the folder.
```bash=
# run an nginx:alpine-based container, in detached mode
# mount the /app folder into the container at the path where nginx serves
# its files from (/usr/share/nginx/html)
# and expose port 80 to view the contents
docker container run -d \
--mount type=bind,source="$(pwd)/app",target=/usr/share/nginx/html \
-p 8080:80 nginx:alpine
```
---
### Demo: Serve a Website [2/2]
Once your container is running, visit localhost:8080—you should see a blank page. Add some content to your html page, then save and refresh localhost:8080. Now you can see the new content you added, because the contents of your folder stays in sync with the contents of the folder inside your container.
---
### Volumes
[Official documentation](https://docs.docker.com/storage/volumes/)
Volumes are managed from within Docker—don't depend on your file structure.
You wouldn't modify the contents directly (only from inside a container), but you can use it to spin up new containers with same contents.
Instead of providing a path to the folder (like you would with a bind mount) you can provide the name of the volume.
---
### Demo: Persist data from a postgres instance that runs in a container
```bash=
# pull the postgres image so we can inspect it
docker pull postgres
# inspect the image to find out what the path to the volume should be
# and what port we want to expose
docker image inspect postgres
```
---
### Demo: Persist data from a postgres instance that runs in a container
```bash=
# run the container (no volume)
docker container run -p 5431:5432 \
-e POSTGRES_PASSWORD=password \
--name postgres5431 -d postgres
# run the container with a volume named "postgres-data"
# that corresponds to the path where a postgres container stores its data (/var/lib/postgresql/data)
docker container run -p 5431:5432 \
-e POSTGRES_PASSWORD=password \
--name postgres5431 -d \
--mount type=volume,source=postgres-data,target=/var/lib/postgresql/data postgres
# now use the psql command line tool to connect
# to the postgres instance running in our container
psql -p 5431 -h localhost -U postgres -W
```
{"metaMigratedAt":"2023-06-16T02:32:51.809Z","metaMigratedFrom":"Content","title":"Docker Container CLI","breaks":"true","contributors":"[{\"id\":\"b3d4b64b-bcb9-47ce-975c-f84011d6c2f4\",\"add\":10210,\"del\":0}]"}