mirror of https://github.com/docker/docs.git
parent
271fe6df6d
commit
bc511bd942
|
@ -1,22 +1,20 @@
|
|||
---
|
||||
title: "Multi container apps"
|
||||
keywords: get started, setup, orientation, quickstart, intro, concepts, containers, docker desktop
|
||||
description: Using more than one container in our application
|
||||
description: Using more than one container in your application
|
||||
---
|
||||
|
||||
Up to this point, we have been working with single container apps. But, we now want to add MySQL to the
|
||||
Up to this point, you've been working with single container apps. But, now you will add MySQL to the
|
||||
application stack. The following question often arises - "Where will MySQL run? Install it in the same
|
||||
container or run it separately?" In general, **each container should do one thing and do it well.** A few
|
||||
reasons:
|
||||
container or run it separately?" In general, each container should do one thing and do it well. The following are a few reasons to run the container separately:
|
||||
|
||||
- There's a good chance you'd have to scale APIs and front-ends differently than databases.
|
||||
- Separate containers let you version and update versions in isolation.
|
||||
- While you may use a container for the database locally, you may want to use a managed service
|
||||
for the database in production. You don't want to ship your database engine with your app then.
|
||||
- Running multiple processes will require a process manager (the container only starts one process),
|
||||
which adds complexity to container startup/shutdown.
|
||||
- Running multiple processes will require a process manager (the container only starts one process), which adds complexity to container startup/shutdown.
|
||||
|
||||
And there are more reasons. So, we will update our application to work like this:
|
||||
And there are more reasons. So, like the following diagram, it's best to run your app in multiple containers.
|
||||
|
||||

|
||||
{: .text-center }
|
||||
|
@ -24,30 +22,34 @@ And there are more reasons. So, we will update our application to work like this
|
|||
## Container networking
|
||||
|
||||
Remember that containers, by default, run in isolation and don't know anything about other processes
|
||||
or containers on the same machine. So, how do we allow one container to talk to another? The answer is
|
||||
**networking**. Now, you don't have to be a network engineer (hooray!). Simply remember this rule...
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> If two containers are on the same network, they can talk to each other. If they aren't, they can't.
|
||||
or containers on the same machine. So, how do you allow one container to talk to another? The answer is
|
||||
networking. If you place the two containers on the same network, they can talk to each other.
|
||||
|
||||
## Start MySQL
|
||||
|
||||
There are two ways to put a container on a network:
|
||||
1) Assign it at start or
|
||||
2) connect an existing container.
|
||||
For now, we will create the network first and attach the MySQL container at startup.
|
||||
- Assign the network when starting the container.
|
||||
- Connect an already running container to a network.
|
||||
|
||||
In the following steps, you'll create the network first and then attach the MySQL container at startup.
|
||||
|
||||
1. Create the network.
|
||||
|
||||
```console
|
||||
$ docker network create todo-app
|
||||
```
|
||||
```console
|
||||
$ docker network create todo-app
|
||||
```
|
||||
|
||||
2. Start a MySQL container and attach it to the network. We're also going to define a few environment variables that the
|
||||
database will use to initialize the database (see the "Environment Variables" section in the [MySQL Docker Hub listing](https://hub.docker.com/_/mysql/)).
|
||||
2. Start a MySQL container and attach it to the network. You're also going to define a few environment variables that the
|
||||
database will use to initialize the database. To learn more about the MySQL environment variables, see the "Environment Variables" section in the [MySQL Docker Hub listing](https://hub.docker.com/_/mysql/)).
|
||||
|
||||
```console
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a data-toggle="tab" data-target="#mac-linux">Mac / Linux</a></li>
|
||||
<li><a data-toggle="tab" data-target="#windows">Windows</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div id="mac-linux" class="tab-pane fade in active" markdown="1">
|
||||
|
||||
```console
|
||||
$ docker run -d \
|
||||
--network todo-app --network-alias mysql \
|
||||
-v todo-mysql-data:/var/lib/mysql \
|
||||
|
@ -56,7 +58,11 @@ For now, we will create the network first and attach the MySQL container at star
|
|||
mysql:8.0
|
||||
```
|
||||
|
||||
If you are using Windows then use this command in PowerShell.
|
||||
<hr>
|
||||
</div>
|
||||
<div id="windows" class="tab-pane fade" markdown="1">
|
||||
|
||||
In Windows, run this command in PowerShell.
|
||||
|
||||
```powershell
|
||||
$ docker run -d `
|
||||
|
@ -67,19 +73,23 @@ For now, we will create the network first and attach the MySQL container at star
|
|||
mysql:8.0
|
||||
```
|
||||
|
||||
You'll also see we specified the `--network-alias` flag. We'll come back to that in just a moment.
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
In the command above, you'll see the `--network-alias` flag. In a later section, you'll learn more about this flag.
|
||||
|
||||
> **Tip**
|
||||
>
|
||||
> You'll notice we're using a volume named `todo-mysql-data` here and mounting it at `/var/lib/mysql`, which is where MySQL stores its data. However, we never ran a `docker volume create` command. Docker recognizes we want to use a named volume and creates one automatically for us.
|
||||
> You'll notice a volume named `todo-mysql-data` in the above command that is mounted at `/var/lib/mysql`, which is where MySQL stores its data. However, you never ran a `docker volume create` command. Docker recognizes you want to use a named volume and creates one automatically for you.
|
||||
|
||||
3. To confirm we have the database up and running, connect to the database and verify it connects.
|
||||
3. To confirm you have the database up and running, connect to the database and verify that it connects.
|
||||
|
||||
```console
|
||||
$ docker exec -it <mysql-container-id> mysql -u root -p
|
||||
```
|
||||
|
||||
When the password prompt comes up, type in **secret**. In the MySQL shell, list the databases and verify
|
||||
When the password prompt comes up, type in `secret`. In the MySQL shell, list the databases and verify
|
||||
you see the `todos` database.
|
||||
|
||||
```console
|
||||
|
@ -100,22 +110,22 @@ For now, we will create the network first and attach the MySQL container at star
|
|||
+--------------------+
|
||||
5 rows in set (0.00 sec)
|
||||
```
|
||||
Exit the MySQL shell to return to the shell on our machine.
|
||||
|
||||
4. Exit the MySQL shell to return to the shell on your machine.
|
||||
|
||||
```console
|
||||
mysql> exit
|
||||
```
|
||||
|
||||
Hooray! We have our `todos` database and it's ready for us to use!
|
||||
You now have a `todos` database and it's ready for you to use.
|
||||
|
||||
## Connect to MySQL
|
||||
|
||||
Now that we know MySQL is up and running, let's use it! But, the question is... how? If we run
|
||||
another container on the same network, how do we find the container (remember each container has its own IP
|
||||
address)?
|
||||
Now that you know MySQL is up and running, you can use it. But, how do you use it? If you run
|
||||
another container on the same network, how do you find the container? Remember that each container has its own IP address.
|
||||
|
||||
To figure it out, we're going to make use of the [nicolaka/netshoot](https://github.com/nicolaka/netshoot) container,
|
||||
which ships with a _lot_ of tools that are useful for troubleshooting or debugging networking issues.
|
||||
To answer the questions above and better understand container networking, you're going to make use of the [nicolaka/netshoot](https://github.com/nicolaka/netshoot) container,
|
||||
which ships with a lot of tools that are useful for troubleshooting or debugging networking issues.
|
||||
|
||||
1. Start a new container using the nicolaka/netshoot image. Make sure to connect it to the same network.
|
||||
|
||||
|
@ -123,14 +133,14 @@ which ships with a _lot_ of tools that are useful for troubleshooting or debuggi
|
|||
$ docker run -it --network todo-app nicolaka/netshoot
|
||||
```
|
||||
|
||||
2. Inside the container, we're going to use the `dig` command, which is a useful DNS tool. We're going to look up
|
||||
2. Inside the container, you're going to use the `dig` command, which is a useful DNS tool. You're going to look up
|
||||
the IP address for the hostname `mysql`.
|
||||
|
||||
```console
|
||||
$ dig mysql
|
||||
```
|
||||
|
||||
And you'll get an output like this...
|
||||
You should get output like the following.
|
||||
|
||||
```text
|
||||
; <<>> DiG 9.18.8 <<>> mysql
|
||||
|
@ -153,11 +163,11 @@ which ships with a _lot_ of tools that are useful for troubleshooting or debuggi
|
|||
|
||||
In the "ANSWER SECTION", you will see an `A` record for `mysql` that resolves to `172.23.0.2`
|
||||
(your IP address will most likely have a different value). While `mysql` isn't normally a valid hostname,
|
||||
Docker was able to resolve it to the IP address of the container that had that network alias (remember the
|
||||
`--network-alias` flag we used earlier?).
|
||||
Docker was able to resolve it to the IP address of the container that had that network alias. Remember, you used the
|
||||
`--network-alias` earlier.
|
||||
|
||||
What this means is... our app only simply needs to connect to a host named `mysql` and it'll talk to the
|
||||
database! It doesn't get much simpler than that!
|
||||
What this means is that your app only simply needs to connect to a host named `mysql` and it'll talk to the
|
||||
database.
|
||||
|
||||
## Run your app with MySQL
|
||||
|
||||
|
@ -168,9 +178,9 @@ The todo app supports the setting of a few environment variables to specify MySQ
|
|||
- `MYSQL_PASSWORD` - the password to use for the connection
|
||||
- `MYSQL_DB` - the database to use once connected
|
||||
|
||||
> **Setting Connection Settings via Env Vars**
|
||||
> **Note**
|
||||
>
|
||||
> While using env vars to set connection settings is generally ok for development, it is **HIGHLY DISCOURAGED**
|
||||
> While using env vars to set connection settings is generally accepted for development, it's highly discouraged
|
||||
> when running applications in production. Diogo Monica, a former lead of security at Docker,
|
||||
> [wrote a fantastic blog post](https://diogomonica.com/2017/03/27/why-you-shouldnt-use-env-variables-for-secret-data/){:target="_blank" rel="noopener" class="_"}
|
||||
> explaining why.
|
||||
|
@ -183,14 +193,16 @@ The todo app supports the setting of a few environment variables to specify MySQ
|
|||
> as the connection password. Docker doesn't do anything to support these env vars. Your app will need to know to look for
|
||||
> the variable and get the file contents.
|
||||
|
||||
With all of that explained, let's start our dev-ready container!
|
||||
You can now start your dev-ready container.
|
||||
|
||||
1. **Note**: for MySQL versions 8.0 and higher, make sure to include the following commands in `mysql`.
|
||||
```console
|
||||
mysql> ALTER USER 'root' IDENTIFIED WITH mysql_native_password BY 'secret';
|
||||
mysql> flush privileges;
|
||||
```
|
||||
2. We'll specify each of the environment variables above, as well as connect the container to our app network.
|
||||
1. Specify each of the environment variables above, as well as connect the container to your app network.
|
||||
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a data-toggle="tab" data-target="#mac-linux2">Mac / Linux</a></li>
|
||||
<li><a data-toggle="tab" data-target="#windows2">Windows</a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div id="mac-linux2" class="tab-pane fade in active" markdown="1">
|
||||
|
||||
```console
|
||||
$ docker run -dp 3000:3000 \
|
||||
|
@ -204,7 +216,11 @@ With all of that explained, let's start our dev-ready container!
|
|||
sh -c "yarn install && yarn run dev"
|
||||
```
|
||||
|
||||
If you are using Windows then use this command in PowerShell.
|
||||
<hr>
|
||||
</div>
|
||||
<div id="windows2" class="tab-pane fade" markdown="1">
|
||||
|
||||
In Windows, run this command in PowerShell.
|
||||
|
||||
```powershell
|
||||
$ docker run -dp 3000:3000 `
|
||||
|
@ -217,7 +233,11 @@ With all of that explained, let's start our dev-ready container!
|
|||
node:18-alpine `
|
||||
sh -c "yarn install && yarn run dev"
|
||||
```
|
||||
3. If we look at the logs for the container (`docker logs -f <container-id>`), we should see a message indicating it's
|
||||
<hr>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
2. If you look at the logs for the container (`docker logs -f <container-id>`), you should see a message similar to the following, which indicates it's
|
||||
using the mysql database.
|
||||
|
||||
```console
|
||||
|
@ -230,10 +250,10 @@ With all of that explained, let's start our dev-ready container!
|
|||
Listening on port 3000
|
||||
```
|
||||
|
||||
4. Open the app in your browser and add a few items to your todo list.
|
||||
3. Open the app in your browser and add a few items to your todo list.
|
||||
|
||||
5. Connect to the mysql database and prove that the items are being written to the database. Remember, the password
|
||||
is **secret**.
|
||||
4. Connect to the mysql database and prove that the items are being written to the database. Remember, the password
|
||||
is `secret`.
|
||||
|
||||
```console
|
||||
$ docker exec -it <mysql-container-id> mysql -p todos
|
||||
|
@ -251,7 +271,7 @@ With all of that explained, let's start our dev-ready container!
|
|||
+--------------------------------------+--------------------+-----------+
|
||||
```
|
||||
|
||||
Obviously, your table will look different because it has your items. But, you should see them stored there!
|
||||
Your table will look different because it has your items. But, you should see them stored there.
|
||||
|
||||
## Next steps
|
||||
|
||||
|
@ -263,6 +283,6 @@ this application. You have to create a network, start containers, specify all of
|
|||
ports, and more! That's a lot to remember and it's certainly making things harder to pass along to someone else.
|
||||
|
||||
In the next section, you'll learn about Docker Compose. With Docker Compose, you can share your application stacks in a
|
||||
much easier way and let others spin them up with a single (and simple) command!
|
||||
much easier way and let others spin them up with a single, simple command.
|
||||
|
||||
[Use Docker Compose](08_using_compose.md){: .button .primary-btn}
|
||||
|
|
Loading…
Reference in New Issue