Dynamically disable the web toolbar and profiler in Symfony 4 using .env - symfony

The web profiler is set to activate if APP_ENV is dev. It is this way on our staging server; however, a security audit is being run on our staging server and it is required that we manually turn the profiler off while keeping APP_ENV = dev.
This will successfully disable the profiler and toolbar:
web_profiler:
toolbar: false
intercept_redirects: false
framework:
profiler:
{ enabled: false, only_exceptions: false }
But I want to use .env to use flags that we can control to disable each. When I try to, Symfony complains:
Environment variables "bool:SYMFONY_TOOLBAR" are never used. Please, check your container's configuration.
This leads me to an answer here, which claims:
profiler > enabled cannot be set with a runtime env variable, because that controls whether all the profiler services are created in the container (wrapping services whenever needed to be able to profile them). Changing the container entirely cannot be done at runtime (and the value of this boolean config does not end up being set itself anywhere in the container, which is why this error is triggered)
The developer says "Use a parameter in a file that is only loaded in dev mode." but I have no idea what that means; so, how can I resolve this? (.env is not a requirement, just ideal)

It is impossible to use environment flags in web_profiler.yaml due to the order in which the framework loads its environment variables. Thankfully it isn't too hard or scary to just make a new environment:
https://symfony.com/doc/4.1/configuration/environments.html#creating-a-new-environment
Create your environment, save your new web_profiler.yaml under it, then add it to bundles.php's relevant lines; in my case, my line reads like this after adding the staging environment:
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true, 'staging' => true],

Related

How can I turn on the profiler in production mode (Symfony)?

I have a strange error. My Symfony app works fine in dev mode. But in production mode I am not able to save any files.
So I need to turn on the profiler in production mode for a second to see what is the error.
How can I achieve this?
Symfony profiler shouldn’t be in prod mode. Symfony docs : "Never enable the profiler in production environments as it will lead to major security vulnerabilities in your project."
You need to focus on your logs server. But if you want to do this.
Create a web_profiler.yaml (.../config/packages/prod)
Insert this content :
web_profiler:
toolbar: true
intercept_redirects: false
framework:
profiler: { only_exceptions: false }
Remove this after your found your problem
Regards

Symfony Validator not using cache

I have symfony 5.2.3 project with a bunch of slow validation unit tests. I want validation constraints mapping to be cached.
Following docs https://symfony.com/doc/current/reference/configuration/framework.html#reference-validation-cache I have my validator.yaml as following (I have dumped it with cli, it is actually set to this):
framework:
validation:
enabled: true
email_validation_mode: html5
cache: cache.default_redis_provider
and cache.yaml:
framework:
cache:
app: cache.adapter.filesystem
default_redis_provider: '%env(REDIS_CACHE_URL)%'
But cache is not being written in my redis. I dig in and find out that Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory is being used for this. So I put some debug there and see that it is getting $cache = null from DI. I override it manually with
$cache = new RedisAdapter(new Client('redis://redis:6379?database=1'));
and my tests are working fast and cache is written and read.
What is going on? Does this validation.cache option even work? I can put any nonsence there and it wont even throw an error
I can't see your complete configuration, but have to set the value of REDIS_CACHE_URL in '.env' file.

How can I run Symfony 4 in production mode?

I am using the Symfony profiler. But I actually only want to make it visible in the Dev mode. But when I push the data via git on my server and open the website, I see the profiler. That does not make sense of cause, but I do not know how to remove it.
I was looking for the file called config/config_dev.yml and config/config.yml because I would think that in config/config.yml I should just set to:
web_profiler:
toolbar: false
intercept_redirects: false
But I do not have any config.yml files. Do I have to create them?
On your server, copy your .env.dist (if you have one) to .env, and set APP_ENV=prod
If you don't yet have a .env file, create one at the root of you project, and put APP_ENV=prod in it.
That being said, note that best practice is to use server level configuration in production env. Reference link : https://symfony.com/doc/current/configuration/external_parameters.html#configuring-environment-variables-in-production
EDIT (based on the comments) for your information :
.env is a file where you will mainly put your global configuration. The .dist variant is meant to be added to git, it won't be used by symfony but is useful for the developpers (including you) to have a default config file to rely on.
Basically, when they'll pull the project for the first time, they'll copy this file to .env then adjust the lines/config to their liking.
The .env must not be added to git for it will be the file that will be used by symfony. If you add it to git, each time you will push your local work then pull from your server, it will replace your server configuration with your local one.

Spring Boot Environment-specific configurations

I have a spring boot application that uses the actuator, auto-configuration and JPA. I want to be able to use an in-memory DB in my test profile, a MySQL DB configuration during development and a separate production DB configuration when the app is deployed in production. Presumably from the java command line I should be able to specify the environment and the right configuration file or config block in application.properties (or .yml) will be picked up.
I have not found a good post with example describing how to do this switching so I thought I'd ask if anyone has a good example. My main aim is to pre-define the spring.datasource and spring.jpa properties at build time and then at run-time switch the app config per environment "dynamically" using the java command line argument. Secondary goal would be to do the same with the management configurations, etc.
Thank you.
Thanks to #Richard for the mention of spring.profiles.active JVM variable. Since my question was specific to the way Spring Boot does this and since there is much more to the answer, I am inclined to answer this myself and include all the details of how I arrived at the answer in the hopes that it will save others time.
First, you can indeed pick the correct profile on the java command line by adding -Dspring.profiles.active=profile_name when you are running your Spring Boot app. (this is assuming your deployment preference is an uber jar with embedded container - Tomcat in my case)
I wanted to leave MySQL datasource configurations under the default profile and put H2 in-memory datasource configuration under a test profile. However, the way Spring Boot picks the right datasource based on profile is not so obvious. Even though I had MySQL details under the default profile and I had the in-memory H2 datasource details under the test profile, it would still pick H2 as the datasource even when spring.profiles.active was omitted from the command line. This was contrary to my assumption that default profile will be picked, well, by default :-)
I ended up having to put H2 configuration under the default profile and then create a local profile that included the MySQL datasource configuration. Here's what I ended up with in my application.yml
spring:
profiles: default
spring:
datasource:
driverClassName: org.h2.Driver
url: jdbc:h2:mem:sampletest;MODE=MySQL
---
spring:
profiles: test
spring.jpa:
hibernate:
ddl-auto: create-drop
---
spring:
profiles: local
spring.datasource:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1/sampledev
username: sample
password: sample
spring.jpa:
hibernate:
dialect: org.hibernate.dialect.MySQLInnoDBDialect
ddl-auto: update
This worked. I was able to switch between default profiles and the local profile by omitting or adding the -Dspring.profiles.active=local on the java command line. Because test profile inherits from default it is also using H2
One more nuance: I added ddl-auto: create-drop to the test profile which uses the in-memory DB to facilitate automatic table creation / teardown for unit tests. But for the local profile which uses MySQL I changed it to update. Implication being that for the local profile I have to first create the database outside of the application.
this article shows how to use spring profiles, available in spring 3.1 and later. It will do exactly what you want.
http://chariotsolutions.com/blog/post/spring-3-1-environment-profiles-2/
set a JVM variable like this: spring.profiles.active=development
then in your configuration xml you can wrap environment specific xml with the profile tags
<beans profiles="development">
<bean id="dataSource" class="..."></bean>
<bean id="messagingProvider" class="..."></bean>
</beans>
You can also set the profile on annotation-driven classes with #Profile("development") at the beginning of the class. That class will only be autowired if the profile matches.
For unit tests you can set the active profile on a test class with #ActiveProfile(profiles = "test", "CI"), it will run using test and CI resources

asp.net mvc BundleConfig - is localhost

BundleTable.EnableOptimizations = false;
Hi! I want to set bundle optimization to false if I app is started on localhost. Since it is called from app-start method I cant get to the Request object. Other posibility is Transformation config's but they are not used on this project.
Does anybody has some other solutions?
In my opinion you better use the configuration manager. When in 'Debug' mode disable the optimizations, when building in 'Release' mode enable it.
It's also possible to create your own configurations, for instance 'localhost' build.
This is the setting you need to change for the different build configurations:
<Optimize>true</Optimize>
or
<Optimize>false</Optimize>
This will keep your code cleaner as you don't have to write any exceptions.
This worked for me
if (!HostingEnvironment.IsDevelopmentEnvironment)
BundleTable.EnableOptimizations = true;

Resources