gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
Thanks to our docker-compose.yaml
file and the docker-compose up
command, we started a MySQL container in Docker. You can prove it by running:
docker-compose ps
Yep! Port 3306 of the container is being exposed to my host machine on port 32776, which is a random port that will change each time we run docker-compose up
.
Whether you followed me through the Docker setup... or decided to install MySQL on your own, we're now at the same point: we need to update the DATABASE_URL
environment variable to point to the database.
Normally I would copy DATABASE_URL
, go into .env.local
, paste, and update it to whatever my local settings are, like root
user, no password and a creative database.
But... I'm not going to do that. Why? Because the DATABASE_URL
environment variable is already configured correctly!
Let me show you. When we started our app, we used the Symfony binary to create a local web server. I'll run:
symfony server:stop
to stop it... just so I can show you the command we used. It was:
symfony serve -d
Tip
If you're using Ubuntu and running Docker in "root" mode, then you
will need to run sudo symfony serve -d
for Symfony to see the Docker
environment variables. Later, when we use things like symfony console
,
you will also need to use sudo. Note that this may cause some cache
file ownership issues in your Symfony app while developing. Ok, have fun!
That started a web server at localhost:8000
. So: what we're seeing in the browser is being served by the symfony
binary.
Well... surprise! The Symfony binary has special integration with Docker! It detects that we have a docker-compose.yaml
file in this project, loops over all of the running services, reads their config and exposes real environment variables to our app with the connection details for each one.
For example, because this service is called database
- we technically could have called it anything - the Symfony binary is already exposing an environment variable called DATABASE_URL
: the exact environment variable that Doctrine is looking for.
I'll show you exactly what I mean. First, go back to your browser, watch the bottom right of the web debug toolbar, and refresh. Ah! The little "Server" icon turned green! This is info about the Symfony web server... and now it says "Env Vars from Docker".
Back at your editor, open up public/index.php
: the front controller for our project. We normally don't need to mess with this file... but let's temporarily hack in some code. After the autoload line, add dd($_SERVER)
.
... lines 1 - 7 | |
require dirname(__DIR__).'/vendor/autoload.php'; | |
dd($_SERVER); | |
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env'); | |
... lines 13 - 33 |
The $_SERVER
global variable holds a lot of things including any real environment variables that are passed to PHP. Back at the browser, refresh and search for "database". Check it out! A DATABASE_URL
environment variable!
That is being set by the Symfony binary, which is reading the info dynamically from Docker. It has all the correct info including port 32776.
When a real environment variable exists, it overrides the value that you have in .env
or .env.local
. In other words, as soon as we run docker-compose up
, our app has access to a DATABASE_URL
environment variable that points to the Docker container. We don't need to configure anything!
Back in index.php
, remove the dd()
line.
... lines 1 - 7 | |
require dirname(__DIR__).'/vendor/autoload.php'; | |
(new Dotenv())->bootEnv(dirname(__DIR__).'/.env'); | |
... lines 11 - 31 |
Another way to see what environment variables the Symfony binary is exporting to our app is by running:
symfony var:export --multiline
And... yes! This has DATABASE_URL
and some other DATABASE
variables that you can use for each part... if you need to. If we added a second service to docker-compose
- like a Redis container - then that would show up here too.
The big picture is this: all we need to do is run docker-compose up -d
and our Symfony app is immediately setup to talk to the database. I love that.
But... we can't really do anything yet... because the MySQL instance is empty! Next, let's create our database and make sure that Doctrine knows exactly which version of MySQL we're using.
// composer.json
{
"require": {
"php": "^7.2.5",
"ext-ctype": "*",
"ext-iconv": "*",
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/doctrine-bundle": "^2.1", // 2.1.0
"doctrine/doctrine-migrations-bundle": "^3.0", // 3.0.1
"doctrine/orm": "^2.7", // v2.7.3
"knplabs/knp-markdown-bundle": "^1.8", // 1.8.1
"knplabs/knp-time-bundle": "^1.11", // v1.12.0
"sensio/framework-extra-bundle": "^5.5", // v5.6.1
"sentry/sentry-symfony": "^3.4", // 3.5.2
"stof/doctrine-extensions-bundle": "^1.4", // v1.4.0
"symfony/asset": "5.1.*", // v5.1.2
"symfony/console": "5.1.*", // v5.1.2
"symfony/dotenv": "5.1.*", // v5.1.2
"symfony/flex": "^1.3.1", // v1.9.10
"symfony/framework-bundle": "5.1.*", // v5.1.2
"symfony/monolog-bundle": "^3.0", // v3.5.0
"symfony/stopwatch": "5.1.*", // v5.1.2
"symfony/twig-bundle": "5.1.*", // v5.1.2
"symfony/webpack-encore-bundle": "^1.7", // v1.7.3
"symfony/yaml": "5.1.*", // v5.1.2
"twig/extra-bundle": "^2.12|^3.0", // v3.0.4
"twig/twig": "^2.12|^3.0" // v3.0.4
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.3", // 3.3.1
"symfony/debug-bundle": "5.1.*", // v5.1.2
"symfony/maker-bundle": "^1.15", // v1.23.0
"symfony/var-dumper": "5.1.*", // v5.1.2
"symfony/web-profiler-bundle": "5.1.*", // v5.1.2
"zenstruck/foundry": "^1.1" // v1.1.0
}
}