Skip to content

Commit 005753f

Browse files
Merge pull request #123 from UoMResearchIT/oct2025_review_FHA
Oct2025 review fha
2 parents 2873311 + e2dabaf commit 005753f

20 files changed

+1618
-45
lines changed

code/episodes/docker-compose-microservices.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ volumes:
5656
Image: Apperture Services: Showing a user accessing WhoAmI via the web portal, which is protected by Authelia, which authenticates against an LDAP server, which pulls user data from a Postgres database.
5757
## Combining Stacks
5858
```yml
59-
# SPUC docker-compose.yml
59+
# SPUC compose.yml
6060

6161
+ networks:
6262
+ apperture:

episodes/docker-cli-toolkit.Rmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Building our Docker CLI toolkit
3-
teaching: 99
4-
exercises: 99
3+
teaching: 40
4+
exercises: 0
55
---
66

77
Before we start to tackle Docker tasks that are only possible in the command line,

episodes/docker-compose-microservices.Rmd

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: And they lived happily ever after
3-
teaching: 99
4-
exercises: 99
3+
teaching: 10
4+
exercises: 0
55
---
66

77
::::::::::::::::::::::::::::::::::::::::::::::::::: objectives
@@ -52,7 +52,7 @@ It is maintained by the University of Manchester's Research IT team, and can eas
5252
`Apperture` is comprised primarily of a compose file.
5353
Just like we have been looking at!
5454

55-
The full `docker-compose.yml` file is available [on github](https://raw.githubusercontent.com/UoMResearchIT/apperture/refs/heads/main/docker-compose.yml).
55+
The full `compose.yml` file is available [on github](https://raw.githubusercontent.com/UoMResearchIT/apperture/refs/heads/main/docker-compose.yml).
5656
It is quite long, so we will reproduce a slimmed down version here.
5757

5858
```yml
@@ -105,15 +105,15 @@ volumes:
105105
lldap-postgres-data:
106106
```
107107
108-
This `docker-compose.yml` file is a little more complex than the ones we have been looking at so far, but it is still just a list of services and their configurations.
108+
This `compose.yml` file is a little more complex than the ones we have been looking at so far, but it is still just a list of services and their configurations.
109109

110110
You'll see some familiar things, like `image`, `ports`, `depends_on` (and `healthchecks`), `volumes`, and `environment`.
111111

112-
Notice the `image` field in the `services` section of the `docker-compose.yml` file.
112+
Notice the `image` field in the `services` section of the `compose.yml` file.
113113
Every service is using a pre-built Docker image from Docker Hub, straight off the shelf!
114114
This is the power of Docker Compose and microservices!
115115

116-
To get an idea of what is going on, let's draw a diagram of the services in the `docker-compose.yml` file.
116+
To get an idea of what is going on, let's draw a diagram of the services in the `compose.yml` file.
117117

118118
![](fig/docker_compose_apperture.png){alt='Apperture Services: Showing a user accessing WhoAmI via the web portal, which is protected by Authelia, which authenticates against an LDAP server, which pulls user data from a Postgres database.'}
119119

@@ -128,13 +128,13 @@ There is no reason we cannot combine the Apperture stack with the SPUC stack we
128128
This would allow us to protect our SPUC interface with the Apperture portal.
129129
An important addition! We need to ensure poachers cannot falsely record sightings of the rare yet valuable unicorns!
130130

131-
This can be achieved by making a couple of changes to the SPUC `docker-compose.yml` file.
131+
This can be achieved by making a couple of changes to the SPUC `compose.yml` file.
132132

133133
In our previous lesson, we learned about networks, which allow services to communicate with each other.
134134
Now we want join the networks of the SPUC and Apperture stacks so that they can communicate with each other.
135135

136136
```yml
137-
# SPUC docker-compose.yml
137+
# SPUC compose.yml
138138
139139
+ networks:
140140
+ apperture:

episodes/docker-compose.Rmd

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Using Docker Compose
3-
teaching: 99
4-
exercises: 99
3+
teaching: 60
4+
exercises: 0
55
---
66

77
::::::::::::::::::::::::::::::::::::::::::::::::::: objectives
@@ -11,7 +11,7 @@ exercises: 99
1111
::::::::::::::::::::::::::::::::::::::::::::::::::: questions
1212
- What is Docker Compose?
1313
- Why and when would I use it?
14-
- How can I translate my `docker run` commands into a `docker-compose.yml` file?
14+
- How can I translate my `docker run` commands into a `compose.yml` file?
1515
- How can I make containers communicate with each other?
1616
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
1717

@@ -39,8 +39,8 @@ Let's take a look at Docker Compose and see how it can help us run SPUC and SPUC
3939

4040
As an initial step, we will learn how to run a container using Docker Compose.
4141

42-
The first thing we need to do is create a `docker-compose.yml` file.
43-
All `docker-compose.yml` files start with `services:`.
42+
The first thing we need to do is create a `compose.yml` file.
43+
All `compose.yml` files start with `services:`.
4444
This is the root element under which we define the services we want to run.
4545
```yml
4646
services:
@@ -124,7 +124,7 @@ docker run -d --rm --name spuc_container -p 8321:8321 -v ./print.config:/spuc/co
124124

125125
There are a lot of flags here!
126126
Each of these flags has a corresponding key in Docker Compose.
127-
Lets order all the elements we want in a table, so we can see what we need to add to our `docker-compose.yml` file.
127+
Lets order all the elements we want in a table, so we can see what we need to add to our `compose.yml` file.
128128

129129
| Flag | Description |
130130
|-----------------------------------------------|---------------------------------------------------------|
@@ -273,7 +273,7 @@ docker compose up -d
273273

274274
You do not necessarily need to `down` your containers to update the configuration, Docker Compose can be *smart* like that.
275275

276-
You can update the `docker-compose.yml` file in your text editor and then run `docker compose up -d` to see the changes take effect.
276+
You can update the `compose.yml` file in your text editor and then run `docker compose up -d` to see the changes take effect.
277277

278278
**Warning**: This is not always foolproof! Some changes will require a rebuild of the container.
279279
It is also worth noting that Docker Compose does not *save* the status with which you started your services.
@@ -552,7 +552,26 @@ Let's go back to that.
552552

553553
## Building containers in Docker Compose
554554

555-
We could use the tag we used when we built the container to use that image.
555+
We could use the tag we used when we built the container to use that image:
556+
```yml
557+
services:
558+
spuc:
559+
image: spuc-stats # Use the image we built earlier
560+
container_name: spuc_container
561+
ports:
562+
- 8321:8321
563+
volumes:
564+
- ./print.config:/spuc/config/print.config
565+
- spuc-volume:/spuc/output
566+
- ./stats.py:/spuc/plugins/stats.py # Mounts the stats.py plugin
567+
environment:
568+
- EXPORT=true
569+
command: ["--units", "iulu"]
570+
571+
volumes:
572+
spuc-volume:
573+
```
574+
556575
However, this would mean that if we want to adjust our locally built container, we would have to rebuild it separately.
557576
558577
Instead, we can use the `build` key to tell Docker Compose to build the container if needed.
@@ -561,7 +580,7 @@ To do that, we use the `build` key instead of the `image` key:
561580
```yml
562581
services:
563582
spuc:
564-
# image: spuacv/spuc:latest
583+
# image: spuc-stats
565584
build: # Instead of using the 'image' key, we use the 'build' key
566585
context: . # Sets the build context (the directory in which the Dockerfile is located)
567586
dockerfile: Dockerfile # Sets the name of the Dockerfile
@@ -575,6 +594,9 @@ services:
575594
environment:
576595
- EXPORT=true
577596
command: ["--units", "iulu"]
597+
598+
volumes:
599+
spuc-volume:
578600
```
579601

580602
This tells docker compose to look for the Dockerfile in the current directory.
@@ -585,7 +607,7 @@ If we run `up`, Docker Compose will default to checking if the image exists and
585607
This is ok... unless we have made changes to the Dockerfile!
586608

587609
To ensure that the image is built, we can run `docker compose build`.
588-
This will build (all) the image(s) specified inside our `docker-compose.yml`.
610+
This will build (all) the image(s) specified inside our `compose.yml`.
589611
After building, we use the usual `up` command.
590612

591613
Alternatively, we can add the `--build` flag to the `up` command, which results in Docker building the image right before starting the container.
@@ -632,7 +654,7 @@ You should now have a container running with the stats plugin enabled!
632654

633655
#### Simpler Dockerfile
634656

635-
You may have noticed that we ended up *duplicating* most of the configuration from the Dockerfile within the `docker-compose.yml` file.
657+
You may have noticed that we ended up *duplicating* most of the configuration from the Dockerfile within the `compose.yml` file.
636658

637659
In reality, if we are using Docker Compose we do not need to bake in all of the configuration inside the Dockerfile.
638660
The only thing that was different was the `pip install pandas` command.
@@ -642,9 +664,9 @@ FROM spuacv/spuc:latest
642664
RUN pip install pandas
643665
```
644666

645-
Alternatively, we could simplify our `docker-compose.yml` file by removing the duplicated configuration.
646-
However, this would make the `docker-compose.yml` file less self-contained and more dependent on the Dockerfile.
647-
It is usually a better idea to keep the configuration in the `docker-compose.yml` file, as it makes it easier to understand and maintain.
667+
Alternatively, we could simplify our `compose.yml` file by removing the duplicated configuration.
668+
However, this would make the `compose.yml` file less self-contained and more dependent on the Dockerfile.
669+
It is usually a better idea to keep the configuration in the `compose.yml` file, as it makes it easier to understand and maintain.
648670

649671
:::::::::::::::::::::::::::::::::::
650672

@@ -843,9 +865,9 @@ For example in a typical web app you may make it so that the frontend can connec
843865
#### Network names
844866

845867
You may have noticed that the network that Docker Compose created for our stack is named `docker_intro_default`.
846-
This is because Docker Compose uses the name of the directory that the `docker-compose.yml` file is in as the name of the network.
868+
This is because Docker Compose uses the name of the directory that the `compose.yml` file is in as the name of the network.
847869

848-
If you want to specify the name of the network, you can use the `networks` key in the `docker-compose.yml` file.
870+
If you want to specify the name of the network, you can use the `networks` key in the `compose.yml` file.
849871
You also need to specify the network name for each service that you want to connect to the network.
850872

851873
For example, to specify the network name as `spuc_network`, you would add the following to the file:
@@ -1099,7 +1121,7 @@ The SPUC service shows an error, because it failed all 5 retries, and the SPUCSV
10991121
::::::::::::::::::::::::::::::::::::::::::::::::::: keypoints
11001122
- Docker Compose is a tool for defining and running multi-container stacks in a YAML file.
11011123
They can also serve as a way of structuring and documenting `docker run` commands for single containers.
1102-
- Instructions are saved in a `docker-compose.yml` file, where services, networks, and volumes are defined.
1124+
- Instructions are saved in a `compose.yml` file, where services, networks, and volumes are defined.
11031125
- Each `service` is a separate container, and it can be fully configured from within the file.
11041126
- Bind mounts and `volumes` can be declared for each service, and they can be shared between containers too.
11051127
- You can define `networks`, which can be used to connect or isolate containers from each other.

episodes/docker-desktop.Rmd

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Docker Desktop
3-
teaching: 20
3+
teaching: 40
44
exercises: 0
55
---
66

@@ -494,6 +494,10 @@ There is a very convenient bin icon on the right, which will prompt you for conf
494494
:::
495495

496496
You should now be able to run the `spuc` image again, and name the container `SPUC`.
497+
However, if you try to add the port you'll find that you still have a conflict.
498+
This is because the port is still in use by the old container, even though it is stopped.
499+
If you delete the randomly named container which had the port map,
500+
you should be able to run the image with the name and port you want.
497501

498502
Since we are deleting stuff, the `hello-world` image was nice and useful to test docker was working, but it is now rather useless.
499503
If I want to delete it, the `Images` tab on the left has a convenient bin icon to do so.
@@ -513,7 +517,7 @@ Clicking on it will prompt you for confirmation, but it will fail.
513517
:::
514518

515519
You'll probably notice that the status of the image is `In use`.
516-
That seems strange though, given that all the containers from that image excited immediately.
520+
That seems strange though, given that all the containers from that image exited immediately.
517521

518522
Lets have a look at the `Containers` tab.
519523
Some of the containers in the list came from the `hello-world` image.

episodes/docker-hub.Rmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: The Docker Hub
3-
teaching: 99
4-
exercises: 99
3+
teaching: 5
4+
exercises: 0
55
---
66

77
So we want to look at the docs for a container image, but we don't want Docker Desktop anymore!

episodes/docker-run-configuration.Rmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Configuring containers
3-
teaching: 99
4-
exercises: 99
3+
teaching: 30
4+
exercises: 0
55
---
66

77
Well this is interesting!

episodes/docker-volumes.Rmd

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Sharing information with containers
3-
teaching: 99
4-
exercises: 99
3+
teaching: 45
4+
exercises: 0
55
---
66

77
Now that we have learned the basics of the Docker CLI,
@@ -205,10 +205,10 @@ This is great!... but there are downsides.
205205

206206
To illustrate this, let's see what the permissions are on the file we just created.
207207
```bash
208-
ls -l spuc/unicorn_sightings.txt
208+
ls -l spuc/output/unicorn_sightings.txt
209209
```
210210
```output
211-
-rw-r--r-- 1 root root 57 Oct 11 14:14 spuc/unicorn_sightings.txt
211+
-rw-r--r-- 1 root root 57 Oct 11 14:14 spuc/output/unicorn_sightings.txt
212212
```
213213

214214
**Note:** This no longer seems to be the case from Docker version 27.3.1 onwards.
@@ -234,10 +234,33 @@ This was a bit difficult, as we had to do it from inside the container, and it d
234234
We now have the tools to address this!
235235
We can use a bind mount to share the config file with the container.
236236

237-
First we need to make the config file itself.
238-
Let's create a file with the following content:
237+
::::::::::::::::::::::::::::::::::::::: callout
238+
239+
## Docker cp
240+
241+
We can get files in and out of containers using the `docker cp` command.
242+
243+
Let's try this to get the `print.config` file out of the container.
244+
It works like the `cp` command, but you have to specify the container name and path:
239245
```bash
240-
echo "::::: {time} Unicorn number {count} spotted at {location}! Brightness: {brightness} {units}" > print.config
246+
docker cp spuc_container:/spuc/config/print.config .
247+
cat print.config
248+
```
249+
```output
250+
# This file configures the print output to the terminal.
251+
# Available variables are: count, time, location, brightness, units
252+
# The values of these variables will be replaced if wrapped in curly braces.
253+
# Lines beginning with # are ignored.
254+
::::: Unicorn spotted at {location}!! Brightness: {brightness} {units}
255+
```
256+
257+
Note that this **will not keep changes in sync** like a bind mount, but it is useful for getting files in and out of containers.
258+
259+
:::::::::::::::::::::::::::::::::::::::
260+
261+
Let's now modify the print.config file to include the time and the unicorn count:
262+
```
263+
::::: {time} Unicorn number {count} spotted at {location}! Brightness: {brightness} {units}
241264
```
242265

243266
Now, to share it with the container, we need to put it in the path `/spuc/config/print.config`.
@@ -263,8 +286,8 @@ Not only that, but because we created the file before mounting it to the contain
263286
Changes to the file will reflect immediately on the container.
264287

265288
For example, let's edit the file to get rid of the date:
266-
```bash
267-
echo "::::: Unicorn number {count} spotted at {location}! Brightness: {brightness} {units}" > print.config
289+
```
290+
::::: Unicorn number {count} spotted at {location}! Brightness: {brightness} {units}
268291
```
269292
Now let's register a sighting, and look at the logs:
270293
```bash

episodes/dockerfiles.Rmd

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Creating Your Own Container Images
3-
teaching: 99
4-
exercises: 99
3+
teaching: 60
4+
exercises: 0
55
---
66

77
::::::::::::::::::::::::::::::::::::::::::::::::::: objectives

0 commit comments

Comments
 (0)