cachix / devenv

Fast, Declarative, Reproducible, and Composable Developer Environments
https://devenv.sh
Apache License 2.0
4.46k stars 335 forks source link

How are the MySQL sockets getting read by PHP? #1494

Open Nebucatnetzer opened 1 month ago

Nebucatnetzer commented 1 month ago

I see that there is a reference to the environment variables but when I look at the generated ini file the actual lines don't contain a value. https://github.com/cachix/devenv/blob/main/src/modules/languages/php.nix#L323-L325

We the mysql service enabled and running.

We recently had a case where a child PHP process wasn't able to access the database. It was called within PHP like this exec("php ./somefile.php") but the code in somefile.php wasn't able to access the database until we set the following in the ini section of devenv. So I was a bit surprised to discover that the variables are already present in the devenv code. One thing I noticed is that the parent PHP process is able to access the DB without a problem, only the child doesn't see the env variables.

pdo_mysql.default_socket="${config.env.MYSQL_UNIX_PORT}"
mysqli.default_socket = "${config.env.MYSQL_UNIX_PORT}"
MrHamel commented 1 month ago

It sounds like environment variables are not getting passed through. Is there a difference if ran with PHP's shell_exec function?

Is there a possibility that somefile.php could be modified so that it can fit into something that works with include/require instead? Another option (although admittedly very dangerous), is create a function that reads a file into a string variable, and evals it.

Nebucatnetzer commented 1 month ago

It sounds like environment variables are not getting passed through. Is there a difference if ran with PHP's shell_exec function?

No that didn't help.

Is there a possibility that somefile.php could be modified so that it can fit into something that works with include/require instead? Another option (although admittedly very dangerous), is create a function that reads a file into a string variable, and evals it.

It's legacy code which we would rather not touch.

sandydoo commented 1 month ago
pdo_mysql.default_socket="${config.env.MYSQL_UNIX_PORT}"
mysqli.default_socket = "${config.env.MYSQL_UNIX_PORT}"

I don't use php, but this is a totally reasonable solution. I imagine the only reason this wasn't done in the first place was to make the env var the single "source of truth" for the port.

@shyim, do you have any ideas/thoughts on this?

shyim commented 1 month ago

you could inline the env var in the ini if it's not changing 🤔, but yea MYSQL_UNIX_PORT is respect by mysql itself too

Nebucatnetzer commented 1 month ago

I think there is a bit of a misunderstanding here. The configuration I've shown works perfectly fine and is the way I fixed the problem.

However I discovered that in devenv PHP is already configured in a way that it should get the values from the environment variable MYSQL_UNIX_PORT. Which then led me to the question that I posted here. Why can a sub-process of PHP-FPM not see/use the environment variable? Hard-coding value into the config worked so it is using the same ini file.

Edit: This isn't a problem either, I'm just trying to understand how things are working together.