Chapters
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
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.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeNuestra aplicación se está ejecutando actualmente en el entorno dev
. Cambiémosla a prod
... que es el que usarías en producción. Cambia temporalmente APP_ENV=dev
porprod
... y luego dirígete a él y actualízalo. ¡Vaya! La barra de herramientas de depuración web ha desaparecido. ¡Eso... tiene sentido! Todo el bundle del perfilador web no está activado en el entorno prod
.
También observarás que el volcado de nuestro controlador aparece en la parte superior de la página. El perfilador web normalmente captura eso y lo muestra abajo en la barra de herramientas de depuración web. Pero... como todo ese sistema ya no está habilitado, ahora hace el volcado justo donde lo llamas.
Y hay muchas otras diferencias, como el registrador, que ahora se comporta de forma diferente gracias a la configuración en monolog.yaml
.
Borrar la caché de prod
La forma de construir las páginas también ha cambiado. Por ejemplo, Symfony almacena en caché muchos archivos... pero eso no se nota en el entorno dev
. Eso es porque Symfony es súper inteligente y reconstruye esa caché automáticamente cuando cambiamos ciertos archivos. Sin embargo, en el entorno prod
, eso no ocurre.
¡Compruébalo! Abre templates/base.html.twig
... y cambia el título de la página a Stirred Vinyl
. Si vuelves y actualizas... ¡mira aquí! No hay cambios! Las propias plantillas Twig se almacenan en la caché. En el entorno dev
, Symfony reconstruye esa caché por nosotros. ¿Pero en el entorno prod
? No Tenemos que borrarla manualmente.
¿Cómo? En tu terminal, ejecuta:
php bin/console cache:clear
Fíjate que dice que está borrando la caché del entorno prod. Así, al igual que nuestra aplicación se ejecuta siempre en un entorno concreto, los comandos de la consola también se ejecutan en un entorno concreto. Y lee la misma bandera APP_ENV
. Así que, como tenemos aquí APP_ENV=prod
, cache:clear
sabe que debe ejecutarse en el entorno prod y borra la caché para ese entorno.
Gracias a esto, cuando refrescamos... ahora el título se actualiza. Volveré a cambiar esto por nuestro nombre genial, Mixed Vinyl
.
Cambiar el adaptador de caché sólo para prod
¡Vamos a probar otra cosa! Abre config/packages/cache.yaml
. Nuestro servicio de caché utiliza actualmente el ArrayAdapter
, que es una caché falsa. Eso puede estar bien para el desarrollo, pero no será de mucha ayuda en producción.
Veamos si podemos volver a cambiar al adaptador del sistema de archivos, pero sólo para el entornoprod
. ¿Cómo? Aquí abajo, usa when@prod
y luego repite las mismas claves. Así que framework
, cache
, y luego app
. Pon esto en el adaptador que queremos, que se llama cache.adapter.filesystem
.
Va a ser muy fácil ver si esto funciona porque seguimos volcando el servicio de caché en nuestro controlador. Ahora mismo, es un ArrayAdapter
. Si refrescamos... ¡sorpresa! Sigue siendo un ArrayAdapter
. ¿Por qué? Porque estamos en el entorno de producción... y prácticamente cada vez que haces un cambio en el entorno prod
, tienes que reconstruir tu caché.
Vuelve a tu terminal y ejecuta
php bin console cache:clear
de nuevo y ahora... lo tienes - ¡ FilesystemAdapter
!
Pero... vamos a invertir esta configuración. Copia cache.adapter.array
y cámbialo porfilesystem
. Lo usaremos por defecto. Luego, en la parte inferior, cambia a when@dev
, y esto a cache.adapter.array
.
¿Por qué hago esto? Bueno, esto literalmente no supone ninguna diferencia en los entornos dev
yprod
. Pero si decidimos empezar a escribir pruebas más adelante, que se ejecuten en el entorno de pruebas, con esta nueva configuración, el entorno de pruebas utilizará el mismo servicio de caché que el de producción... lo que probablemente sea más realista y mejor para las pruebas.
Para asegurarte de que esto sigue funcionando, borra la caché una vez más. Refresca y... ¡funciona! Seguimos teniendo FilesystemAdapter
. Y... si volvemos al entorno dev
en .env
... y refrescamos... ¡sí! La barra de herramientas de depuración de la web ha vuelto, y aquí abajo, ¡volvemos a utilizar ArrayAdapter
!
Ahora bien, en realidad, es probable que nunca cambies al entorno prod
mientras estés desarrollando localmente. Es difícil trabajar con él... ¡y no tiene sentido! ¡El entorno prod
está realmente pensado para producción! Y así, ejecutarás ese comando bin/console cache:clear
durante el despliegue... pero probablemente casi nunca en tu máquina local.
Antes de continuar, entra en VinylController
, baja a browse()
, y saca ese dump()
.
Bien, ¡comprobación de estado! Primero, todo en Symfony lo hace un servicio. Segundo, los bundles nos dan servicios. Y tercero, podemos controlar cómo se instancian esos servicios a través de las diferentes configuraciones de bundle en config/packages/
.
Ahora, vamos a dar un paso importante creando nuestro propio servicio.
19 Comments
Aaaaah! I got it! It was a doctrine configuration error! It could have been a bit more explicit error...
Thanks anyway, Symfonycasts remains by far the best site about Symfony.
Now that my new app runs smoothly I can go and learn S7...See you soon ;)
Edit: nooo, sorry, scratch that! It doesn't run smoothly yet, and it's kinda weird. On dev mode, I still have that same blocking (not explicit :p) error. But on dev mode, I now have 404 on every requests: login, api, etc. But I also have a new error in the firefox console: (in french, sorry)
Blocage d’une requête multiorigines (Cross-Origin Request) : la politique « Same Origin » ne permet pas de consulter la ressource distante située sur https://www.mybeautifulsymfonysite.fr/api/tags?isTheStar=true. Raison : l’en-tête CORS « Access-Control-Allow-Origin » est manquant. Code d’état : 404.
I guess that's still an .env problem.
Edit day 2:
I'm still struggling with that problem. Now I don't get anymore that putenv error, only CORS errors. I tried so many nelmio cors confiigurations that I kinda lost track ^^. I'm at a point where (I think) i authorized everything from everywhere, yet it doesn't work. Now I'm trying to get rid of Nelmio and try something else.
Hey Jean,
Attempted to call function "putenv" from namespace "Symfony\Component\HttpKernel".
Hm, that sounds like you need to add a back slash in front of that function, i.e. \putenv()
. The only question is, do you call that function in your code or is it something that's called in the code from vendor/ dir that you can't touch. if first one - you can easily fix it yourself I think. Otherwise, you may try to fix it with that back slash in vendors just to give it a try and see if that helps. But the proper fix might be to upgrade related dependencies were that is fixed already. I see you updated the comment saying you don't have that error anymore and I wonder how you fixed that :)
About the CORS problem, are you using custom written API? OR do you use ApiPlatform? Because with ApiPlatofm that might be already configured for you and should work out of the box.
Btw, that page give 404 error. Please, make sure that the same exact /api/tags?isTheStar=true
URL works locally for you. If it works, go ssh to the prod server and make sure you have that route there, you can run bin/console debug:router --env=prod
and check for that /api/tags
exist there. You may also want to run cache:clear --env=prod
and cache:warmup --env=prod
commands to make sure you refresh the old cache on prod, that's important to do after the deploy process, depends on your deploy strategy.
But if you have customly written API - make sure you have nelmio/cors-bundle
properly installed and enabled in bundles.php. Then maybe try the next config in your config/packages/nelmio_cors.yaml
:
nelmio_cors:
defaults:
allow_credentials: false
allow_origin: ['*']
allow_headers: ['Content-Type', 'Authorization']
allow_methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS']
expose_headers: []
max_age: 3600
paths:
'^/api/':
allow_origin: ['*']
allow_methods: ['GET', 'POST', 'OPTIONS']
allow_headers: ['Content-Type', 'Authorization']
If you made those changes directly on prod - don't forget to clear the cache every time you change your config! Otherwise no changes will be applied.
After you add that CORS config - make sure you have CORS headers when do new requests to the https://www.mybeautifulsymfonysite.fr/api/tags?isTheStar=true - you can do it in the Chrome dev toolbar for example, or using curl
in the CLI:
curl -I -X OPTIONS https://www.mybeautifulsymfonysite.fr/api/tags?isTheStar=true
The response should have correct headers.
If it finally works - then you may try a more strict config - instead of *
use specific domains, .e.g https://www.mybeautifulsymfonysite.fr
if all your API requests goes from there. P.s. are you sure you're using the correct domain? Because that host does not work for me at all, probably a misconfiguration on the server, you should make the host work first to be able to try those API requests.
And last but not least, try to check the logs in var/log/prod.log
just in case, you can even track them in real time with tail -f var/log/prod.log
and try to do the request. Sometimes logs may contain useful hints too.
I hope that helps!
Cheers!
Thank you for your reply. I use Nelmio Cors and haven't written anything about putenv() ever, anywhere. Il's a very basic symfony configuration, mainly inspired by your work here. I never touched the vendor dir and I use Api Platform (sometimes i regret it ^^).
The putenv error only appears in prod mode on my server. In dev mode I can get to the fronthome but absolutely no requests are accepted. When I'm at "https://WWW.mydomain.fr" I only get 404s. It's without the "WWW" that I get the "cross origin requests" error, resulting into a 404. Www or not, I get 404s also on /login, not only api's calls.
And this is what I get when I do your curl call:HTTP/1.1 200 OK<br />date: Fri, 15 Nov 2024 13:12:18 GMT<br />server: Apache<br />allow: GET,POST,OPTIONS,HEAD<br />vary: User-Agent<br />content-length: 0<br />set-cookie: WEBMO-MNO=11115|ZzdIt|ZzdIt; path=/; HttpOnly; SameSite=Strict
I'll keep trying. Thanks anyway for your input.
Edit: so I tried again everyting in local with your Nelmio configuration above. Absolutely no errors anywhere, dev or prod, every urls are ok. I can get to the./api page docs.
For the server I switch the database url to the right one, updates Axios baseUrl, and that's it. And clear cache each time I try something new.
Edit2: in the prod cache on the server I can read url_generating_routes.php and I can see that all the routes are indeed there: login, logout, admin section and all the apis. I'm not sure that means anything, though ^^'
Coud it be some configuration on my server that causes my problem? Or is it obviously something i did wrong on my side, somewhere? What should be the correct answer of that curl call?
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
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!
Of course I cleared the cache.
That's odd. If you change something else, do you see it reflected?
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
- edit
.env
file to switch to 'prod' - refresh the page and the page will load with no 500 error
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!
"Houston: no signs of life"
Start the conversation!
What PHP libraries does this tutorial use?
// 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.4.5
"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.4.3", // v6.4.3
"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
}
}
Sorry to bother you on an "old" chapter, but I tried to upload a new app made (proudly ^^) with Symfony 6.4 (yeah I started that before the release of S7), and I have a "not very explicit" error:
Attempted to call function "putenv" from namespace "Symfony\Component\HttpKernel".
...and that's it.
I guess it has something to do with this chapter, but I have no idea how to solve it, and Google doesn't help at all. I never had it before, and of course, "the app runs perfectly on my pc", both on dev and prod mod.
Beside I have very little control on the server for this app. I just know that it runs on PHP 8.3, I have control only over a few vars, but I can have potential support from the company - I guess... I must sadly add that I know almost nothing about servers configuration.
Could you please guide me through that? It's quite frustrating ^^
Thank you.