I am facing an issue where the build process of my Symfony application fails, as explained in many different forums (none recent). For instance:
When doing composer install with --no-dev only the production packages
are installed (as it should be). However when composer launches the
symfony scripts they are launched in development modes and thus start
throwing errors when AppKernel.php can not find packages needed for
development. These scripts should also be executed in production mode!
Quote source
The above Github issue is closed, as it apparently can be fixed by setting the SYMFONY_ENV env variable to the environment of your choice: export SYMFONY_ENV=prod.
I have done that, and calling printenv correctly prints the variable. I can even call the Symfony console php bin/console manually. and it will launch in prod environment.
Success? Seemingly, but no... Calling composer install still forces all scripts to launch in dev environment. What gives?
The root cause appears to be the environment variable not being set globally, so whatever user the commands ended up running as, www-data via my deploy script, or root(as I called sudo composer?) from the console, did not have the environment variable set that I created with my default user.
Adding SYMFONY_ENV=prod on a new line in /etc/environment, and then restarting fixed the issue, and the scripts are now running in prod.
Related
I run different versions of Symfony and PHP on my Mac for various apps I have to work on (sorry that our clients are so slow to get to upgrade), and I'm trying to install the LTS version of Symfony through the CLI documentation recommendations, but I'm trying to get it to use a composer.phar in the folder I run the command in... it keeps defaulting to the globally-installed one.
Sure I could just go change composer's execution path or upgrade/downgrade it temporarily whenever I want to run the cli for x version of PHP, but that's gonna drive me crazy and I'd rather see how to tell it to run a certain composer.phar file. I'm not seeing in the documentation how to do this to get the benefits of the --webapp option.
The documentation is weird on it anyway; I can't tell if running composer directly (as composer.phar) will give me the benefits of the --webapp option using the symfony command (because the composer commands are identical for 'traditional web application' and 'console application or API'):
https://symfony.com/doc/5.4/setup.html#creating-symfony-applications
# run this if you are building a traditional web application
$ symfony new my_project_directory --version=5.4 --webapp
# run this if you are building a microservice, console application or API
$ symfony new my_project_directory --version=5.4
# run this if you are building a traditional web application
$ composer create-project symfony/skeleton:"^5.4" my_project_directory
$ cd my_project_directory
$ composer require webapp
# run this if you are building a microservice, console application or API
$ composer create-project symfony/skeleton:"^5.4" my_project_directory
When I run the install through composer directly, I can't tell if I'm getting the benefits of the symfony command --webapp option... and I'm not seeing an option for the symfony command to specify to use the folder's composer.phar.
I had to cheat a little bit: I installed the latest composer using the instructions here to a composer.phar file:
https://getcomposer.org/download/
I then created a console alias like php composer.phar, ran the Symfony create composer command with that alias, which created the symfony-5 folder no problem, then I copied the composer.phar file to the new folder and run the alias for any other composer commands, like with require webapp, which is working! Kind of nice to freeze a version of composer for any similar repos.
Maybe not the best answer, but it's working.
Also I discovered that I could just run composer self-update to get the latest version, which worked, then composer self-update [whatever version number] to get back to one I need that works with other repos (since certain version ranges just do not work with certain version ranges of PHP). Annoying, but functional.
Ultimately I think moving forward, it's best to make a copy of composer.phar at a compatible version range for your older PHP apps, depending on their versions, and use those in an alias, rather than totally rely on a global composer version, which has proven not completely workable for my work.
Please help, I've tried everything;
The command works well on the development server, but not on live.
Before you mark it as duplicate:
The filename ends with Command.php
The Bundle is registered
The command is ContainerAware
The command is in the Bundle\Command directory and in the App\Bundle\Command namespace
I have tried:
clearing and warming up the cache on the server multiple times using the symfony console php console --env=preprod cache:clear and php console --env=preprod cache:warmup
listing available commands by calling the console without extra arguments php console --env=preprod
Is there any other way to force symfony to re-check available commands ?
For future reference:
The problem was that I connected to the remote host before deploy, and bash doesn't update symlink targets.
So the Command was not available in my current working directory.
A simple cd .., cd current solved it.
I recently deployed a new Symfony 4 project to a prod server where I set (via ssh) both APP_ENV and APP_SECRET among others, as environment variables. Both commands printenv and set list those variables in their output so I assume everything should be fine on that part.
I get an error 500 on the site though, the log returning PHP Fatal error: Uncaught RuntimeException: APP_ENV environment variable is not defined. You need to define environment variables for configuration or add "symfony/dotenv" as a Composer dependency to load variables from a .env file.
What am I missing here ?
[EDIT 2020] --> use the 'symfony/dotenv'
According to the how to deploy official documentation what you can do is to move 'symfony/dotenv' in your composer file from require-dev to require so it's installed also on production environement. Then you can keep using a .env.local file.
If you don't want or can't use the 'symfony/dotenv'
For Apache and on Ubuntu first you need mod_env activated
sudo a2enmod env
sudo service apache2 restart
Then put the environement variable in the .htacess or in the vhost config file. For SF4 the .htacess is in /public and here is the syntax. I don't know if order matter, I would say no, so I added them on the top of the file.
SetEnv APP_ENV prod
SetEnv APP_SECRET fjsdkfj...
SetEnv DATABASE_URL mysql://...
Now some random useful tricks :
You don't want to commit the .htaccess file. Add it to the shared part of your deployment tool. In my case (easy-deploy-bundle)
->sharedFilesAndDirs(['public/.htaccess'])
You'll need to copy the environment variables in /etc/environment so it's available by composer ... this one is a real pain in the ass, because now you duplicated your variables. So the Symfony team said env variable are betters because safer and standard. But duplicate the information is not safer at all. Maybe I'm doing it wrong (which is completly possible). If you know how to avoid this please share.
The printenv command will show you if it's correctly configured.
If you use easy-deploy-bundle for production remove the --quiet option on composer so you have a clear error message if it fail (because it doesn't find the env variable for example). Also check that --no-dev option is here, so it won't install dotenv package.
->composerInstallFlags('--prefer-dist --no-interaction --no-dev')
System variables won’t be available to your web server. The variable should be defined in the vhost/htaccess file. I assume you are using Apache.
if you are using nginx have to defined at the end of pool configuration file.
php5
/etc/php5/fpm/pool.d/www.conf
php7
/etc/php/7.1/fpm/pool.d/www.conf
** EDIT **
For several cases we need to call Symfony commands on a deployed CloudFoundry app. Symfony commands are php scripts which are called with the PHP CLI.
One example is bin/console doctrine:schema:update (but could be user generation, cache clearing etc.)
So for our app we need both, fpm and cli enabled. This is done with:
"PHP_MODULES": [
"fpm",
"cli"]
in options.json.
After connecting to the app with cf ssh I change to app directory and I call php/bin/php doctrine:schema:update this results in a ClassNotFound: PDO issue.
During staging these commands are called successfully.
I checked that for PHP CLI the PDO extension is not available (by checking php -i) although I have mentioned it in options.json.
"PHP_EXTENSIONS": [
...
"pdo",
"pdo_mysql",
...]
How to enable extensions for CLI and FPM on one app? And is it theoretically possible to have different extensions for CLI and FPM and as well different user-php.ini s to fully/particularly override php.ini of CLI and FPM?
So for our app we need both, fpm and cli enabled. This is done with:
"PHP_MODULES": [ "fpm", "cli"]
in options.json.
This is something that we should probably clean up in the build pack. I do not believe it's (PHP_MODULES) actually used any more.
Maybe a year or more ago, the build pack switched how it downloads PHP. It would previously download individual components modules & extensions. Now it just downloads everything at once. This actually ends up being faster since it's one larger download vs many smaller downloads, and bandwidth is generally very fast for build pack downloads.
Worth mentioning that while PHP_EXTENSIONS no longer triggers what to download it is still used in terms of what extensions get enabled in php.ini. Thus you still need to set that or indicate extensions through composer.
After connecting to the app with cf ssh
I believe that this is the issue. You need to source the build pack env variables so that the env is configured properly.
Ex:
vcap#359b74ff-686c-494e-4a1e-46a9c420f262:~$ php
bash: php: command not found
vcap#359b74ff-686c-494e-4a1e-46a9c420f262:~$ HOME=$HOME/app source app/.profile.d/bp_env_vars.sh
vcap#359b74ff-686c-494e-4a1e-46a9c420f262:~$ php -v
PHP 5.6.26 (cli) (built: Oct 28 2016 22:24:22)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
Staging does this automatically as does runtime for your app. Unfortunately cf ssh does not.
UPDATE:
A slightly easier way to do this is to run cf ssh myapp -t -c "/tmp/lifecycle/launcher /home/vcap/app bash ''". This will open a bash shell and it lets the lifecycle launcher handle sourcing & setting up the environment.
And is it theoretically possible to have different extensions for CLI and FPM and as well different user-php.ini s to fully/particularly override php.ini of CLI and FPM?
Sure. By default, we download and install all extensions. Thus you just need a different php.ini (or some other setting to enable that extension) in which you enable your alternate set of extensions.
When you cf ssh into the container, you could copy the existing php.ini somewhere else and edit it for your CLI needs. Then reference that php-alt.ini when you run your CLI commands.
Never did this but does enabling the php cli in PHP_MODULES (https://docs.developer.swisscom.com/buildpacks/php/gsg-php-config.html) help?
I am trying to install Symfony 2.1.3 (latest). I am running composer and installs everything okay. The only error that I get is:
Script Sensio\Bundle\DistributionBundle\Composer\ScriptHandler::clearCache
handling the post-install-cmd event terminated with an exception
[RuntimeException]
An error occurred when executing the "'cache:clear --no-warmup'" command.
It's being installed under www folder. I am running nginx and followed the composer approach. I read on internet that apache should be run manually not as a service, however I am using nginx instead. Does apache still have any bearing on it? I'm using debian squeeze.
Edit: As per AdrienBrault's suggestion the error was because the timezone was not set in the php.ini. Only with --verbose I could see the warning. Thanks guys.
Apache is not related - PHP is called via command line.
Most likely is the permission in the cache folder: did you check if the user that runs the composer update can actually write the cache folder?
Try to manually run rm -Rf app/cache/dev (for production environment replace dev with prod) and see if you get any permission error.
Also you will get this error if the default.timezone setting is not configured in php when running in CLI. To verify just run
php --info | grep timezone
and check that the setting date.timezone is correctly configured.
On the security side, setting 777 to the folder is not the optimal solution - if you have ACL enabled you could use that to correctly set up the permission for the cache and logs folder. Read more at the Symfony2 official installation page
I had this same issue for a while and after hours of face to brick wall pounding I realized... I have a .gitmodule in my project, and on initial checkout these submodules are NOT initialized and as such are not there for your composer to update, which results in the above error.
Make sure you run the following
git submodule update --init src/Acme/Sadness/Bundle
of course replace src/Acme/Sadness/Bundle with YOUR project namespace.
Hope this helps someone not go through the same pain I just did.
If you have vendor folder already I would remove it and install symfony 2.1.3 again via "composer.phar install". Problem might be coming from outdated version of composer
I had the same problem and I resolve in this way.
execute this on the console
and you should see something like this
$ locate php.ini
/etc/php5/apache2/php.ini
/etc/php5/cli/php.ini
/etc/php5/fpm/php.ini
the first line is probably your php.ini that appear when you do a phpinfo();
the problem is that when you execute composer update this no check the same php.ini
in my case the second line
all my sites work fine but always I had problems not now
after edit the second file and put the same time zone that you set in the first one
run
$ sudo service apache2 reload
and now
$ composer update
I hope that this work for you like work for me
regards
Emiliano