If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeOur app is currently running in the dev
environment. Let's switch it to prod
... which is what you would use on production. Temporarily change APP_ENV=dev
to prod
:
... lines 1 - 15 | |
###> symfony/framework-bundle ### | |
APP_ENV=prod | |
... lines 18 - 20 |
then head over and refresh. Whoa! The web debug toolbar is gone. That... makes sense! The entire web profiler bundle is not enabled in the prod
environment.
You'll also notice that the dump from our controller appears on the top of the page. The web profiler normally captures that and displays it down on the web debug toolbar. But... since that whole system isn't enabled anymore, it now dumps right where you call it.
And there are a lot of other differences, like the logger, which now behaves differently thanks to the configuration in monolog.yaml
.
The way pages are built has also changed. For example, Symfony caches a lot of files... but you don't notice that in the dev
environment. That's because Symfony is super smart and rebuilds that cache automatically when we change certain files. However, in the prod
environment, that doesn't happen.
Check it out! Open up templates/base.html.twig
... and change the title on the page to Stirred Vinyl
. If you go back over and refresh... look up here! No change! The Twig templates themselves are cached. In the dev
environment, Symfony rebuilds that cache for us. But in the prod
environment? Nope! We need to clear it manually.
How? At your terminal, run:
php bin/console cache:clear
Notice it says that it's clearing the cache for the prod environment. So, just like how our app always runs in a specific environment, the console commands also run in a specific environment. And, it reads that same APP_ENV
flag. So because we have APP_ENV=prod
here, cache:clear
knew that it should run in the prod environment and clear the cache for that environment.
Thanks to this, when we refresh... now the title updates. I'll change this back to our cool name, Mixed Vinyl
.
Let's try something else! Open up config/packages/cache.yaml
. Our cache service currently uses the ArrayAdapter
, which is a fake cache. That might be cool for development, but it won't be much help on production:
framework: | |
cache: | |
... lines 3 - 10 | |
app: cache.adapter.array | |
... lines 12 - 25 |
Let's see if we can switch that back to the filesystem adapter, but only for the prod
environment. How? Down here, use when@prod
and then repeat the same keys. So framework
, cache
, and then app
. Set this to the adapter we want, which is called cache.adapter.filesystem
:
framework: | |
cache: | |
... lines 3 - 10 | |
app: cache.adapter.array | |
... lines 12 - 20 | |
when@prod: | |
framework: | |
cache: | |
app: cache.adapter.filesystem |
It's going to be really easy to see if this works because we're still dumping the cache service in our controller. Right now, it's an ArrayAdapter
. If we refresh... surprise! It's still an ArrayAdapter
. Why? Because we're in the prod environment... and pretty much any time you make a change in the prod
environment, you need to rebuild your cache.
Go back to your terminal and run
php bin console cache:clear
again and now... got it - FilesystemAdapter
!
But... let's reverse this config. Copy cache.adapter.array
and change it to filesystem
. We'll use that by default. Then at the bottom, change to when@dev
, and this to cache.adapter.array
:
framework: | |
cache: | |
... lines 3 - 10 | |
app: cache.adapter.filesystem | |
... lines 12 - 20 | |
when@dev: | |
framework: | |
cache: | |
app: cache.adapter.array |
Why am I doing that? Well, that literally makes zero difference in the dev
and prod
environments. But if we decide to start writing tests later, which run in the test environment, with this new config, the test environment will use the same cache service as production... which is probably more realistic and better for testing.
To make sure this still works, clear the cache one more time. Refresh and... it does! We still have FilesystemAdapter
. And... if we switch back to the dev
environment in .env
:
... lines 1 - 15 | |
###> symfony/framework-bundle ### | |
APP_ENV=dev | |
... lines 18 - 20 |
and refresh... yes! The web debug toolbar is back, and down here, we are once again using ArrayAdapter
!
Now, in reality, you probably won't ever switch to the prod
environment while you're developing locally. It's hard to work with... and there's just no point! The prod
environment is really meant for production! And so, you will run that bin/console cache:clear
command during deployment... but probably almost never on your local machine.
Before we go on, head into VinylController
, go down to browse()
, and take out that dump()
:
... lines 1 - 12 | |
class VinylController extends AbstractController | |
{ | |
... lines 15 - 32 | |
'/browse/{slug}', name: 'app_browse') ( | |
public function browse(HttpClientInterface $httpClient, CacheInterface $cache, string $slug = null): Response | |
{ | |
$genre = $slug ? u(str_replace('-', ' ', $slug))->title(true) : null; | |
$mixes = $cache->get('mixes_data', function(CacheItemInterface $cacheItem) use ($httpClient) { | |
$cacheItem->expiresAfter(5); | |
$response = $httpClient->request('GET', 'https://raw.githubusercontent.com/SymfonyCasts/vinyl-mixes/main/mixes.json'); | |
return $response->toArray(); | |
}); | |
return $this->render('vinyl/browse.html.twig', [ | |
'genre' => $genre, | |
'mixes' => $mixes, | |
]); | |
} | |
} |
Okay, status check! First, everything in Symfony is done by a service. Second, bundles give us services. And third, we can control how those services are instantiated via the different bundle configuration in config/packages/
.
Now, let's go one important step further by creating our own service.
Hey @Domingo987
That's odd. From the error, I believe you're not loading the TwigBundle
for the prod environment. Check your bundles.php
file to see if it loads that bundle. Also, I may recommend to re-install your vendor directory
Let me know if that helped. Cheers!
Thanks for suggestions but nothing will work. I've done a composer update, I've checked the bundles, cleared the caches.
I work with Symfony since Symfony 4. Its the first time that the prod environement will not work as the dev.
I put here the log :
[PHP-FPM ] {"message":"Authenticator does not support the request.","context":{"firewall_name":"main","authenticator":"App\\Security\\UtilisateurAuthenticator"},"level":100,"level_name":"DEBUG","channel":"security","datetime":"2023-05-09T08:00:22.966375+00:00","extra":{}}
[PHP-FPM ] {"message":"Uncaught PHP Exception Twig\\Error\\SyntaxError: \"Did you forget to run \"composer require symfony/twig-bundle\"? Unknown function \"dump\" in \"actualites/actu_detail.html.twig\".\" at /Users/symfony6/town/vendor/symfony/twig-bridge/UndefinedCallableHandler.php line 93","context":{"exception":{"class":"Twig\\Error\\SyntaxError","message":"Did you forget to run \"composer require symfony/twig-bundle\"? Unknown function \"dump\" in \"actualites/actu_detail.html.twig\".","code":0,"file":"/Users/Sites/symfony6/town/vendor/symfony/twig-bridge/UndefinedCallableHandler.php:93"}},"level":500,"level_name":"CRITICAL","channel":"request","datetime":"2023-05-09T08:00:23.532817+00:00","extra":{}}
[Web Server ] May 9 10:00:23 |ERROR | SERVER GET (500) /actualite/first-time ip="127.0.0.1"
Thanks for any suggestions
Interesting... Have you checked your config and service files for some weird, prod-specific config? If that's not the case I believe the error message is misleading. Try disabling xDebug, it sometimes causes a weird behavior
I am an "end user". I have started a new project from scratch. For the moment the dev and the prod work both well.
Thanks for your help.
Hi team,
I'm absolutly disappointed. Since 2 dys I try to install py project on a server (Website). I respect all in how to deploy, and no css, js... . I use webpack encore and commands "yarn encore production" & "yarn build run" works fine in my computer. Have you an idea? (I clear cache php bin/console cache:clear --env=prod and delete folder "cache" before sftp transfert)
Thank' in advance
For completed I note that webpack doesn't point in the good directory : in console error it search build directory at the root, and in reality it could be find in public directory. How solve this? To solve this for the moment I make a copy of build in root directory. It works but it's not the solution. I have no subsdirectory.
Many thanks
Hi @Delenclos-A!
I'm absolutly disappointed.
Well, we don't want that. So let me see if I can help :). And yes, I think I can see the problem! We CAN solve this problem with a tweak in your Webpack config. But actually, I can suggest a (hopefully) better solution overall for you.
Ok, so the site is installed at http://potcommun.lamih.fr/public/login
. The key thing I notice is that the public
directory is in the URL. Even ignoring Webpack, that isn't ideal. I'm guessing it would be much nicer to just have the URL be http://potcommun.lamih.fr/login
. This would also fix the Webpack problem.
On your host, you probably have a document root directory which is available to the public - let's pretend it is /var/www
. And so, you've deployed your app into this directory. This means you have a /var/www/public
directory with your application's index.php
inside of it. That's why you need to have the extra /public
in the URL: that executes the /var/www/public/index.php
file.
To remove the extra public, you have 2 options:
1) If you have access to your server configuration (e.g. Apache, Nginx, etc) and are able to, you could change the "document root" from /var/www/
to /var/www/public
. This is really the only directory that should be public (right now, your entire project source is public - e.g. https://potcommun.lamih.fr/webpack.config.js
2) Or, an often easier way is to use a symbolic link. That looks like this:
A) Deploy your app to some OTHER directory that is NOT served by your web server - e.g. ~/potcommun
.
B) Delete the web root - so literally rm -rf /var/www
C) Create a symbolic link from /var/www
to /potcommun/public
. The command is:
cd /var
ln -s ~/potcommun/public www
With this setup, your document root will STILL be /var/www
. But that is a symbolic link to the public/
directory of your app.
Please let me know if this helps!
Hi, great answer. Thank's to take time to help symfony's community. It works fine. I've changed the document root and it's just magic.
Have a good day and Thank's
In my environment, switching to prod does not show any dump on top of the page as in your video
Hey @Anatolie
I'm guessing you forgot to clear the cache for the prod environment. Could you double-check that?
Cheers!
When I just switch to 'prod', I get a 500 error, turns out I need to clear cache first before switching to 'prod', the steps are:
php bin/console cache:clear
.env
file to switch to 'prod'Hey @Yulong!
Hmm. I'm not sure what happened in your situation, but normally you would need to switch steps 1 and 2. The idea is:
1) Edit .env
file to switch to prod
(at this point, if you refreshed, you WILL likely get a 500 error).
2) php bin/console cache:clear
- because .env
is set to prod
this will clear the prod
cache. If you did this step before step 1, it would be clearing the dev
cache, which is something you can do, but it wouldn't help in the prod
environment.
Anyways, I'm sure it was something minor - I just wanted to give you a bit more detail about the "why" behind the order of these steps. Btw, you can also run php bin/console cache:clear --env=prod
to clear the "prod" cache, regardless of what APP_ENV
is set to in .env
:).
Cheers!
// composer.json
{
"require": {
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"knplabs/knp-time-bundle": "^1.18", // v1.19.0
"symfony/asset": "6.1.*", // v6.1.0-RC1
"symfony/console": "6.1.*", // v6.1.0-RC1
"symfony/dotenv": "6.1.*", // v6.1.0-RC1
"symfony/flex": "^2", // v2.1.8
"symfony/framework-bundle": "6.1.*", // v6.1.0-RC1
"symfony/http-client": "6.1.*", // v6.1.0-RC1
"symfony/monolog-bundle": "^3.0", // v3.8.0
"symfony/runtime": "6.1.*", // v6.1.0-RC1
"symfony/twig-bundle": "6.1.*", // v6.1.0-RC1
"symfony/ux-turbo": "^2.0", // v2.1.1
"symfony/webpack-encore-bundle": "^1.13", // v1.14.1
"symfony/yaml": "6.1.*", // v6.1.0-RC1
"twig/extra-bundle": "^2.12|^3.0", // v3.4.0
"twig/twig": "^2.12|^3.0" // v3.4.0
},
"require-dev": {
"symfony/debug-bundle": "6.1.*", // v6.1.0-RC1
"symfony/maker-bundle": "^1.41", // v1.42.0
"symfony/stopwatch": "6.1.*", // v6.1.0-RC1
"symfony/web-profiler-bundle": "6.1.*" // v6.1.0-RC1
}
}
Hello,
I have developed an app in 6.2 which works perfectly in dev, but when i swith to prod it will not work anymore. I've cleared the caches but this doesn't change the issue.
The log talks about "Authenticator does not support the request." and "Did you forget to run \"composer require symfony/twig-bundle\"? As I said: in dev-mode the app works perfectly.
Any ideas ? Thanks