Environments, parameters and secrets
The same application runs on your computer, in tests and on a server — and behaves differently in each place: shows or hides errors, sends email for real or into a stub. Environments and configuration control that.
Environments
| Environment | Used for | Specifics |
|---|---|---|
dev | Development | The debug toolbar, detailed errors, the cache rebuilds itself |
test | Automated tests | A separate database, no emails are sent |
prod | The production server | Everything is cached, errors go only to the log |
The APP_ENV variable sets the environment.
The .env files
Symfony reads several files; values from later ones replace earlier ones:
| File | In the repository | Purpose |
|---|---|---|
.env | Yes | Defaults without secrets |
.env.local | No | Your machine's settings |
.env.test, .env.prod | Yes | Values for a particular environment |
.env.prod.local | No | Secrets of a particular server |
Real environment variables of the server outrank any file.
php bin/console debug:dotenvThe command shows which files were read and what values resulted.
Settings for one environment
In the files of the config/packages folder a when@ section applies only in the named environment:
# config/packages/framework.yaml
framework:
secret: '%env(APP_SECRET)%'
when@test:
framework:
test: true
when@prod:
framework:
http_cache: trueApplication parameters
Your own values that do not depend on the server go into config/services.yaml:
parameters:
app.posts_per_page: 20
app.support_email: 'help@example.com'use Symfony\Component\DependencyInjection\Attribute\Autowire;
class PostController extends AbstractController
{
public function __construct(
#[Autowire(param: 'app.posts_per_page')]
private int $perPage,
) {}
}In a controller a parameter can also be read like this: $this->getParameter('app.posts_per_page').
Env var processors
Environment variables are always strings. A prefix inside %env()% converts the value:
parameters:
app.debug_mail: '%env(bool:DEBUG_MAIL)%'
app.cache_ttl: '%env(int:CACHE_TTL)%'
app.admins: '%env(csv:ADMIN_EMAILS)%'
app.features: '%env(json:FEATURES)%'
app.region: '%env(default:app.default_region:REGION)%'The secrets vault
Production passwords and keys can be kept in the repository encrypted:
php bin/console secrets:generate-keys --env=prod
php bin/console secrets:set STRIPE_SECRET --env=prod
php bin/console secrets:list --env=prodA secret is read like an ordinary variable — %env(STRIPE_SECRET)%. The encrypted files live in config/secrets/prod, while the decryption key prod.decrypt.private.php stays out of the repository: it is placed on the server by hand or passed in the SYMFONY_DECRYPTION_SECRET variable.
Checking the configuration
php bin/console debug:config framework
php bin/console debug:container --parameters
php bin/console debug:container --env-varsCommon mistake
The .env file goes into the repository — secrets do not belong in it. Real passwords and keys are written to .env.local, to the server's environment variables or to the secrets vault. If a secret has already reached the repository history, deleting it from there is not enough: the key must be replaced.