Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,102 +1,106 @@
# Prerequisites

# Prereqs
Ensure you have cloned or downloaded the course GitHub repository to your local machine.

Make sure you have the course github repo cloned/downloaded to your local machine.

Locate the `build-a-simple-containerized-application` folder in the course repo.
Locate the `build-a-simple-containerized-application` folder in the course repository.

# Application 1 - 2048

![2048-diagram](files/2048-game.png)
*Diagram shows the flow - from the Dockerfile to the fun playing game!*
*Diagram shows the flow - from the Dockerfile to the fun playing game!*

## Creating a 2048 Docker Image

Move into the `app1-2048` folder.
open the `Dockerfile` in a text editor of choice.
Notice how there are `5` lines .. FROM, LABEL, COPY, EXPOSE and CMD. When you build the docker image in the next step, pay attention to how many layers are created in the image.
- Move into the `app1-2048` folder.
- Open the `Dockerfile` in a text editor of your choice.
- Notice how it contains `5` lines: `FROM`, `LABEL`, `COPY`, `EXPOSE`, and `CMD`. When you build the Docker image in the next step, pay attention to how many layers are created.

This Dockerfile uses the latest version of the `nginx` image (which includes a configured installation of NGINX).
This Dockerfile uses the latest version of the `nginx` image (which includes a pre-configured installation of NGINX).

https://hub.docker.com/_/nginx
[https://hub.docker.com/_/nginx](https://hub.docker.com/_/nginx)

It sets metadata `maintainer`. It then copies all of the `2048/` folder from the localdocker host/client machine into the `/usr/share/nginx/html` folder within the image.
It sets the metadata `maintainer`. It then copies all of the `2048/` folder from the local Docker host/client machine into the `/usr/share/nginx/html` folder within the image.

Finally we use the `EXPOSE` directive to inform uses of this image that the appplication is running on `tcp/80` and use the `CMD` statement to set the initial process for containers running from this image.
Finally, we use the `EXPOSE` directive to inform users of this image that the application is running on `tcp/80` and use the `CMD` statement to set the initial process for containers running from this image.

To build the image, from the `app1-2048` folder we run the docker build command. We use `-t` to tag the image with `2048` and use `.` to set the working directory for the command. ANy paths specified in the dockerfile will use `.` as the starting point ..the working directory.
To build the image, from the `app1-2048` folder, we run the Docker build command. We use `-t` to tag the image with `dockerized-2048` and use `.` to set the working directory for the command. Any paths specified in the Dockerfile will use `.` as the starting point, which is the working directory.

```docker build -t dockerized-2048 .```
```sh
docker build -t dockerized-2048 .
```

Notice how 2 layers are created in the docker image.
Notice how 2 layers are created in the Docker image:

- The first layer is the base image `nginx:latest`.
- The last layer is created based on the `COPY` statement to copy in the application files from `./2048`.
- The first layer is the base image `nginx:latest`.
- The last layer is created based on the `COPY` statement to copy in the application files from `./2048`.

## Running a 2048 Docker Container

Run a `docker images` to show all images on the Docker Host.
Locate the `dockerized-2048` image which you just created.
This image, is running an application using `tcp/80` so we need to use the `-p` CLI option to run this on an alternative docker host post (this will be discussed in detail later in the course).
Run `docker images` to show all images on the Docker Host. Locate the `dockerized-2048` image you just created. This image is running an application using `tcp/80`, so we need to use the `-p` CLI option to run this on an alternative Docker host port (this will be discussed in detail later in the course).

Run a docker container of 2048 using
Run a Docker container of 2048 using:

`docker run -d -p 8081:80 dockerized-2048`
```sh
docker run -d -p 8081:80 dockerized-2048
```

this will run in detached mode, so your terminal should return to the prompt immediately.
This will run in detached mode, so your terminal should return to the prompt immediately.

Verify the container is running with `docker ps`. Confirm the port mapping with `docker port <CONTAINERID>`.
Verify the container is running with `docker ps`. Confirm the port mapping with `docker port <CONTAINERID>`.

Browse to `http://localhost:8081`
Browse to `http://localhost:8081`.

Play the game :)

## Cleanup

Run a `docker stop <CONTAINERID>` to stop the 2048 container app.
Run a `docker rm <CONTAINERID>` to remove the 2048 container.
Run `docker stop <CONTAINERID>` to stop the 2048 container app. Run `docker rm <CONTAINERID>` to remove the 2048 container.

# Application 2 - Container of Cats

This dockefile is intentionally less efficient than app1 above. I want you to understand WHY it's less efficient.
This Dockerfile is intentionally less efficient than app1 above. I want you to understand WHY it's less efficient.

## Creating a Container of Cats Docker Image

Move into the `app2-containerofcats` folder.
open the `Dockerfile` in a text editor of choice.
- Move into the `app2-containerofcats` folder.
- Open the `Dockerfile` in a text editor of your choice.

Let's review this `Dockerfile` and specifically identify how it's different from the previous `app1`.

Let's review this `Dockerfile` and specifically identify how it's different from the previous `app1`.
- First, it uses a different base image. Instead of `nginx:latest`, which is specifically designed for simple `nginx` web use-cases, this uses `ubi8`, which is a universal Red Hat 8 image (general purpose).
- This image is also larger than other lean images such as `alpine` and `nginx`.
- Because this is a general-purpose image, we have to install a web server (apache2) in this case via the `RUN` statement. This creates a layer.
- Next, there are 2 `COPY` statements which copy in `index.html` and `containerandcat*.jpg` media files into the image. These two statements create _2_ additional layers.

- First, it uses a different base image. Instead of `nginx:latest` which is specifically designed for simple `ngnix` web use-cases, this uses `ubi8` which is a universal redhat 8 image (general purpose)
- This image is also larger than other lean image such as `alpine` and `nginx`.
- Because this is a general purpose image, we have to install a web server (apache2) in this case via the `RUN` statement. This creates a layer.
- Next, there are 2 x `COPY` statements which copy in `index.html` and `contaierandcat*.jpg` media files into the image. These two statements create _2_ additional layers.
This Dockerfile and resultant image are more generalized. This results in a larger image and containers which consume more resources.

This dockerfile and resultant image are more generalised. This results in a larger image, and containers which consume more resources.
To create a Docker image for the `containerofcats` application, we run this command:

To create a docker image for the `containerofcats` dockerized application we run this command.
```sh
docker build -t containerofcats .
```

```docker build -t containerofcats .```
*Notice how much longer it takes to create, compared to the 2048 image, even though it's a similar architecture: a web server & some files.*

*notice how much longer it takes to create, vs the 2048 image, even though it's a similar architecture .. web server & some files*
## Running a Containerofcats Docker Container

## Running a containerofcats Docker Container
Run `docker images` to show all images on the Docker Host. Locate the `containerofcats` image you just created. This image is running an application using `tcp/

Run a `docker images` to show all images on the Docker Host.
Locate the `containerofcats` image which you just created.
This image, is running an application using `tcp/80` so we need to use the `-p` CLI option to run this on an alternative docker host post (this will be discussed in detail later in the course).
80`, so we need to use the `-p` CLI option to run this on an alternative Docker host port (this will be discussed in detail later in the course).

Run a docker container of containerofcats using
Run a Docker container of containerofcats using:

`docker run -d -p 8081:80 containerofcats`
```sh
docker run -d -p 8081:80 containerofcats
```

this will run in detached mode, so your terminal should return to the prompt immediately.
This will run in detached mode, so your terminal should return to the prompt immediately.

Verify the container is running with `docker ps`. Confirm the port mapping with `docker port <CONTAINERID>`.
Verify the container is running with `docker ps`. Confirm the port mapping with `docker port <CONTAINERID>`.

Browse to `http://localhost:8081`
Browse to `http://localhost:8081`.

## Cleanup

Run a `docker stop <CONTAINERID>` to stop the containerofcats container app.
Run a `docker rm <CONTAINERID>` to remove the containerofcats container.
Run `docker stop <CONTAINERID>` to stop the containerofcats container app. Run `docker rm <CONTAINERID>` to remove the containerofcats container.

43 changes: 19 additions & 24 deletions docker-compose/instructions.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@

# Docker Compose

Docker compose is a way to create and manage multi-container applications. It works using a YAML configuration file called `compose.yaml` or `docker-compose.yml`.
Docker Compose is a way to create and manage multi-container applications. It works using a YAML configuration file called `compose.yaml` or `docker-compose.yaml`.

Generally using docker compose is a multi-step process:
Generally, using Docker Compose is a multi-step process:

- Define each of your containers using a `Dockerfile`
- Push those containers to a repository
- Define a docker compose file
- use the file via the `docker compose` command.
- Define each of your containers using a `Dockerfile`.
- Push those containers to a repository.
- Define a Docker Compose file.
- Use the file via the `docker compose` command.

This is an example `compose.yaml` file.
This is an example `compose.yaml` / `docker-compose.yaml` file.

```
```yaml
services:
db:
image: mariadb:10.6.4-focal
Expand Down Expand Up @@ -45,26 +44,22 @@ volumes:
wordpress_data:
```

It defines two containers `db` and `wordpress` both defined under `services:`. It also defines two named volumes `mariadb_data` and `wordpress_data`, which are created outside of the lifecycle of any one container and can be referenced by the containers defined within the compose file, in this example `db`.
It defines two containers, `db` and `wordpress`, both defined under `services:`. It also defines two named volumes, `mariadb_data` and `wordpress_data`, which are created outside of the lifecycle of any one container and can be referenced by the containers defined within the compose file, in this example, `db`.

Go ahead and create a file in your current working folder called `compose.yaml` and paste in the above contents. Then to use this file run a `docker compose up -d`. `up` is how we tell docker compose to bring up the things defined in the file, and `-d` directs compose to run in detached mode (which works in the same way as it does it containers).
Go ahead and create a file in your current working folder called `compose.yaml` and paste in the above contents. Then to use this file, run a `docker compose up -d`. `up` is how we tell Docker Compose to bring up the things defined in the file, and `-d` directs compose to run in detached mode (which works in the same way as it does in containers).

browse to ```http://localhost:8081``` and complete the installation process of wordpress. You will need to select a language, click next, set a site title `All the cats`, set an admin user `admin`, note down the auto generated password (you will need this a few times), enter your email and click `Install Wordpress`.
Browse to `http://localhost:8081` and complete the installation process of WordPress. You will need to select a language, click next, set a site title `All the cats`, set an admin user `admin`, note down the auto-generated password (you will need this a few times), enter your email, and click `Install WordPress`.

Then ..Login, Click `posts` then `Add new` and create a new post with some images, use the `+` to add a gallery, then add some test images, the details don't matter. Click `publish` and then `publish` again. Then click `view post` & make sure you can see the site ok...
Then...Login, Click `posts` then `Add new` and create a new post with some images, use the `+` to add a gallery, then add some test images, the details don't matter. Click `publish` and then `publish` again. Then click `view post` & make sure you can see the site ok...

Run a ```docker compose down``` to stop all the containers and then do a, ```docker ps -a```, notice the containers are fully removed?
run a ```docker volume ls``` and note how the named volumes still exist?

The containers just created by docker compose are now gone.
Run a ```docker compose up -d``` .. and watch what compose does, it only recreates what's missing. Docker compose is smart enough to always create what's required to make what is container in the docker compose file `true` whether that means creating everything in it, or just a small section.
browse to ```http://localhost:8081``` and notice how the install is finished ? no configuration is needed ? and you see your blog post? that's because the named volumes are used, which contain the database and the image data from wordpress. Even though the containers were deleted and recreated the data persisted because it's stored in volumes which exist outside of the lifecycle of the container.
Run a `docker compose down` to stop all the containers and then do a, `docker ps -a`, notice the containers are fully removed?
Run a `docker volume ls` and note how the named volumes still exist?

The containers just created by Docker Compose are now gone.
Run a `docker compose up -d`... and watch what compose does, it only recreates what's missing. Docker Compose is smart enough to always create what's required to make what is contained in the Docker Compose file `true`, whether that means creating everything in it, or just a small section.
Browse to `http://localhost:8081` and notice how the install is finished? No configuration is needed? And you see your blog post? That's because the named volumes are used, which contain the database and the image data from WordPress. Even though the containers were deleted and recreated, the data persisted because it's stored in volumes that exist outside of the lifecycle of the container.

# Cleanup

Run a `docker compose down` to stop and delete any containers.
Run a `docker volume ls` to list all volumes and delete the named ones created by compose using `docker volume rm <VOLNAME>`



Run a `docker compose down` to stop and delete any containers.
Run a `docker volume ls` to list all volumes and delete the named ones created by compose using `docker volume rm <VOLNAME>`
Loading