gstreamer0.10-ffmpeg
gstreamer0.10-plugins-good
packages.
We have a Docker database container running and our app is instantly configured to talk to it thanks to the Symfony web server. But... we can't really do anything yet... because that MySQL instance is empty! In var:export
, you can see that the database name is apparently "main". But that does not exist yet.
No problem! When we installed Doctrine, it added a bunch of new bin/console
commands to our app. Run:
php bin/console
and scroll up to find a huge list that start with doctrine:
. The vast majority of these are not very important - and we'll talk about the ones that are.
One of the handy ones is doctrine:database:create
, which reads the database config and creates the database. So, in our case, it should create a database called main
.
Ok! Copy the command name and run:
php bin/console doctrine:database:create
And... yikes!
Access denied for db_user at localhost.
Huh. For some reason, it's using this DATABASE_URL
from .env
instead of the one that's set by the Symfony binary.
... lines 1 - 27 | |
DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7 | |
... lines 29 - 30 |
The problem is that, when you load your site in the browser, this is processed through the Symfony web server. That allows the Symfony binary to inject all of the environment variables.
But when you just run a random bin/console
command, that does not use the symfony binary. And so, it does not have an opportunity to add the environment variables.
No worries! There is, of course, a solution. Instead of running:
php bin/console
We'll run:
symfony console
symfony console
literally means bin/console
... but because we're running it through the Symfony executable, it will inject the environment variables that are coming from Docker.
Tip
The latest version of MakerBundle generates a MYSQL_DATABASE: main
config
into your docker-compose.yaml
file. If you have this, then the database will
already be created! Feel free to run the command just in case ;).
So:
symfony console doctrine:database:create
And... boom! We have a database!
Before we jump into fun stuff like generating entities and database tables, I want to tighten up one more thing. Open up docker-compose.yaml
. The :latest
next to the image means that we want to use the latest version of MySQL. Where does that image come from?
... line 1 | |
services: | |
database: | |
image: 'mysql:latest' | |
... lines 5 - 13 |
Google for Docker hub to find https://hub.docker.com. When you say that you want a mysql
image at version latest
, Docker communicates back to Docker Hub to get the details. Search for MySQL for all the info about that image including the tags that are currently available. Right now, the latest
tag is equal to 8.0.
Head back over to docker-compose.yaml
. You don't have to do this, but I'm going to change latest
to 8.0
so that I'm locked at a specific version that won't suddenly change.
... line 1 | |
services: | |
database: | |
image: 'mysql:8.0' | |
... lines 5 - 13 |
Over at the terminal, even though latest
and 8.0
are technically the same image, let's restart docker-compose
anyways to update the image. Run:
docker-compose down
And then:
docker-compose up -d
It quickly downloaded the new image... which was probably just a "pointer" to the same image we used before.
Tip
In newer versions, the server_version
config may not be in your doctrine.yaml
file,
but you can add it manually.
Now that we've set the MySQL version in Docker, we should also do the same thing with Doctrine. Open up config/packages/doctrine.yaml
. See that server_version
key?
doctrine: | |
dbal: | |
... lines 3 - 4 | |
# IMPORTANT: You MUST configure your server version, | |
# either here or in the DATABASE_URL env var (see .env file) | |
#server_version: '5.7' | |
... lines 8 - 19 |
Set this to 8.0. If you're using mariadb, you can use a format like mariadb-10.5.4
.
doctrine: | |
dbal: | |
... lines 3 - 6 | |
server_version: '8.0' | |
... lines 8 - 19 |
This is... kind of an annoying thing to set, but it is important. It tells Doctrine what version of MySQL we're running so that it knows what features are supported. It uses that to adjust the exact SQL it generates. Make sure that your production database uses this version or higher.
Next, let's create our first database table by generating an entity.
Hey MattWelander,
You probably need to specify those collate and collation options in the DATABASE_URL
since you're using Doctrine configuration this way. I'm afraid that DATABASE_URL
may overwrite your config you do in the doctrine.yaml
.
Also, I'd would still recommend using the default utf8mb4
and utf8mb4_unicode_ci
for your database - that still should handle your special chars as well IIRC. And btw, are you sure the collate is correct? Because it seems you wrote collation value in the collate, I think the correct collate
should be utf8mb4
- probably something that would be good to try.
And btw, make sure you cleared the cache and re-created DB from scratch (or create migrations for this) to apply the changes, otherwise it will take no effect.
Cheers!
Now, bin/console simply throws this error:
PHP Fatal error: Cannot declare interface Stringable, because the name is already in use in /Users/ashatou/Work (Local)/2. Personal/11. Learning/Symfony/SymfonyCast/code-symfony5-doctrine/code-symfony5-doctrine/start/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php on line 3
Fatal error: Cannot declare interface Stringable, because the name is already in use in /Users/ashatou/Work (Local)/2. Personal/11. Learning/Symfony/SymfonyCast/code-symfony5-doctrine/code-symfony5-doctrine/start/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php on line 3
Symfony\Component\ErrorHandler\Error\FatalError {#227
#message: "Compile Error: Cannot declare interface Stringable, because the name is already in use"
#code: 0
#file: "./vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php"
#line: 3
-error: array:4 [
"type" => 64
"message" => "Cannot declare interface Stringable, because the name is already in use"
"file" => "/Users/ashatou/Work (Local)/2. Personal/11. Learning/Symfony/SymfonyCast/code-symfony5-doctrine/code-symfony5-doctrine/start/vendor/symfony/polyfill-php80/Resources/stubs/Stringable.php"
"line" => 3
]
}
Don't know what I have done and how to decipher this lovely error message 🤔
This is really frustrating. I cannot even follow up with the course. The whole thing is messed up. You started the first course saying that Symfony is lean and mean. It is mean. I have been developing for Node.js for several years now and I have never faced such amount of errors every single step I am trying to do anything. And it has nothing to do with using old version of Symfony. It is "Symfony" that's full of issues regardless the version. Anyone who has developed on Node knows what I mean. With all due respect, and after spending a week with Symfony, Symfony simply sucks. And all the s**t about it saving times with bin/console commands is wasted on fixing errors even the masters in the community get puzzled by.
I will give it another try. I will keep on searching trying to fix it. But overall experience is really bad.
(Note for the instructor: I like how you're passionate about the topics 🙂 I really do. But it doesn't make any sense when explaining Symfony. I'd love to see courses from you on Node, Docker, K8s, ElasticSearch, AWS, Android, etc. Seriously - you're good.)
I received this error when I want to run: symfony console doctrine:database:create
In ExceptionConverter.php line 98:
An exception occurred in the driver: SQLSTATE[HY000] [2002] No connection could be made because the target machine actively refused it
In Exception.php line 26:
SQLSTATE[HY000] [2002] No connection could be made because the target machine actively refused it
In Connection.php line 34:
SQLSTATE[HY000] [2002] No connection could be made because the target machine actively refused it
Can you help me?
Hey @Trainee,
Yeah that's an annoying issue and that was already discussed here. Check this thread https://symfonycasts.com/sc... for the solution! I hope that will help!
Cheers!
I offen see the message "A network error caused the media download to fail part-way."
And I need to refresh the page for continue watching the video.
It didn't be before.
Can you fix this?
Hi dzianisr
Thanks for reporting this. We're aware of the problem and we're working together with our video hosting provider (it seems like this problem is coming from their end). My truly apologies for any incovenience you may have
Hello there
First of all I totally love your tutorials and I've learned a lot so far.
You mention that the server version needs to be set. As far as I can see there is a MYSQL_MAJOR environment variable in docker which shows '8.0' for me. Wouldn't it be possible for symfony cli to read that from docker? I would guess other variables like 'DATABASE_PASSWORD' are already filled by symfony by reading it from docker. Then you could set server_version
in doctrine.yaml
to something like %env(DATABASE_VERSION)%
in the generated file, so it's default configured to use the docker environment variable if set by symfony cli or a 'DATABASE_VERSION' variable that is set in .env(.*).
Maybe this is already considered by the symfony team. In that case: is it already implemented in current versions of symfony/doctrine?
Hey Bytenex,
Yes, sure, you can read any env vars from inside the Symfony, try "%env(MYSQL_MAJOR)%" for the server_version it should work. Or, you can take a look at "resolve:" env var processor: https://symfony.com/doc/cur... - in case you want to use container parameters in your env var.
Not sure if it's already implemented in Symfony in any way, most probably no, because I can't find any mention of MYSQL_MAJOR
Cheers!
Hey victor ,
you are right. I also tried to look it up but found no real documentation on this, but when using a generated docker-compose.yaml file (from symfony console make:docker:database) it shows up in my docker dashboard.
My idea was that if the generated doctrine.yaml included the %env(DATABASE_VERSION)% as default then it would be possible to let symfony cli read that from the running docker container, like it does with other variables. That would help make stuff simpler because there would be no need to set the server_version manually. It could also be set by an .env file depending on the server the code is deployed to. With hard-coding the value into the doctrine.yaml it makes it less flexible. Don't know if this is a design choice.
I just wanted to point that out so it may get implemented in a future release of symfonycli and doctrine.
(P.S.: I don't really know how to contribute to symfonycli or doctrine but I know that victor is closely related to both projects that's why I though I mention it here and it may get passed to the right people)
Hey Bytenex,
Yeah, idea sounds valid to me at the first sight, not sure why it wasn't implemented yet, probably some design choice. Anyway, thank you for sharing this idea!
Cheers!
Hello guys,
when I run : symfony console doctrine:database:create
I have 3 red messages :
An exception occurred in driver: SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client
SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client (n Exception.php line 18:)
SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client (In PDOConnection.php line 38:
)
please need help
Hey Albert G.!
Yes, I know this issue - it's super annoying! There is a thread on this page - https://symfonycasts.com/sc... - where we talk about ways to debug this. I wish I knew a bit more about why some people get this error and not others (when using Docker... where things should all be the same).
Let me know if that other thread helps.
Cheers!
for me is not working, always is throwing the error
In AbstractMySQLDriver.php line 106:
An exception occurred in driver: SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client
In PDOConnection.php line 31:
SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client
In PDOConnection.php line 27:
SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client
In PDOConnection.php line 27:
PDO::__construct(): The server requested authentication method unknown to the client [caching_sha2_password]
Hey m3tal
I'm interested if this works... but I'm also interested in what the root cause is. We're all using Docker and presumably the same version of MySQL.
What version of PHP are you all using? I am finding some info that you need 7.1.16 or higher or 7.2.4 or higher (or any version of 7.3 and 7.4) in order to have a version of PHP that understands the new way to authentication with MySQL. I'm hoping someone with this problem can confirm whether or not they're using an older PHP version... though I think it's unlikely, as Symfony itself should be requiring 7.2.5 or higher.
Btw, another workaround may be to run inside MySQL:
ALTER user 'root'@'%' identified with mysql_native_password by 'password';
Cheers!
Hello I had the same Error but your tip with
ALTER user 'root'@'%' identified with mysql_native_password by 'password';
works fine THX
at the point:
symfony console make:migration
I get the same error as @bogdan macsim
I tried everything above but I can't get any further and can't migrate.
Using PHP version: PHP 7.3.22
Hey,
If you run any other command related to Doctrine and the database like `doctrine:schema:update` does it work? What Database are you using? Double check your connection string and if you're using 127.0.0.1 as the domain, try changing it to localhost
Cheers!
Hey,
it's the same issue with "doctrine:schema:update". Im using mysql.
after I started my database container with docker-compose up -d
im running the following command with the correct port to check if the Database is ready.
mysql -u root --password=password --host=127.0.0.1 --port=32773
landing on the command line I "exit" it and try "symfony console doctrine:migrations:migrate". Getting the
"In AbstractMySQLDriver.php line 128:
An exception occurred in driver: SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client"
Cheers
Hi All, I had the same problem, it was fixed by running the command Ryan wrote above:ALTER user 'root'@'%' identified with mysql_native_password by 'password';
I have PHP 7.3.13 and still got the error.
Hey Beleiu,
Let me clarify, did the "ALTER user" command help you? Or you still have problems? Can you tell me if the MySQL username that you use in your DB credentials is the "root"? If the username is different - you should replace "root" by the username you use in the command above.
If you still have the error - could you cope/paste the exact error again, please?
Cheers!
Hi Ryan.
My setup is PHP CGI 7.3.18
mysql Ver 8.0.21 for Linux on x86_64 (MySQL Community Server - GPL)
Docker 2.3.0.4
Your workaround may work also.
I have installed the docker just like you have made it in the video. but when I have use the command to make the migrations, I got an error, that I pasted to you there.
I saw that the user root dot have the privilege for login from 127.0.0.1, only from localhost and is refusing the connections.
Hey m3tal!
Thanks for the reply with more info - and my apologies for my VERY slow reply! So, it's definitely not a PHP version problem... I thought not, but you have confirmed that for me :).
I saw that the user root dot have the privilege for login from 127.0.0.1, only from localhost and is refusing the connections.
This is very interesting. Where did you see this? If I get into the MySQL terminal and run SHOW GRANTS
, I see a bunch of grants, but all to root@%
(so, root from any hostname). Do you see something different?
Thanks for the added info - there is clearly not something "right" on certain systems, and I'd really like to figure out what it is.
Cheers!
Thanks guys, tried this and a bunch of other stuff, just not worth the hassle. XAMPP just gunna have to work for me :)
edit: this is Neech, posted anon and created account afterwards
Hey Bogdan,
Glad you got it working! Looks like removing stopped service containers with any anonymous volumes attached helped you. Thanks for sharing your solution with others.
Cheers!
Hello !
Is there a way to make all this things work in parallel with "vue-cli-service serve" ? I'm building an API on Symfony and a Frontend on VueJS and the symfony local server + proxy is breaking my VueJS app server =(
Hey Nathan D.
But why it's conflicting? If it's port conflict, then use different port for symfony cli server with --port=8081
option! Or you can change vue-cli-service port. It's all up to you! =)
Cheers!!!
Hey sadikoff,
It's not a port conflict.
API : https://api.alfred.local (Symfony)
FRONTEND: https://alfred.local (vueJS)
1- I start the proxy by "symfony proxy:start"
2- I start the server of my API by "symfony server:start". So at this step everything working and my API is accessible on api.alfred.local (I have attached the domain before)
3- I start the frontend by "yarn serve" (which is vue-cli-service serve). At this point my APi is still working but on my frontend (alfred.local) I got this error from the Local Server of my Symfony API :
#The "alfred.local" hostname is not linked to a directory yet.
# Link it via the following command:
symfony proxy:domain:attach alfred --dir=/some/dir
I followed the Symfony doc for the proxy, so I excluded my alfred.local from my proxies setup. But it seems to not works. Chrome still catching my frontend domain with the symfony proxy
Do you have any idea on what is happening ?
Still searching a way to up my frontend and my API on the same domain. (Cookie based authentication)
I already have a full docker setup that is working but it's so slow on MacOS that I need to find another way ... I'm loosing so much time at every refresh.
Hey Nathan D.
Yeah I understand your problem it's really cause a lot of time spending.n Have you tried clicking on Re-apply settings button on the chrome://net-internals/#proxy page to completely reset chrome proxy settings? How exactly you excluded your domain from proxy settings?
Cheers!
Hey sadikoff
chrome://net-internals/#proxy : already tried but nothing change
I'm excluding domain from my MacOS settings like recommended in the Symfony doc : https://symfony.com/doc/cur...
Didn't find a solution for now ... I switched to symfony server and working on the default localhost:8000, so much time saved compare to Docker =D
I think you can replicate that by creating a new symfony project and a new VueJS project using command for both. Pretty sure you gonna be facing the same issue as me if you try to run both at same time and on the same domain (prod like).
Thanks for the time you take helping on that issue ;)
Cheers!
Hey Nathan D.
Sorry for such big delay, I really can reproduce your error, but I'm not sure about the reason of such behavior. I'll advise you to post your issue here https://github.com/symfony/...
Cheers!
Hi,
Apparently it's not necessary to docker-compose down
before docker-compose up
;)
Don't hesitate to tell me if this could be a problem.
Cheers!
Hey Steven
If you don't have any Docker instance up, then yeah, it shouldn't be necessary to do that and I don't think it would cause any problems
Cheers!
As someone who has tried docker and given up multiple times, this looks very promising. I was left with some questions:
1. How to persist the database between docker-composer up/down (I believe this involves docker volumes)?
2. How to configure a custom my.cnf?
3. How to use a different database name?
4. Further to above, how to use a separate database for tests?
Hello Kevin,
If you are using MYSQL, put this line inside your docker-compose.yml :
volumes:
- .docker/data/mysql_db:/var/lib/mysql:cached
Don't forget to remove .docker/data folder from your git. In your .gitignore put that ;)
.docker/data/*
Hey Kevin B.!
Sorry for the slow reply... that's what you get for (A) being friends with me and (B) asking good questions. Lucky you!
- How to persist the database between docker-composer up/down (I believe this involves docker volumes)?
You have this answer below. Yes, it involves volumes... and it is maybe a feature we should add to the maker (maybe as an option).
- How to configure a custom my.cnf?
Hmm. What types of things to you configure in my.cnf? So, this totally is possible... and it's possible (of course) in 10 different ways :p. The default my.cnf
path is /etc/mysql/my.cnf
, so I believe you could add this as a volume so that you could edit it locally. But, more likely, you may need a Dockerfile so that you can COPY in a my.cnf
that you have in your app into the above path. So... yes, this is where Docker gets more complex ;). And the goal of the maker command is to make it easy for people to solve the 98% of situations they will have. I'm not sure yet if a custom my.cnf is a common problem or not. And, I think solving it would make the generated config more complex (the classic trade-off), so I'm not sure if we should do anything with this or not yet. But yea, it IS possible to customize this, but it takes more work.
- How to use a different database name?
So THIS is the one current problem with this setup. Because the symfony binary exposes DATABASE_URL as a real env var, you cannot override it in .env.test, for example. I currently solve this by adding a second container called database_test, then override the doctrine.dbal.url
to read DATABASE_TEST_URL
in config/packagest/test/doctrine.yaml
. But, this is a hack ;). The real solution will be to do nothing more than override the doctrine.dbal.dbname
config in config/packagest/test/doctrine.yaml
to override just the database name to be something different. Unfortunately, this doesn't work yet ad the url
key takes precedence over dbname
:/. After chatting internally, I'm going to propose that this is reversed in DoctrineBundle. Then we can ship a recipe with a test Doctrine config to fix this out-of-the-box.
- Further to above, how to use a separate database for tests?
Do you mean more than just a different database name? Do you mean, like a different database container? Or even Sqlite? In both cases, the situation is (actually) fairly straightforward: you'll need to create a custom config/packagest/test/doctrine.yaml
and set whatever config you want there. You won't be overriding any env vars or anything like that: just changing your test config to use whatever database you need.
Let me know what you think :).
Cheers!
Hi, weaverryan weaverryan :disqus
I have question about runing tests. When i run "symfony console *****" env enviroment param DATABASE_URL is set automaticly with correct database port. But when i run "php bin/phpunit" enviroment variable DATABASE_URL in .env.test not set automaticaly. I must everytime change port in DATABASE_URL which it is different every run . Is it some other better way ? Thanks for help :)
Hey Michal N.
When you run your tests what's the value of your APP_ENV variable? Double check that you have set it to "test" in your phpunit.xml
file, then, in your doctrine.yaml
config file for the test environment double-check that you have this config
doctrine:
dbal:
# "TEST_TOKEN" is typically set by ParaTest
dbname_suffix: '_test%env(default::TEST_TOKEN)%'
Cheers!
Hey MolloKhan
I am very glad for your answer. I know how you thing it, but your solution only work for classic situation. Classic situation when i have classic database on local computer but, I use docker container with database. When I use "symfony console something" then apply symfony binary and symfony automatic get data for docker - name port etc from docker-compose.yaml + pick port which is different for each session.
When i use "php bin/phpunit" no load symfony binary and dont automatic pick data about port which is different for each docker session. I must add "hack" code into tests/boostrap.php php where i get actual port for run docker container by name.
I try find better option but i dont finded anything :(
// 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
}
}
am trying to have symfony doctrine generate my database with Swedish collation (otherwise the sorting of characters åäö gets all messed up).
I put this in my config file, but it seems to have no effect.
doctrine:
All tables (and fields) get created with utf8_unicode_ci (nothing that I chose btw, it seems to be the standard). The weird thing is that if I manually change the collation of a DB table (or just a single field), doctrine is very quick to change it back to the default.
So if I manually set utf8_swedish_ci, the next time I run doctrine:schema:update it will change the table back to utf8_unicode_ci.
Am I using the wrong setting? Does it need to be defined somehow explicitly for every single field? (I'd like to keep it internationally-ready so I want to be able to set it in one single place for when I make specific language-deployments later).