Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine
This tutorial has a new version, check it out!

Leveraging the prod Environment

Keep on Learning!

If you liked what you've learned so far, dive in!
Subscribe to get access to this tutorial plus
video, code and script downloads.

Start your All-Access Pass
Buy just this tutorial for $10.00

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

Right 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

The dev and prod Cache Directories

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.

Changing the Cache in the dev Environment

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.

Leave a comment!

87
Login or Register to join the conversation
Vladimir Z. Avatar
Vladimir Z. Avatar Vladimir Z. | posted 2 years ago

weaverryan 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!

2 Reply

Hey Vlad!

> 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!

Reply
gazzatav Avatar
gazzatav Avatar gazzatav | posted 16 days ago | edited

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=devto 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!

1 Reply

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!

Reply
gazzatav Avatar

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!

Reply
Mike P. Avatar
Mike P. Avatar Mike P. | posted 4 years ago

Its a joy to follow the course, you make me super curious about the next video! :)

1 Reply
Ray D. Avatar

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.

1 Reply
Aleksandr T. Avatar
Aleksandr T. Avatar Aleksandr T. | Ray D. | posted 4 years ago

the same thing

Reply

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!

Reply

Hey Raymond Dube

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!

Reply
Ray D. Avatar

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. :)

Reply

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'

Reply
Ray D. Avatar

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.

Reply

Excellent, if you find something interesting, let us know and we will update our content (even if it's something related to windows)
Cheers!

Reply
Ray D. Avatar

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. :)

Reply

Haha, don't worry Raymond Dube :)

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!

Reply

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

Reply

Hey Nicolás González Flores

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!

Reply
Hicham A. Avatar
Hicham A. Avatar Hicham A. | posted 2 years ago

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

Reply

Hey Travel RN Hub!

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!

Reply
Wilfried D. Avatar
Wilfried D. Avatar Wilfried D. | posted 2 years ago

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 ?

Reply

Hey Wilfried DEUDJUI!

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!

Reply
Wilfried D. Avatar

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...

Reply

Hey Wilfried DEUDJUI

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?

Reply
Wilfried D. Avatar

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

Reply

> 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!

Reply
Benoit L. Avatar
Benoit L. Avatar Benoit L. | posted 2 years ago

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

Reply

Hey yvon Huynh

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!

Reply
Benoit L. Avatar

Hello Diego Aguiar , I think the problem is solved with the presence of the .env file, stupid mistake. how to properly switch to Symfony cache though?thanks

Reply

Hey yvon Huynh

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/cur... then, you have to select which adapter you want to use (https://symfony.com/doc/cur... 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/cur...

Anyways, if you have more questions let us know! Cheers!

Reply
Benoit L. Avatar

thank you Diego Aguiar I will study them !

Reply
Richard Avatar
Richard Avatar Richard | posted 2 years ago

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...

https://i.imgur.com/F4LnrFg...

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...

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.

Reply

Hey maxii123

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!

Reply
Stephan Avatar
Stephan Avatar Stephan | posted 2 years ago

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?

Reply
Stephan Avatar

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.

Reply

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!

Reply

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:

apcu is disabled


I have downloaded apcu service with: composer require symfony/polyfill-apcu

Do I have to enable it somewhere?

Reply

Hey Giacomo Balloccu

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!

Reply
Jose G. Avatar
Jose G. Avatar Jose G. | posted 3 years ago

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

Reply

Hey Jose Dario Guerrero Aragon

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!

Reply
B1 Avatar

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.

Reply
Todor Avatar

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 deprecated 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.

1 Reply

Hey payskin!

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!

Reply

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

Reply

Hey Camille Seuvin

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!

Reply

Thanks Diego Aguiar 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)

Reply

Can you show me a screenshot of what you see?

Reply

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

Reply

Yes it is ! I double check and it's the same :
http://recordit.co/RWvXontCtP
(And I clean cache too)

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// 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
    }
}