Docker Compose
Target
This project is about Docker Compose. You will:
- write a Docker Compose deployment
- familiarize yourself with the basic commands of the Compose CLI
docker compose
Tools
- Try to complete the tasks below with the help of the slides and the cheatsheet.
- If you have any problems, you will find a fold-out block for each task describing the solution.
Task 1 - Create and use a docker-compose.yml
In this section, you will familiarize yourself with the Compose file format and start the Docker Demo App using the Compose CLI docker compose
.
- Create a new subfolder
deployment
of the workspace folder/home/coder/workspace
. - Create a new file
compose.yml
in the folderdeployment
. - Open the file
compose.yml
. -
Copy the following content into the file:
--- services: webapp: image: corewire/docker-demoapp:1.0.0 ports: - 8080:5000
- All containers of a Compose deployment are defined in the
services
block. webapp
defines a service. In this service you define,- ) that the image
corewire/docker-demoapp:1.0.0
is used and - ) a port mapping of the container port
5000
to the host port8080
so that the application can be reached athttp://code-X.labs.corewire.de:8080
.
- ) that the image
- All containers of a Compose deployment are defined in the
-
Change to the
deployment
folder in the terminal.Solution (click on the arrow if you get stuck)
- If you are already in the
Workspace
folder, you can switch directly to the new folder withcd
:cd deployment
- If you are still in a subfolder of
Workspace
, first navigate to the workspace folder:Then change to the correct subfolder:cd ..
cd deployment
- If you are already in the
-
Start your service in the background.
Solution (click on the arrow if you get stuck)
- Use
-d
to start the container in the background.docker compose up -d
- You can display all running containers of a compose deployment with the command
docker compose ps
.
docker compose up -d
- If you have defined more than one service,
docker compose up -d
starts all services. - If you only want to start individual services, use
docker compose up -d <service_name>
- Use
-
Display the logs of the
webapp
service.Solution (click on the arrow if you get stuck)
- You can display the logs with or without the
-f
option. With-f
newly appearing logs are displayed.docker compose logs -f webapp
- You can display the logs with or without the
-
Open the URL
http://code-X.labs.corewire.de:8080
in the browser, where X is your number. You should now see the demo app. -
Stop and remove the service again:
ordocker compose stop webapp docker compose rm webapp
docker compose down
Warning about docker compose down
docker compose down
is a very destructive command.- If you have defined more than one service,
docker compose down
will stop all services, remove all containers and remove all local networks. - So if you only want to stop individual services, use
docker compose stop
anddocker compose rm
.
Task 2 - Volumes in Docker Compose
You have learned in previous chapters of the training that containers are 'stateless'. Stateless means that data written during the runtime of a container disappears as soon as the container is deleted. In this section, you will learn how to define volumes in the Compose file format.
- The Docker Demo App stores notes created in the web interface under the path
/app/data/notes
by default. -
Add a section
volumes
to yourcompose.yml
file to thewebapp
service.Volume for service 'webapp'
- Type: bind-mount
- Local path: ./volumes/webapp-data
- Mount path in the container: /app/data/notes
- If you have forgotten the exact syntax, use the training material or the documentation of the Compose file format for Volumes.
Solution (click on the arrow if you get stuck)
The syntax is volumes: and below with indentation and
-
<hostpath>:<containerpath>
:Alternatively, there is also a long form, but this assumes that the folder--- services: webapp: image: corewire/docker-demoapp:1.0.0 ports: - 8080:5000 volumes: - ./volumes/webapp-data:/app/data/notes
/volumes/webapp-data
already exists:--- services: webapp: image: corewire/docker-demoapp:1.0.0 ports: - 8080:5000 volumes: - type: bind source: ./volumes/webapp-data target: /app/data/notes
-
Start the webapp service.
Solution (click on the arrow if you get stuck)
docker compose up -d webapp
-
You should now see that a new folder
volumes
appears in your directory, in which a folderwebapp-data
is located. This folder should be empty. - Now open the URL
http://code-X.labs.corewire.de:8080
in the browser, where X is your number. You should now see the demo app. - Create a note in the web interface of the demo app.
- You should now see in the folder
volumes/webapp-data
that a new file has been created, similar tonote_2022-06-16T13:43:23.690467.txt
. -
Stop and remove the service
webapp
.Solution (click on the arrow if you get stuck)
To stop and remove use the following command:
ordocker compose stop webapp docker compose rm webapp
docker compose down
-
Start the webapp service.
Solution (click on the arrow if you get stuck)
docker compose up -d webapp
-
Now open the web interface of the demo app again (
http://code-X.labs.corewire.de:8080
). - You should now be able to see the note you just created.
Task 3 - Database Service
In this section you will define a new service that will start a MariaDB database server.
-
Add a service
database
to yourcompose.yml
file:Database Service 'database'
- Name: database
- Image Name: mariadb
- Image Tag: latest
- Reference: https://hub.docker.com/_/mariadb
- "MYSQL_USER=example-user"
- "MYSQL_PASSWORD=password"
- "MYSQL_ROOT_PASSWORD=root_password "
- Type: named volume
- Name: database-volume
- Mount path in container: /var/lib/mysql
- Name: database-network
- Use the training materials and the Compose documentation:
Solution (click on the arrow if you get stuck)
--- services: webapp: image: corewire/docker-demoapp:1.0.0 ports: - 8080:5000 volumes: - ./volumes/webapp-data:/app/data/notes database: image: mariadb:latest environment: - "MYSQL_USER=example-user" - "MYSQL_PASSWORD=password" - "MYSQL_ROOT_PASSWORD=root_password" volumes: - database-volume:/var/lib/mysql networks: - database-network volumes: database-volume: networks: database-network:
-
Start the service
database
.Solution (click on the arrow if you get stuck)
To start the service, use the following input:
docker compose up -d database
-
Display the logs of the
database
service.Solution (click on the arrow if you get stuck)
To output the logs, use the following input:
docker compose logs -f database
-
If the database container has started successfully, you will see the following output at the end of the log stream:
database_1 | 2022-06-16 14:42:06 0 [Note] Server socket created on IP: '0.0.0.0'. database_1 | 2022-06-16 14:42:06 0 [Note] Server socket created on IP: '::'. database_1 | 2022-06-16 14:42:06 0 [Note] mariadbd: ready for connections. database_1 | Version: '10.8.3-MariaDB-1:10.8.3+maria~jammy' socket: '/run/mysqld/mysqld.sock' port: 3306 mariadb.org binary distribution
Task 4 - Connecting the webapp to the database
In this section, we connect the Docker demo app to a database, i.e. the webapp
service to the database
service.
-
On the web interface of the Docker Demo App (http://code-X.labs.corewire.de:8080) you see the following error message:
This is because the Docker demo app is not connected to any database and the application expects a database server to be accessible under the DNS name "database" by default.Connection to MariaDB Server could not be established: Unknown MySQL server host 'database' (-5)
-
Customize the service
webapp
by adding environment variables and a network:Service 'webapp'
- "DATABASE_HOST=database "
- "DATABASE_PORT=3306"
- "DATABASE_USER=example-user"
- "DATABASE_USER_PASSWORD=password "
- Name: database-network
Solution (click on the arrow if you get stuck)
--- services: webapp: image: corewire/docker-demoapp:1.0.0 ports: - 8080:5000 volumes: - ./volumes/webapp-data:/app/data/notes networks: - database-network environment: - "DATABASE_HOST=database" - "DATABASE_PORT=3306" - "DATABASE_USER=example-user" - "DATABASE_USER_PASSWORD=password" database: image: mariadb:latest environment: - "MYSQL_USER=example-user" - "MYSQL_PASSWORD=password" - "MYSQL_ROOT_PASSWORD=root_password" volumes: - database-volume:/var/lib/mysql networks: - database-network volumes: database-volume: networks: database-network:
-
Restart the
webapp
service.Solution (click on the arrow if you get stuck)
To start the service, use the following input:
docker compose up -d webapp
-
Open
http://code-X.labs.corewire.de:8080
, the error message should now have disappeared.