---
title: Use Docker Compose
weight: 80
linkTitle: "Part 7: Use Docker Compose"
keywords: get started, setup, orientation, quickstart, intro, concepts, containers,
docker desktop
description: Using Docker Compose for multi-container applications
aliases:
- /get-started/08_using_compose/
- /guides/workshop/08_using_compose/
---
[Docker Compose](/manuals/compose/_index.md) is a tool that helps you define and
share multi-container applications. With Compose, you can create a YAML file to define the services
and with a single command, you can spin everything up or tear it all down.
The big advantage of using Compose is you can define your application stack in a file, keep it at the root of
your project repository (it's now version controlled), and easily enable someone else to contribute to your project.
Someone would only need to clone your repository and start the app using Compose. In fact, you might see quite a few projects
on GitHub/GitLab doing exactly this now.
## Create the Compose file
In the `getting-started-app` directory, create a file named `compose.yaml`.
```text
├── getting-started-app/
│ ├── Dockerfile
│ ├── compose.yaml
│ ├── node_modules/
│ ├── package.json
│ ├── spec/
│ ├── src/
│ └── yarn.lock
```
## Define the app service
In [part 6](./07_multi_container.md), you used the following command to start the application service.
```console
$ docker run -dp 127.0.0.1:3000:3000 \
-w /app -v "$(pwd):/app" \
--network todo-app \
-e MYSQL_HOST=mysql \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=secret \
-e MYSQL_DB=todos \
node:18-alpine \
sh -c "yarn install && yarn run dev"
```
You'll now define this service in the `compose.yaml` file.
1. Open `compose.yaml` in a text or code editor, and start by defining the name and image of the first service (or container) you want to run as part of your application.
The name will automatically become a network alias, which will be useful when defining your MySQL service.
```yaml
services:
app:
image: node:18-alpine
```
2. Typically, you will see `command` close to the `image` definition, although there is no requirement on ordering. Add the `command` to your `compose.yaml` file.
```yaml
services:
app:
image: node:18-alpine
command: sh -c "yarn install && yarn run dev"
```
3. Now migrate the `-p 127.0.0.1:3000:3000` part of the command by defining the `ports` for the service.
```yaml
services:
app:
image: node:18-alpine
command: sh -c "yarn install && yarn run dev"
ports:
- 127.0.0.1:3000:3000
```
4. Next, migrate both the working directory (`-w /app`) and the volume mapping
(`-v "$(pwd):/app"`) by using the `working_dir` and `volumes` definitions.
One advantage of Docker Compose volume definitions is you can use relative paths from the current directory.
```yaml
services:
app:
image: node:18-alpine
command: sh -c "yarn install && yarn run dev"
ports:
- 127.0.0.1:3000:3000
working_dir: /app
volumes:
- ./:/app
```
5. Finally, you need to migrate the environment variable definitions using the `environment` key.
```yaml
services:
app:
image: node:18-alpine
command: sh -c "yarn install && yarn run dev"
ports:
- 127.0.0.1:3000:3000
working_dir: /app
volumes:
- ./:/app
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: secret
MYSQL_DB: todos
```
### Define the MySQL service
Now, it's time to define the MySQL service. The command that you used for that container was the following:
```console
$ docker run -d \
--network todo-app --network-alias mysql \
-v todo-mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=todos \
mysql:8.0
```
1. First define the new service and name it `mysql` so it automatically gets the network alias. Also specify the image to use as well.