Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

docker-compose Env Vars & Symfony

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

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.

Configure DATABASE_URL Manually?

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.

DATABASE_URL From Docker

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.

Dumping the Environment Variable

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).

33 lines public/index.php
... 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!

Seeing the Environment Variables

Back in index.php, remove the dd() line.

31 lines public/index.php
... 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.

Leave a comment!

59
Login or Register to join the conversation
gazzatav Avatar
gazzatav Avatar gazzatav | posted 4 months ago | edited

there Ouch, doctrine:fixtures:load has successfully deleted all my previous manual data from my postgresql database but now when I run it I get:

PHP Warning: Uncaught ErrorException: Warning: require_once(/home/gary/Projects/Symfony/climate_overflow): failed to open stream: No such file or directory in /home/gary/Projects/Symfony/climate_overflow/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/ColocatedMappingDriver.php:189
Stack trace:
#0 /home/gary/Projects/Symfony/climate_overflow/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/ColocatedMappingDriver.php(189): require_once()
#1 /home/gary/Projects/Symfony/climate_overflow/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/MappingDriverChain.php(104): Doctrine\ORM\Mapping\Driver\AnnotationDriver->getAllClassNames()
#2 /home/gary/Projects/Symfony/climate_overflow/vendor/doctrine/doctrine-bundle/Mapping/MappingDriver.php(29): Doctrine\Persistence\Mapping\Driver\MappingDriverChain->getAllClassNames()
#3 /home/gary/Projects/Symfony/climate_overflow/vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php(94): Doctrine\Bundle\DoctrineBundle\Mapping\MappingDriv in /home/gary/Projects/Symfony/climate_overflow/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/ColocatedMappingDriver.php on line 189
PHP Fatal error: Doctrine\ORM\Mapping\Driver\AnnotationDriver::getAllClassNames(): Failed opening required '' (include_path='.:/usr/share/php') in /home/gary/Projects/Symfony/climate_overflow/vendor/doctrine/persistence/src/Persistence/Mapping/Driver/ColocatedMappingDriver.php on line 189

CRITICAL [php] Fatal Compile Error: Doctrine\ORM\Mapping\Driver\AnnotationDriver::getAllClassNames(): Failed opening required ' ' (include_path='.:/usr/share/php') ["exception" => Symfony\Component\ErrorHandler\Error\FatalError^ { …}]

Any ideas? Looks like a bug to me. I put an Exception in the load function and it didn't reach that so I don't think it's me!

Edit: Just looked again at the comment from Rene below, is it possible that the bug is in the version of bundle which has been installed? I have php 7.2.24.

Edit 2:
Why is it that I try to figure something for half an hour, then when I finally post a question I solve it within minutes?

Well anyway an uncaught exception in vendor code is probably a bug. I am creating the Question in load using a constructor (before I move on to Foundry). The first constructor I wrote was taking the id as an argument which I thought might be a problem (as it is generated) and which I changed as soon as this error occurred but did NOT save 🤦.


- public function __construct(int $id, string $title, string $slug, string $question, \DateTime $askedAt, int $votes){
- $this->id=$id;
+ public function __construct(string $title, string $slug, string $question, \DateTime $askedAt, int $votes){
$this->title=$title;
$this->slug=$slug;
$this->question=$question;
1 Reply
Néstor D. Avatar
Néstor D. Avatar Néstor D. | posted 9 months ago

Hi,

Apparently I'm having some trouble to get this course running with Symfony local web server, which I haven't had in other courses.

When I run `symfony serve` or `sudo symfony serve` I get the following logs:

[Web Server ] Feb 11 21:52:30 |DEBUG | PHP Reloading PHP versions
[Web Server ] Feb 11 21:52:31 |DEBUG | PHP Using PHP version 7.4.27 (from default version in $PATH)
[Application] Feb 7 20:44:32 |INFO | REQUES Matched route "app_homepage". method="GET" request_uri="https://127.0.0.1:8001/" route="app_homepage" route_parameters={"_controller":"App\\Controller\\QuestionController::homepage","_route":"app_homepage"}
[Application] Feb 7 20:44:33 |INFO | REQUES Matched route "_wdt". request_uri="https://127.0.0.1:8001/_wdt/91a593" route="_wdt" route_parameters={"_controller":"web_profiler.controller.profiler::toolbarAction","_route":"_wdt","token":"91a593"}
[Application] Feb 7 20:44:34 |ERROR | REQUES Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\NotFoundHttpException: "No route found for "GET /favicon.ico" (from "https://127.0.0.1:8001/")" at /mnt/c/Sites/symfonycasts/code-symfony-doctrine/start/vendor/symfony/http-kernel/EventListener/RouterListener.php line 136
[Application] Feb 7 21:02:57 |ERROR | CONSOL Error thrown while running command "make". Message: "Command "make" is not defined. Did you mean one of these? make:auth make:command make:controller make:crud make:docker:database make:entity make:fixtures make:form make:functional-test make:message make:messenger-middleware make:migration make:registration-form make:reset-password make:serializer:encoder make:serializer:normalizer make:subscriber make:twig-extension make:unit-test make:user make:validator make:voter" command="make" message="Command \"make\" is not defined.\n\nDid you mean one of these?\n make:auth\n make:command\n make:controller\n make:crud\n make:docker:database\n make:entity\n make:fixtures\n make:form\n make:functional-test\n make:message\n make:messenger-middleware\n make:migration\n make:registration-form\n make:reset-password\n make:serializer:encoder\n make:serializer:normalizer\n make:subscriber\n make:twig-extension\n make:unit-test\n make:user\n make:validator\n make:voter"
[Application] Feb 11 08:46:23 |ERROR | CONSOL Error thrown while running command "make". Message: "Command "make" is not defined. Did you mean one of these? make:auth make:command make:controller make:crud make:docker:database make:entity make:fixtures make:form make:functional-test make:message make:messenger-middleware make:migration make:registration-form make:reset-password make:serializer:encoder make:serializer:normalizer make:subscriber make:twig-extension make:unit-test make:user make:validator make:voter"
[Web Server ] Feb 11 21:52:31 |INFO | PHP listening path="/usr/bin/php7.4" php="7.4.27" port=40201
[PHP ] [Fri Feb 11 21:52:31 2022] PHP 7.4.27 Development Server (http://127.0.0.1:40201) started

I get Application errors in the log and the course won't load on my browser getting an "Unable to connect" error page when navigating to https://127.0.0.1:8000.

Do you know what is happening?

Thank you in advance.

1 Reply

Hey Nestor,

Please, try to run "composer install" and try again. If still have this issue, maybe try to "rm -rf vendor/", then "composer install", and try again. If you still have this issue - could you share some steps to reproduce this? I suppose you downloaded the course and started from start/ folder following the steps from README? Did it work well in previous chapters? Btw, do you have symfony/maker-bundle installed in your project?

Cheers!

Reply
Néstor D. Avatar

Hi Victor,

I tried what you suggested but the issue seemed to be lying somewhere else.

I recently upgraded WSL to version 2 and navigating to the course in the browser like https://127.0.0.1:8000 apparently no longer works. https://localhost:8000 needs to be used instead as suggested here https://github.com/symfony/....

Thank you for your reply and keep up the good work!

Cheers!

2 Reply

Hey Nestor,

Ah, yes, nothing much you can do with this on WSL - I just heard the same from Diego who also uses WSL on Windows. So yes, just use localhost instead of IP.

Cheers!

Reply
Dima Avatar

Hey guys! Thanks for the work on these tutorials, it's very special, and thanks to Ryan for keeping great vibe through all the courses!

I'm trying to learn how to operate with database through symfony's basic mysql docker routine. Using this make:docker:database command. Tutorial says that symfony binary read my DATABASE_URL itself, and I don't need to configure that in .env file. I followed all the steps, but after refreshing browser in my profiler it says that docker-compose isn't up and this env vars icon also red (there has to be sign "FROM DOCKER" and green light). But inside app my docke-compose is up, and all configured well.

Sorry if I explained the problem not very well, I'm very new to all of it, but maybe anyone know where might be the problem? In logs I also can see this error:

error while trying to collect executed migrationsapp Hide context Show trace
[▼
"exception" => Doctrine\DBAL\Exception\ConnectionException {#588 ▼
-query: null
#message: "An exception occurred in the driver: SQLSTATE[HY000] [1045] Access denied for user 'db_user'@'localhost' (using password: YES)"
#code: 1045
#file: "/home/dima/couldron_overflow/vendor/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php"
#line: 103
-previous: Doctrine\DBAL\Driver\PDO\Exception {#576 …}
trace: {▶}

Reply

Hey @Dima Bredun!

Thank you for the kind words! And I think you are understanding the problem perfectly. For some reason, the Symfony binary simply is *not* seeing your Docker containers and is *not* injecting the environment variables. You made that very clear by noticing the red env vars icon in the web debug toolbar and also noticing the error in the logs (where it's using the default DATABASE_URL from .env, which means that DATABASE_URL must not be injected as a real environment variable).

So, the question is why? Try running this:


symfony var:export --multiline

If things are working (meaning the symfony binary sees your docker containers), then one of the lines you see should start with export DATABASE_URL.... If you do not see this, then the symfony binary isn't seeing your Docker containers... for some reason... and we will need to dig deeper.

If you DO see this entry, then things "are working" and the question is: why isn't this environment variable seen then you refresh your app in the browser? For this, check 2 things. First, you *are* using the symfony binary's built-in web server, correct? I just need to check :). Second, if you are, try restarting the web server - symfony server:stop then symfony serve -d. That shouldn't be necessary, but it's possible that it's needed on some systems.

Let me know what you find out!

Cheers!

Reply
Dima Avatar

I started to run local symfony server under sudo (previously I use the symfony serve -d command without it) and it started to work! Now the app can see my docker configuration.

Thanks for the help Ryan and once again for all the great work you guys have done on this tutorial 👏

Reply

OMG - I just replied without seeing this first! My bad!

Great job debugging - of course, sudo! I'm not sure why that's needed - probably your docker-compose was run (or the docker processes are owned) by root. Anyways, I'm happy you got it and thanks for sharing your solution!

Cheers!

Reply
Dima Avatar

I already tried symfony var:export command, but there wasn't DATABASE_URL lime. The line export SYMFONY_DOCKER_ENV=

equals to nothing, so looks like it doesn't see my containers like you said. And restarting of symfony server didn't help as well, I tried. Maybe you know cases when symfony binary ignoring docker containers? Which steps I can make to try to fix it?

Just in case, previously I deleted my docker-compose and ran make:docker:database again, maybe it crashed things inside the app? But then it was created like it should be, and container is up, but not in browser.

Reply

Hey Dima!

Sorry for the slow reply! Hmm, so no DATABASE_URL inside of var:export. So yes, it's not seeing your containers.

> Maybe you know cases when symfony binary ignoring docker containers?

That's a great question - but I have *not* heard of this not working before... At the root of your app, if you run docker-compose ps, do you see the running container (with "Up") status? Is there anything custom at all about your setup (it sounds like no, but I'm checking)? What operating system are you on?

It's gotta be some edge-case thing. I haven't, yet, experienced a situation where the docker container is running, but the symfony binary doesn't see it. The symfony var:export is your go-to way to debug things, as you can directly see - at that moment - whether or not the symfony binary sees your Docker container.

Cheers!

Reply
Matteo S. Avatar
Matteo S. Avatar Matteo S. | posted 1 year ago

Are you seriously using root as the db user???

Reply

Hi Matteo S.!

Absolutely! :) I wouldn't use root as a database user on production, but for local development - especially in this case, where we're inside a Docker container that holds *only* the local database for this project - there's no problem with it. Of course, if you'd like to do something else, you absolutely can :).

Cheers!

Reply
Matteo S. Avatar

I see. On the other hand, i like to have as few differences as possible between production and dev (when it costs nothing). By having a non-superuser as the database user, i face a few problems that you don't in the tutorial. One is configuring the username and password in Docker compose, that is trivial (just two extra parameters and it creates a database and user out of the box). The other is how could make:database:create create the database if the main user configured in doctrine is not root. Then of course I don't need that in dev if Docker compose creates the database for me, but i wonder about production. Ok, usually on production you probably create the database outside of symfony entirely and to Symfony that's just a given, but is that the only scenario? I imagined a workflow where the creation of the database could be the very first "migration" (of course that would require configuring a mysql root user/password in doctrine). Is that not possible?

Reply

Hey Matteo S.!

> On the other hand, i like to have as few differences as possible between production and dev (when it costs nothing). By having a non-superuser as the database user, i face a few problems that you don't in the tutorial

Very fair point! This is definitely the ideal situation. For the tutorial, we're balancing that ideal and having "simple config" so that we can focus on the items that we *want* to focus on. Both sides can't fully win :/.

> Ok, usually on production you probably create the database outside of symfony entirely and to Symfony that's just a given, but is that the only scenario? I imagined a workflow where the creation of the database could be the very first "migration" (of course that would require configuring a mysql root user/password in doctrine). Is that not possible?

This is tough because of the highly varied ways that you can deploy. In SymfonyCloud (a PaaS), the database is created for you, which is nice because you don't need to worry about it and you don't need your database user to have permissions for creating or deleting a database. In past deploy systems (e.g. using Ansistrano), we DID give our database user the power to create the database and we ran bin/console doctrine:database:create --if-not-exists on every deploy. That was wasteful (as it only ran on the first ever deploy), but it made sure that we could run our deploy script in any situation and we were good. Other systems split the "infrastructure building" from the "deploying". In that situation, you might use Ansible or Terraform to create your servers including your database. Then, on deploy, you can safely assume that the database already exists (so, that's a bit similar to the SymfonyCloud setup).

That's kind of a... fuzzy answer - but, unfortunately it really does depend on how your deploy :).

Cheers!

Reply
Default user avatar

Hi,

After I run docker-compose up -d,
I can connect to the container via the mysql.exe command in command prompt (windows console).

When I refresh my webpage , I get the following error :

An exception occurred in driver: SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client

Can anyone help me ?

Thanks a lot.

Ariel

Reply

Hi @Ariel!

I know this error! And it's a pesky one... especially since, in theory, if you're using Docker, you should be getting the same Mysql & configuration that I'm using :/. But, for some reason, some people hit this error... and it's still a mystery to me.

Here's a thread on this topic - https://symfonycasts.com/sc... - I wish I better understood the root cause of this... it's really annoying... but I don't. I never get it on my system.

Anyways, let me know if that thread helps :)

Cheers!

Reply
Ariel S. Avatar

Hi Ryan,

It works !
I followed your advice (on the thread), and ran in mysql:

ALTER user 'root'@'%' identified with mysql_native_password by 'password';

and I can know connect to docker.
Thank you very much !

Symfonycasts is fantastic.
Ariel

Reply

Ah, yay! And thank you for following up that the solution worked!!

Cheers!

Reply
Gizmola Avatar

This is caused by MySQL 8 changing the default way that password authentication works. It's now using "caching_sha2_password" by default which has stringent requirements like rsa key exchange in order for it to work. If someone is using an older version of php like 7.3, there isn't support for the scheme.

I found that just altering the root user within mysql didn't work. You would also have to do this every time you bring up the mysql container. Adding this command line for the mysql service to the docker-compose file takes care of the problem.


....
services:
###> doctrine/doctrine-bundle ###
database:
image: 'mysql:latest'
command: ['--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci','--default-authentication-plugin=mysql_native_password']
1 Reply

Hey Gizmola!

Thanks for posting the solution here for others - I appreciate that :).

Cheers!

1 Reply
Jayant B. Avatar
Jayant B. Avatar Jayant B. | posted 1 year ago

After I did the step symfony serve -d and did the refresh to see debug tool bar and I got following error -

An exception occurred in driver: SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client

Please let me know how to resolve this issue.

Reply

Hey Jayant B.!

I know this error - it's real pain in the butt! Assuming you're using Docker for the database (which it sounds like you are), I'm not sure why you would get this and nobody else would :/. One simple option is to change your MySQL version to 5.7 in your docker-compose and rebuild everything. That "should" fix it. But this error is a real pain - MySQL changed how they required authentication in a minor version.

Another thing you can try (I'm trying to think of reasonably easy solutions) is what you see here: https://github.com/laradock... - specifically the command key.

Let me know if either of these things help. People hit this issue occasionally (I never have) and, to be honest, I always struggle to remember what the best solution is.

Cheers!

Reply
Jayant B. Avatar

Hello Weaverryan
I have tried changing the MYSQL version to 5.7 and restarted the docker and it worked. Thank you!

Just thinking out loud, i am using Wamp server and on which MYSQL version is also 5.7.31, before switching to docker, application was working fine with 5.7.31 so may be that's why i got this issue. if my wamp server had MYSQL 8.0 then probably composer would have installed the application/packages according to that at the first point when I ran composer install.

Thanks & Regards
Jayant

Reply
Christopher S. Avatar
Christopher S. Avatar Christopher S. | posted 1 year ago

I created a mysql Database using docker that I can also access, but when I tried to load the side it tells me something about not being able to find drivers, with the last message being "pdoexception could not find driver".

Reply

Hey Christopher S.!

I know this error :). It's a missing PDO extension in PHP. Exactly what how you install that depends on your operating system. For example, if you're using Ubuntu, then you would need to run something like sudo apt-get install php7.4-mysql (replacing the PHP version with whatever your version is). When you're done, be sure to restart the web server.

Let me know if that helps!

Cheers!

Reply
Covi A. Avatar
Covi A. Avatar Covi A. | posted 1 year ago

when i work with your code the code is worked perfectly. but now i am trying to create my own project i face a problem. when make dd($_SERVER) index page
then i see only this


^ array:29 [▼
"DOCUMENT_ROOT" => "/home/mono/Projects/Baby/public"
"REMOTE_ADDR" => "127.0.0.1"
"REMOTE_PORT" => "42920"
"SERVER_SOFTWARE" => "PHP 7.4.3 Development Server"
"SERVER_PROTOCOL" => "HTTP/1.1"
"SERVER_NAME" => "127.0.0.1"
"SERVER_PORT" => "42595"
"REQUEST_URI" => "/products"
"REQUEST_METHOD" => "GET"
"SCRIPT_NAME" => "/index.php"
"SCRIPT_FILENAME" => "/home/mono/Projects/Baby/public/index.php"
"PATH_INFO" => "/products"
"PHP_SELF" => "/index.php/products"
"HTTP_HOST" => "127.0.0.1:8000"
"HTTP_USER_AGENT" => "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36"
"HTTP_ACCEPT" => "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
"HTTP_ACCEPT_ENCODING" => "gzip, deflate, br"
"HTTP_ACCEPT_LANGUAGE" => "en-US,en;q=0.9"
"HTTP_CACHE_CONTROL" => "max-age=0"
"HTTP_SEC_CH_UA" => "" Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91""
"HTTP_SEC_CH_UA_MOBILE" => "?0"
"HTTP_SEC_FETCH_DEST" => "document"
"HTTP_SEC_FETCH_MODE" => "navigate"
"HTTP_SEC_FETCH_SITE" => "none"
"HTTP_SEC_FETCH_USER" => "?1"
"HTTP_UPGRADE_INSECURE_REQUESTS" => "1"
"HTTP_X_FORWARDED_FOR" => "127.0.0.1"
"REQUEST_TIME_FLOAT" => 1622528958.7374
"REQUEST_TIME" => 1622528958
]

no any database information. i don't understand what i missing please help me.
my operating system is : ubuntu 20.04


#.env file
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data.db"
DATABASE_URL="mysql://root:password@127.0.0.1:3306/main?serverVersion=5.7"
#DATABASE_URL="postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=13&charset=utf8"
###< doctrine/doctrine-bundle ###


#docker-compose.yaml
version: '3.7'
services:
database:
image: 'mysql:latest'
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: main
ports:
# To allow the host machine to access the ports below, modify the lines below.
# For example, to allow the host to connect to port 3306 on the container, you would change
# "3306" to "3306:3306". Where the first port is exposed to the host and the second is the container port.
# See https://docs.docker.com/compose/compose-file/#ports for more information.
- '3306'
Reply

Hey Monoranjan,

Hm, difficult to say what may be wrong. Symfony project should read the env vars from .env files, and if you have .env and .env.local with some env vars inside and run the website in dev mode - you should see them. Where did you "dd($_SERVER);" in your code? in the controller? Well, you may want to also dump $_ENV, i.e. run "dd($_SERVER, $_ENV);" to make sure you don't see env vars in both of them. Do you run the project via Docker or via Symfony built-in web server? Also, what Symfony version do you use in your project? Did you download it from scratch or is it an old project from the past that you upgrade?

Also, you can debug the env vars known to the system with: "bin/console debug:container --env-vars". Do you see any env vars in the output?

Cheers!

Reply

Hey Victor,
I'm having the exact same problem. I don't have a docker-compose.yml in my project but when I run symfony server:start -d I get errors that APP_ENV doesn't exists. I dump my app variables using composer and I can see them, but when I run the symfony binary I get errors, and I can't see my local .env or .env.local .env.test variables

-------------------- ---------------------------------
Symfony
-------------------- ---------------------------------
Version 5.1.11
Long-Term Support No
End of maintenance 01/2021 Expired
End of life 01/2021 Expired
-------------------- ---------------------------------
Kernel
-------------------- ---------------------------------
Type AppØKernel
Environment dev
Debug true
Charset UTF-8
Cache directory ./var/cache/dev (2.3 MiB)
Log directory ./var/log (91 KiB)
-------------------- ---------------------------------
PHP
-------------------- ---------------------------------
Version 7.4.14
Architecture 64 bits
Intl locale en_US
Timezone UTC (2021-06-01T14:51:32+00:00)
OPcache true
APCu false
Xdebug true
-------------------- ---------------------------------

Reply

Hey bclincy!

Hmmm. Ok, something obviously isn't right :). Let's do some debugging!

> when I run symfony server:start -d I get errors that APP_ENV doesn't exists

Can you show me what that error looks like?

> I dump my app variables using composer and I can see them

Which command are you running for this?

> but when I run the symfony binary I get errors, and I can't see my local .env or .env.local .env.test variables

What do you see if you run symfony var:export --multiline?

And if you run symfony version what version do you see?

Let me know and hopefully we can find the issue.

Cheers!

Reply

Hello Mr. Weaver,
The errors are the basic errors, but I shot a screen cast. I did notice that because I had a .env.local.php that it was grabbing data from that when ran the command line: bin/console debug:container --env-vars
I removed that file and it still didn't work.

I did a screen cast so you can see everything in real time:
https://www.icloud.com/iclouddrive/0A7nZ0_Zry3c2oQ53NpvP80HQ#Screen_Recording_2021-06-01_at_6.50.20_PM

> The command to composer dump env vars:
composer dump-env

Version of Symfony: Symfony CLI version v4.23.5 (2021-04-07T05:30:32+0000 - stable)

Symfony var: export
symfony var:export --multiline
export SYMFONY_DOCKER_ENV=
export SYMFONY_TUNNEL=
export SYMFONY_TUNNEL_ENV=

Reply

Hey Brian,

Thanks for providing the video!

Did you download the course project code from SymfonyCasts or are you trying to apply changes on your own project? It seems like your public/index.php is incorrect, probably you upgraded your project to the newer version of Symfony and did wrong changes.

I see you have Symfony v5.1.11. Please, sync your index.php file with this recipe: https://github.com/symfony/... - as you can see it loads autoload.php file first and then .env file *before* accessing any env variables like APP_ENV, APP_DEBUG, etc. from .env files.

So, there's no magic, and this makes sense that you don't have those env vars at the point where you dd($_SERVER) because you do it *before* the code that actually loads them from .env files.

I think if you will sync your index.php with the one from the official recipe - it should work well I suppose.

Cheers!

1 Reply

That worked, thank you Victor!

Reply

Hey Brain,

I'm glad to hear it! Thanks for confirming that the solution works for you.

Cheers!

Reply
Default user avatar
Default user avatar Bertrand Maingault | posted 1 year ago

on Ubuntu 20.04, i followed this tutorial for using docker rootless : https://docs.docker.com/eng...
Unfortunately, it am unable, whatever i try to make symfony detect the ENV variable for docker.
What i did is to set the port in dockercompose.yaml for my database to 3306:3306, hence it always start on this port. I manually specify the database variable in my env file. and it works.
but i am not using the native ability that symfony have to get the variable automatically from docker... if anyone has any advice on how to fix this...i would be glad to hear.

Reply

Hey Bertrand Maingault!

Hmmm, I'm sorry to hear about the trouble! First, good job working around it... even though that's no idea. Here's one thing to try, for debugging purposes. Run:


symfony var:export --multiline

This will print all the env vars that the symfony binary will expose. And, in a perfect world, you would see the Docker stuff here. If they are NOT there, then that's a mystery. If they ARE here... but you don't see them when you load the site, that is a *different* mystery. In that second case, try stopping and restarting the symfony server just in case.

Let me know what you find out - I was JUST testing this on 20.04 last week and things were going smooth for me.

Cheers!

Reply
Default user avatar

Hello guys,

I had the same issue and maybe you had the same as me so I share (because I lost many days on it ^^)
When I typed this :


symfony var:export --multiline

It returns only 3 variables starting by "SYMFONY_", and not my database variable
In fact, if you use a docker image like php-fpm, the default configuration do not pass the env variable you specified in your env file, because the default conf remove those by default with "clear_env" which is set to true, so it remove it.
To do so, what I did is to update by dockerfile of my php-fpm image by setting this


# Allow nginx to pass docker env variables to symfony application
RUN sed -i.bak "s/;clear_env = no/clear_env = no/g" /usr/local/etc/php-fpm.d/www.conf

Then, I rebuilt and restart the docker containers

Hoping it will help :)

2 Reply

Hey @akred!

Thanks for posting this! But I think I need some help to understand better :p.

When you run “symfony var:export”, this finds your running containers (like a database container), and dumps certain env vars based on those. But this should have nothing to do with whether or not you have a web server container running or not. For example, it should see a database container and add some env vars based on it. If it sees any other container it doesn’t care about - like nginx - it would just ignore it.

So I think you’re doing something different than the flow here - like you’re having Docker read your .env file an expose those? Let me know - I was just trying to understand what’s going on in your flow - and help future people know when this solution will help them :).

Cheers!

Reply
Georg H. Avatar
Georg H. Avatar Georg H. | posted 1 year ago

Hi there,
this question is about a second database connection. I configured a second connection in `.env`. This connection works fine in a controller, e.g.:

$conn = $this->getDoctrine()
->getConnection('gso');
$ngso = $conn->fetchArray("SELECT COUNT(*) from gso.persons");

But how can I get a `Repository` that uses this connection? The Doctrine documentation says, that `EntityManager::create()` accepts a connection as it's first argument, but the second argument needs to be a configuration. Can Symfony give me the appropriate configuration object?
Thanks in advance!

Reply
Georg H. Avatar

Some more duckDuckGoing told me that an extra section `entity_managers` has to be configured in `doctrine.yaml` in the section `orm:` (see ourcodeworld). It is important to use a different value for `prefix:` in `mappings:` for the new EntityManager . Then in a Controller this works:

$pn = $this->getDoctrine()
->getRepository(GsPerson::class, 'gso')
->find(211945);

where `gso` is the name of the EntityManager entry in `doctrine.yaml`.

Reply

Hey Georg

It seems like you figured it out but in any case, I'll leave you here the documentation of how to configure multiple EntityManagers on Symfony + Doctrine
https://symfony.com/doc/cur...

Cheers!

Reply
Georg H. Avatar

Hey Diego,
thank you very much. That's exactly what I need!

Greetings!

1 Reply

I'm getting the following error in the browser when I'm running sudo symfony server:start -d and am thinking this is likely do to the aforementioned cache ownership issues. Everything prior to this lesson works fine when running symfony server:start -d, but the docker db stuff doesn't load (ie docker compose is still down and Env Vars is still none in the browser debug toolbar).


This site can’t provide a secure connection
127.0.0.1 sent an invalid response.
ERR_SSL_PROTOCOL_ERROR

Any chance someone could point us in the direction of a solution for this? Just so future folks don't have to spend a bunch of time on Google. Also, is there a flavor of Debian that is better suited to run this stack out of the box?

(I'm using Ubuntu 20.04.1 LTS)

Reply

Hi somecallmetim!

First, apologies for my very slow reply! This was a deep question, so the team left it for me - so that's my fault.

Ok, a few things:

1) Yes, you *can* (as you hopefully have found out) continue the tutorial 100% fine without Docker. Docker is meant to be a "nice option when it makes life easier". But for a variety of reasons, Docker works well for some people, and totally not well for others. Don't sweat it :).

2) About Docker and sudo. I just played around with a fresh Ubuntu 20.04 EC2 instance. I have some answers for all the different behavior you were seeing.

A) using var:export in sudo vs not sudo:

You mentioned that running symfony var:export --multiline (by the way, running this to debug was an excellent idea!) resulted in a ton of SYMFONY_ variables being exported but running this with sudo had a very short list. That actually has nothing to do with the docker situation. Very simple, when you run symfony server:start -d without sudo, then running sudo symfony var:export won't "see" the server. In other words, the short list of variables you saw with sudo is equivalent to what you see if you run symfony var:export with no web server running at all yet. Anyways, I hope that clears up that piece of odd behavior - your different users (normal vs root) apparently track separate web server processes and don't see each other's.

B) The Docker Variables

This... I'm less sure about :/. I would start by doing *exactly* what you were doing: start Docker, start the symfony server, and then running symfony var:export --multiline. If things are working properly, you WILL see the DATABASE_URL environment variable there. If you don't, then you don't even need to fuss around with the web server: it won't work. But if you don't see DATABASE_URL there (it looks like you didn't), I'm not sure what the problem is :/. I DID find to my surprise (because this doesn't happen on my mac) that after starting docker, I needed to restart the Symfony web server before my web app could see the Docker env vars (but this doesn't affect var:export - you should see the env vars there the minute you start Docker). So this part... I admit, is still a mystery to me.

C) This site can’t provide a secure connection

Indeed, this sounds like a certificate problem to me... and it sounds like you "solved" it... except that you got the "Your connection is not private", which you should not. I'm also not sure about this piece - this "just works" on a Mac, but it's possible (and it may depend on your browser, actually) that it doesn't work or needs more work. I think I remember something being special about Firefox possibly... but I can't remember.

Anyways, these are... "half" answers - I wish I could do better. For the symfony binary, I'm a user of it (and I really like it) but not a developer *on* it... so I have less answers than normal. They do, btw, have an issue queue: https://github.com/symfony/...

Cheers!

Reply

Another interesting thing. When I'm running the symfony server without sudo and I run symfony var:export --multiline I get the following. However...

export SYMFONY_APPLICATION_DEFAULT_ROUTE_HOST=127.0.0.1:8000
export SYMFONY_APPLICATION_DEFAULT_ROUTE_PATH=/
export SYMFONY_APPLICATION_DEFAULT_ROUTE_PORT=8000
export SYMFONY_APPLICATION_DEFAULT_ROUTE_SCHEME=https
export SYMFONY_APPLICATION_DEFAULT_ROUTE_URL=https://127.0.0.1:8000/
export SYMFONY_DEFAULT_ROUTE_HOST=127.0.0.1:8000
export SYMFONY_DEFAULT_ROUTE_PATH=/
export SYMFONY_DEFAULT_ROUTE_PORT=8000
export SYMFONY_DEFAULT_ROUTE_SCHEME=https
export SYMFONY_DEFAULT_ROUTE_URL=https://127.0.0.1:8000/
export SYMFONY_DOCKER_ENV=
export SYMFONY_PROJECT_DEFAULT_ROUTE_HOST=127.0.0.1:8000
export SYMFONY_PROJECT_DEFAULT_ROUTE_PATH=/
export SYMFONY_PROJECT_DEFAULT_ROUTE_PORT=8000
export SYMFONY_PROJECT_DEFAULT_ROUTE_SCHEME=https
export SYMFONY_PROJECT_DEFAULT_ROUTE_URL=https://127.0.0.1:8000/
export SYMFONY_TUNNEL=
export SYMFONY_TUNNEL_ENV=

When I'm running the symfony server *with* sudo and I run symfony var:export --multiline I get

export SYMFONY_DOCKER_ENV=
export SYMFONY_TUNNEL=
export SYMFONY_TUNNEL_ENV=

In both cases, the Docker Env isn't set (as opposed to apparently supposed to being 1). It also strikes me as strange that all the path/port Env variables just disappear.

Reply

Side note: tried this with sudo docker-compose up -d and sudo docker-compose down with the exact same results.

Reply

I ran symfony server:ca:uninstall & symfony server:ca:install a couple different times both using sudo and not. End result is now running sudo symfony serve -d does *kind of* work. Now, I get a Your connection is not private error (which I can, of course, bypass). But even when I do bypass that security error the docker db stuff still doesn't load (ie docker compose is still down and Env Vars is still none in the browser debug toolbar). Running symfony serve -d without sudo works without the certificate error, but still doesn't load the docker env vars.

Reply

Gave up and set it up to just run off my local mysql installation. Hopefully this doesn't make things difficult in future parts of the tutorial. :-/

Reply
Tobias I. Avatar
Tobias I. Avatar Tobias I. | posted 1 year ago

If I understand this tutorial correctly, all the data stored in the database will be lost when the container is stopped.

How do we handle deployment with this setup? Do we run docker on the production server as well? What do we do when we need to stop the container, if let's say we need to update?

Reply

Hey Tobias I.!

That's correct! You *can* make the database persist between "shutdowns" with a "volume" (this is something we've considered adding as an option in MakerBundle when generating the code). But, even that doesn't relate to product: production is a whole different animal. I use Docker like this locally for convenience, but I don't use it for production (I use SymfonyCloud, but that's not really important for this conversation).

That's kind of a "non-answer" I realize, but the truth is that I don't run Docker on production. Many people do, but Docker is something that some people love and some people absolutely hate for its complexity. That's why I use it in this "light" fashion: using the easy parts, but not diving into its full power or complexity.

Cheers!

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

This tutorial also works great for Symfony 6!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.4.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "doctrine/doctrine-bundle": "^2.1", // 2.1.1
        "doctrine/doctrine-migrations-bundle": "^3.0", // 3.0.2
        "doctrine/orm": "^2.7", // 2.8.2
        "knplabs/knp-markdown-bundle": "^1.8", // 1.9.0
        "knplabs/knp-time-bundle": "^1.11", // v1.16.0
        "sensio/framework-extra-bundle": "^6.0", // v6.2.1
        "sentry/sentry-symfony": "^4.0", // 4.0.3
        "stof/doctrine-extensions-bundle": "^1.4", // v1.5.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.17.5
        "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.8.0
        "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.4.0
        "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.5.0
    }
}