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 SubscribeRight now, our app is in the dev
environment. How can we change it to prod
? Just open .env
and set APP_ENV
to prod
!
# .env
# ...
APP_ENV=prod
# ...
Then... refresh!
This page may or may not work for you. One big difference between the dev
and prod
environments is that in the prod
environment, the internal Symfony cache is not automatically rebuilt. That's because the prod
environment is wired for speed.
In practice, this means that whenever you want to switch to the prod
environment... like when deploying... you need to run a command:
./bin/console cache:clear
The bin/console
file also reads the .env
file, so it knows we're in the prod
environment.
And now when we refresh, it should definitely work. And check it out! There's no web debug toolbar. And if you go to a fake page, you get a very boring error page. And yea, you can totally customize this: just Google for "Symfony error pages": it's really easy. The point is, this is not a big development exception page anymore.
Click back into our article, and then go find its template: show.html.twig
. Let's change the 3 hours ago
to 4 hours ago
:
... lines 1 - 4 | |
{% block body %} | |
<div class="container"> | |
<div class="row"> | |
<div class="col-sm-12"> | |
<div class="show-article-container p-3 mt-4"> | |
<div class="row"> | |
<div class="col-sm-12"> | |
... line 13 | |
<div class="show-article-title-container d-inline-block pl-3 align-middle"> | |
... lines 15 - 17 | |
<span class="pl-2 article-details"> 4 hours ago</span> | |
... lines 19 - 22 | |
</div> | |
</div> | |
</div> | |
... lines 26 - 71 | |
</div> | |
</div> | |
</div> | |
</div> | |
{% endblock %} | |
... lines 78 - 83 |
Move back to your browser and refresh! Yep! The page did not update! That's the behavior I was talking about.
To make it update, find your terminal and run:
./bin/console cache:clear
Oh, and check out the var/cache
directory. Each environment has its own cache directory: dev
and prod
. When you run cache:clear
, it basically just clears the directory and recreates a few files. But there is another command:
./bin/console cache:warmup
This goes a step further and creates all of the cache files that Symfony will ever need. By running this command when you deploy, the first requests will be much faster. Heck, you can even deploy to a read-only filesystem!
And now when you refresh... it works: 4 hours ago.
Change the environment back to dev
:
# .env
# ...
APP_ENV=dev
# ...
Here's our next challenge. In config/packages/framework.yaml
, we configured the cache to use APCu:
framework: | |
... lines 2 - 16 | |
cache: | |
... lines 18 - 28 | |
# APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues) | |
app: cache.adapter.apcu |
What if we did want to use this for production, but in the dev
environment, we wanted to use the filesystem cache instead for simplicity. How could we do that?
We already know the answer! We just need to override this key inside the dev
environment. Create a new file in config/packages/dev
called framework.yaml
... though technically, this could be called anything. We just need the same keys: framework
, cache
, app
. Add those, but now set app
to cache.adapter.filesystem
, which was the original value:
framework: | |
cache: | |
app: cache.adapter.filesystem |
Let's see if it worked! Open ArticleController
and dump the $cache
object so we can see what it looks like:
... lines 1 - 13 | |
class ArticleController extends AbstractController | |
{ | |
... lines 16 - 26 | |
public function show($slug, MarkdownInterface $markdown, AdapterInterface $cache) | |
{ | |
... lines 29 - 53 | |
dump($cache);die; | |
... lines 55 - 67 | |
} | |
... lines 69 - 80 | |
} |
And, refresh! Yes! It's using the FilesystemAdapter
! What about the prod
environment? In .env
, change APP_ENV
back to prod
:
# .env
# ...
APP_ENV=prod
# ...
But don't forget to clear the cache:
./bin/console cache:clear
The warmup
part is optional. Refresh! Yea! In the prod
environment, the cache still uses APCu.
Change the environment back to dev
:
# .env
# ...
APP_ENV=dev
# ...
In reality, you won't spend much time in the prod
environment... it mostly exists for when you deploy to production.
Let's also remove the dump()
:
... lines 1 - 13 | |
class ArticleController extends AbstractController | |
{ | |
... lines 16 - 26 | |
public function show($slug, MarkdownInterface $markdown, AdapterInterface $cache) | |
{ | |
... lines 29 - 53 | |
dump($cache);die; | |
... lines 55 - 67 | |
} | |
... lines 69 - 80 | |
} |
Oh man, with environments behind us, we can jump into the heart of our tutorial.. the thing I have been waiting to do: create our own services.
Hey Vladimir Z.!
> I've been thinking about getting a Symfony certification.
Woo! You should!
> Do you plan on creating a course just for that?
Yes, we've thought about this for awhile - and I'd like to do it... but we don't have it yet :/
> What suggestions do you have to prepare for it and what courses do you recommend?
I answered this question a few years ago (wow! Time flies!) - and other than the Symfony version involved, my answer is the same - https://symfonycasts.com/sc... - the only difference is that the book I reference is outdated now (I think). The exam is hard - so you really need to study very broadly. The exam topics - listed at the bottom of https://certification.symfo... - give you a very accurate indication of how many things are covered.
I hope that helps! And happy studying - it's very rewarding to be on the other side.
Cheers!
Just in case anyone else likes to work through the older tutorials with newer Symfony versions and libraries as an exercise...
The Symfony local server with 5.4 does not fully respect the .env file any more. There is a command (which I cannot find documentation for) symfony server:prod
which creates a .prod file in the project root. I found that changing APP_ENV=dev
to APP_ENV=prod
had no effect. The local server only delivered a prod like page after running symfony server:prod
. Then changing APP_ENV=prod
back to APP_ENV=dev
had no effect. Guess how many times I cleared the cache! After an hour or so I found the empty file .prod and after deleting it the profiler tools were back.
Like the new commenting tools - the font is a bit small though. EDIT: Lol, the preview shows the small font but after posting it's bigger!
Hey.
Woh looks like you had crazy debugging time)))
There is some sort of documentation.... mmm probably not documentation, but a help system in Symfony CLI
â–² ~ symfony help server:prod
Description:
Switch a project to use Symfony production environment
Usage:
symfony local:server:prod [options]
Options:
--dir=value Project directory
--off Disable prod mode
as you can see there is --off
option to disable it. IIRC Symfony CLI was always based on a self-help system that's why there is no complete documentation on it.
But I agree with you that the mechanism of this command should be described somewhere. Symfony CLI is an opensource now, so probably you can create a PR to make this command better =)
Cheers!
Ha ha! I missed that option, it's the sort of thing that's obvious when you know it. I kept looking for a more symmetric server:dev
command and wondering why it wasn't there. It's a lot quicker typing touch .prod
and rm .prod
. Think I might do that instead!
If the server is 'required' using --dev (composer require symfony/web-server-bundle --dev) wouldn't mean it will not work when you switch to the prod'uction environment?
I'm not sure if this is the case, but when I switch to prod, and clear the cache, the server stops unexpectedly. I would think that means I need to reuire the server bundle without the --dev.
--edit--
without clearing the cache, things to seem to work correctly. Of course this is an Windows environment, so all bets are off on behaviour.
Hey guys,
Do not confuse Composer's "require-dev" with Symfony's dev environment - they are different things. And do not confuse running Symfony web server vs loading website on the Symfony web server. I run Symfony web server in *dev* mode, but then I load the website on this server in dev (or prod, or even test) environment by access the proper front controller like http://localhost:8000/app_dev.php (or http://localhost:8000/app.php, or http://localhost:8000/app_test.php). So as you can see, even if you've run the server in Symfony dev mode, you can load your website in prod mode by going to a proper URL, i.e. http://localhost:8000/app.php - we're talking about different running kernels. It's like talking that if you load your website in the dev mode in one Chrome's tab, you can't load it in the prod mode in a different tab simultaneously - we're talking about different processes. I hope it's clearer to you now.
Cheers!
Hey Ray D.
That web server is not meant to be used for a production environment, where you may have big numbers of users and transactions, that's why it's recommended to require it as a dev dependency, and instead you can install "Apache", "Nginx" or any other web server that fits your needs.
Cheers!
Hi Diego,
I understand that it's not meant for production, but unless you're working in a dev/prod environment, the steps used in the video don't work, at least not on windows. Clearing the cache resets the site to use production values, where, in most cases, the server may not be running with the same setup, which may, and did in my case, cause issues.
I may decide to setup a production server for training purposes, even if it never sees the public eye. :)
Setting up a production server is always a good training but, symfony's web server should work for you anyways. It doesn't care if you required it as a dev dependency because you already installed that dependency (you have to use the flag --no-dev in order to avoid installing dev dependencies when running composer install), probably there is something else in your configuration that is causing that weird behaviour.
Try running 'bin/console cache:clear -e prod'
You hit the nail on the head, --no-dev would work correctly. I think the video from the initial install should have noted something about that. I"ll have to take a look there later and maybe make a comment.
Excellent, if you find something interesting, let us know and we will update our content (even if it's something related to windows)
Cheers!
I wish I had a better memory, but I forgot to reply to this 2 months ago.
The problem, for me, was that during the install, the software recommends/suggests using --dev, but KnpU, correctly omits that portion, so we can do the proper dual environment testing.
This doesn't mean we're using the server for actual production, just using the built in server to simulate, as best we can, the production environment.
It's really all on me, following the course more closely, I should have seen the difference, but all's well that ends well. :)
Haha, don't worry Ray D. :)
If you ever forget to add the "--dev" part, you can always fix it yourself by moving the dependency from "require" to "require-dev" in your composer.json
Cheers!
Hello guys, I'm having the same problem. No matter in which environment I am, whenever I do cache:clear and refresh the page, the server hits me with a "[ERROR] Server terminated unexpectedly."
I changed in the bundle.php the env of the WebServerBundle to "all" so I could get rid off the error "There are no commands defined in the "server" namespace." when starting the server. But Idk what to do to fix the other error.
Any suggestions?
Best
Hey fahani
Sorry for the late response. About the error "[ERROR] Server terminated unexpectedly.", can you run it passing "-vvv" so we can gather more info about the problem
And about "There are no commands defined in the "server" namespace." that bundle is not meant to run in a prod environment, that's why it's only loaded for "dev" environmnet, but if what you want is to test something quickly, then you can do exactly what you did :)
Cheers!
Why do I get this message after typing ./bin/console cache:clear
unable to write in the "/var/www/html/project/var/cache/prod" directory
thank you
Hey Hicham A.!
Hmm, great question! The "simple answer" is that some file(s) or directories inside var/cache
are not writeable - or are not writeable by your user. Basically, it's a permissions issue.
The harder thing to explain is why this is happening. There are a number of different causes:
1) If, when you deployed, you ran a command with sudo - like sudo cache:clear
- then all of the files may be owned now by "root". If that's the case, do a sudo rm -rf var/cache/*
and then be sure not to run any future commands with sudo.
2) Similar to the above, it's possible that, after you originally deployed, before running bin/console cache:clear
and (the recommended) bin/console cache:warmup
, a web request hit your server. When that happened, because the cache was empty, Symfony generated the cache files. That's actually ok! The problem is that if this happened, it's possible that the owner of the var/cache/prod directory is (for example) www-data
. This puts you in a similar situation to (1) - your "ssh" user is not the owner of the files. And so, you can't write to them.
To see more about your situation, run: ls -la var/cache/prod
so that we can see who owns the files and what the permissions are. Also run whoami
to see what user you currently are.
Let me know what you find out!
Cheers!
Thank you for this course. I am currently facing an issue: I updated my security.yml file to allow a role to access an url and it works perfectly in dev. But when I move the change to production, it does not work, I wonder why. I cleared the cache and warmed it up, but still not working. I even manually deleted the prod cache folder but no changes. Any idea on how I can make it work ?
Hey Wilfried D.!
Hmm. Well, that should not happen :). The environments should behave identically once you've cleared the prod cache. What exactly is the "bad" behavior you're seeing in the prod environment? Is it that the user that has a role suddenly cannot access a URL (but they can in dev)? Can you post your security.yaml
file?
Cheers!
Hi Ryan.
This is how it behaves: I have the role ROLE_STAFF, that is allow to access the url matched by "path: ^/company/list". In the controller, I annoted the the action like this:
/**
* @Route("/company/list", name="list_company")
* @IsGranted("ROLE_STAFF")
*/
public function listCompany(): Response
Previously, the role was ROLE_CHIEF_OF_SQUAD. After clearing the cache in prod, it still required the role ROLE_CHIEF_OF_SQUAD to grant access to the url instead of ROLE_STAFF...
Below it the security.yml
security:
access_control:
- { path: ^/company/list, roles: ROLE_STAFF, requires_channel: '%env(SECURE_SCHEME)%' }
- { path: ^/login$, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: '%env(SECURE_SCHEME)%' }
role_hierarchy:
ROLE_ACCOUNTANT: [ROLE_STAFF, ROLE_PAY_ECTN, ROLE_ACCOUNT_BALANCE]
ROLE_CADET_SQUAD: [ROLE_STAFF, ROLE_LIST_ECTN, ROLE_SHOW_ECTN]
ROLE_SQUAD: [ROLE_CADET_SQUAD, ROLE_ECTN_SQUAD]
ROLE_CHIEF_OF_SQUAD: ROLE_SQUAD
I have the same issue with easyadmin. I updated the config file but it does not refresh in prod...
Hey Wilfried D.
That's very odd. It makes me think two possibilities
1) Your production code didn't get updated
2) The production cache, for some reason, didn't get cleared
Or, are you using a different cache mechanism in production?
Hello Diego, Ryan. Finally fixed it. The production code was updated and as I said i even manually remove the prod cache folder. While trying to understand what whas going on, an idea just popped in my head: restart the web server, in my case apache
I restarted the web server and all the odd behaviour was corrected... still not fully understand where was the link, but can now move futher...
Thank you all for your willingness to assist... You are doing great job with symfonycast
> I restarted the web server and all the odd behaviour was corrected
Wow, really? It makes me think that Apache is caching the responses but I don't know, it's just a wild guess
>Thank you all for your willingness to assist... You are doing great job with symfonycast
You are welcome man!
Cheers!
Hi, I have a problem when deploying to prod environment on Centos server, I set APP_ENV=prod in .env file
then I exported APP_ENV=prod as suggested in Symfony official documentation, then ran composer install (with or without --no-dev flag)
in either cases when the system tries to clear cache I got this error:
Uncaught Error: Class 'Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle' not found
It seems it is ignoring the prod environment
Hey Benoit L.
First of all I want to say that DoctrineCacheBundle is deprecated and you should use Symfony cache instead. Now, to your problem. Do you get the same error locally? Try removing manually your cache and then install composer again and let me know what happened
Cheers!
Hello MolloKhan , I think the problem is solved with the presence of the .env file, stupid mistake. how to properly switch to Symfony cache though?thanks
Hey Benoit L.
I'm glad to hear that you managed to fix your problem. About caching, you first have to install Symfony's cache https://symfony.com/doc/current/components/cache.html#installation then, you have to select which adapter you want to use (https://symfony.com/doc/current/cache.html#configuring-cache-with-frameworkbundle) if you just don't know, you can use the cache.adapter.filesystem
, and then, you just have to configure a pool and use it in your code. Here you can find more info and examples of how to do it exactly https://symfony.com/doc/current/cache.html
Anyways, if you have more questions let us know! Cheers!
I cant get it into prod mode. I tried adding APP_DEBUG=0 as documented below in my .env but that didnt work either.
screen shots:-
https://i.imgur.com/v9d9JWS.png
https://i.imgur.com/F4LnrFg.png
Anything else?
EDIT: I quit my shell, restarted it, navigated to my directory and "echo $APP_ENV" now reports "prod" - ok promising. I removed the cache with brute force : rm -rf var/cache and then "warmed it up".
And now:
https://i.imgur.com/rJV3fHg.png
I'm flummoxed.
EDIT EDIT:
OK I solved it.
Problem #1: using ZSH under debian buster I needed to move out of my project directory and back into it in order for the new value of APP_ENV
to be picked up from the .env
file.
problem #2: ./bin/console server:run
doesnt work for prod
. The solution is symfony serve
.
Hey Richard
Yea... you can't use bin/console server:run
when in prod environment, unless you run it before changing environments but anyways, it's better to start getting used to use Symfony CLI
Cheers!
When I run ./bin/console server:run with in the .env file, APP_ENV=env, I have this error even if the bundle is installed:
There are no commands defined in the "server" namespace.
You may be looking for a command provided by the "WebServerBundle" which is currently not instal
led. Try running "composer require symfony/web-server-bundle --dev".
How can I solve that?
It seems that I am still in prod environment even if I put APP_ENV=dev in .env file because when I run ./bin/console cache:clear I have that: [OK] Cache for the "prod" environment (debug=false) was successfully cleared. So, there is a problem somewhere. PS: Sorry, for my first message it is: APP_ENV=dev.
Hey @stephansav
You can run the clear cache command specifying which environment you want by passing in the option --env=dev
. Or, you can manually clear your cache by running rm -rf var/cache
(standing at your project's root)
I hope this helps. Cheers!
Hi! Currently I have this problem, when I uncomment the line in framework (the one about cache apcu) when I try to load a page which uses the cache I get the error: <blockquote>apcu is disabled</blockquote>
I have downloaded apcu service with: composer require symfony/polyfill-apcu
Do I have to enable it somewhere?
Hey Gballocc7
Yes, you also have to install and enable APCu on your local machine, the installation depends on your OS but if you are an Ubuntu user like me, here is a guide: https://serverpilot.io/docs...
Cheers!
In prod environment, any change in show.html.twig is showing up in the browser, without clearing the cache. im using Symfony 4.2.4
Hey Jose G.
Hmm, that's odd and makes me believe that you are actually hitting dev environment. Do you see the debug toolbar at the bottom of the page? Also you can check the logs inside "var/log{dev, prod}" just to see if there is something funny going on.
Cheers!
So, I'm through all the other oops mentioned in previous comments, and took some time experimenting a bit.
The server crashing behavior is reproducible in Windows 10 (1809) with PHP 7.3.1, APCu 5.1.6 for Windows, Composer 1.8, Symfony 4.2.2 when apc.enable_cli=1 in php.ini.
- Symfony server is started in dev environment
- change APP_ENV to prod in .env
- refresh page --> page works
- clear cache --> [OK] Cache for the "prod" environment (debug=false) was successfully cleared.
- refresh page --> localhost not responding,
- check console --> server terminated unexpectedly
Warming up the cache only, or clearing AND warming up the cache works. Clearing the cache only kills the server at next page refresh.
Setting apc.enable_cli to 0 in php.ini makes clearing the cache safe.
Here's another problem, not mentioned before:
- server is running
- APP_ENV set to prod,
- not touching the cache just to make sure everything works :)
- whenever I change the time in show.html.twig and refresh the page, the time changes in the page.
So the page is somehow not being cached in prod. :-\
Setting apc.enable_cli to 1 or 0 does not affect this behavior. Turning off apc in config/packages/cache.yaml does not help either. The page always updates even in prod.
Any idea why? Might be a Windows thing.
Windows Version 10.0.18363.815; PHP CGI 7.3.14 (also tried with 7.4.5, the issue remains); Symfony CLI version 4.14.3; Symfony Framework 4.4.8; APCu v. 5.1.18
I get server crashes on both - the Symfony CLI (since the Web Server Bundle is <i>deprecated</i> in Symfony 4.4) and the PHP's built-in Web Server after altering some twig template and then clearing the cache via cache:clear. When hitting again on page refresh the error comes out.
I had to comment out apc.enable_cli=1
in my php.ini. Since then no more crashes.
Hey B1!
Wow! Excellent research! So let's tack each thing on its own.
First, about the apc.enable_cli part. What version of Symfony are you using? If it's the newest version, this smells a bit like a possible bug to me - could be a bug in Symfony with Windows + opcache or it could be a bug in opcache + PHP + Windows. I did find one other person with the same issue, but no more info :/ https://github.com/symfony/...
Second, about the time changing when you refresh the page in prod, I also don't like this ;). First, to make sure I'm not misunderstanding, what "time" are you referring to on the page? Second, do you see the web debug toolbar on the page or not? Let me know and we can go from there :).
Cheers!
Hello,
When I try a fake page, a Symfony exception page was showed instead of the boring exception browser error.
The Debug Toolbar didn't appear (it means I was in prod env)
###> symfony/framework-bundle ###
APP_ENV=prod
Hey ojtouch
If you are on prod environment, then, yes, you won't see the debug toolbar, and you will see the error page templates instead of the error message with its stack trace
Cheers!
Thanks MolloKhan for your reply, but I don't understand, I have to see the 404 error page (browser defaut 'oops..') but I see the error page of Symfony (in prod env)
That's weird. Can you double check that you are actually on prod environment?
You can run bin/console
and in the first line you can see which environment is being used
If it says "prod", then, clear the cache bin/console cache:clear
and try again
Yes it is ! I double check and it's the same :
http://recordit.co/RWvXontCtP
(And I clean cache too)
// composer.json
{
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"knplabs/knp-markdown-bundle": "^1.7", // 1.7.0
"nexylan/slack-bundle": "^2.0,<2.2.0", // v2.0.0
"php-http/guzzle6-adapter": "^1.1", // v1.1.1
"sensio/framework-extra-bundle": "^5.1", // v5.1.4
"symfony/asset": "^4.0", // v4.0.4
"symfony/console": "^4.0", // v4.0.14
"symfony/flex": "^1.0", // v1.17.6
"symfony/framework-bundle": "^4.0", // v4.0.14
"symfony/lts": "^4@dev", // dev-master
"symfony/twig-bundle": "^4.0", // v4.0.4
"symfony/web-server-bundle": "^4.0", // v4.0.4
"symfony/yaml": "^4.0" // v4.0.14
},
"require-dev": {
"easycorp/easy-log-handler": "^1.0.2", // v1.0.4
"symfony/debug-bundle": "^3.3|^4.0", // v4.0.4
"symfony/dotenv": "^4.0", // v4.0.14
"symfony/maker-bundle": "^1.0", // v1.0.2
"symfony/monolog-bundle": "^3.0", // v3.1.2
"symfony/phpunit-bridge": "^3.3|^4.0", // v4.0.4
"symfony/profiler-pack": "^1.0", // v1.0.3
"symfony/var-dumper": "^3.3|^4.0" // v4.0.4
}
}
there I've been thinking about getting a Symfony certification. What suggestions do you have to prepare for it and what courses do you recommend? Do you plan on creating a course just for that? Thank you!