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 SubscribeI don't want to get too far into deployment, but let's do a quick "How To Deploy Your Symfony App 101" course. Here's the idea.
Deployment 101
Step 1: You need to somehow get all of your committed code onto your production machine and then run
composer install
to populate the vendor/
directory.
Step 2: Somehow create a .env.local
file with all of your production environment variables, which will include APP_ENV=prod
, so that you're in the prod environment.
And Step 3: run
php bin/console cache:clear
which will clear the cache in the production environment, and then
php bin/console cache:warmup
to "warm up" the cache. There may be a few other commands, like running your database migrations... but this is the general idea. And the Symfony docs have more details.
By the way, in case you're wondering, we deploy via https://platform.sh, using Symfony's Cloud integration... which handles a lot of stuff for us. You can check it out by going to https://symfony.com/cloud. It also helps support the Symfony project, so it's a win-win.
Use Real Environment Variables When Possible
Anyway, the trickiest part of the process is Step 2 - creating the .env.local
file with all of your production values, which will include things like API keys, your database connection details and more.
Now, if your hosting platform allows you to store real environment variables directly inside of it, problem solved! If you set real env vars, then there is no need to manage a .env.local
file at all. As soon as you deploy, Symfony will instantly see and use the real env vars. That's what we do for Symfonycasts.
Creating .env.local During Deploy?
But if that's not an option for you, you'll need to somehow give your deployment system access to your sensitive values so that it can create the .env.local
file. But... since we're not committing any of these values to our repository, where should we store them?
One option for handling sensitive values is Symfony's secrets vault. It's a set of files that contain environment variables in an encrypted form. These files are safe to commit to your repository... because they're encrypted!
Creating the dev Vault
If you want to store secrets in a vault, you'll need two of them: one for the dev
environment and one for the prod
environment. We're going to create these two vaults first... then I'll explain how to read values out of them.
Start by creating one for the dev
environment. Run:
php bin/console secrets:set
Pass this GITHUB_TOKEN
, which is the secret we want to set. It then asks for our "secret value". Since this is the vault for the dev
environment, we want to put something that's safe for everyone to see. I'll explain why in a moment. I'll say CHANGEME
. You can't see me type that... only because Symfony hides it for security reasons.
Since this is the first secret we've created, Symfony automatically created the secrets vault behind the scenes... which is literally a set of files that live in config/secrets/dev/
. For the dev vault, we're going to commit all of these files to the repository. Let's do that. Add the entire secrets directory:
git add config/secrets/dev
Then commit with:
git commit -m "adding dev secrets vault"
The Secrets Vault Files
Here's a quick explanation of the files. dev.list.php
stores a list of which values live inside the vault, dev.GITHUB_TOKEN.28bd2f.php
stores the actual encrypted value, and dev.encrypt.public.php
is the cryptographic key that allows developers on your team to add more secrets. So if another developer pulled down the project, they'll have this file... so they can add more secrets. Finally, dev.decrypt.private.php
is the secret key that allows us to decrypt and read the values in the vault.
As soon as the vault files are present, Symfony will automatically open them, decrypt the secrets, and expose them as environment variables! But, more on that in a few minutes.
Storing the dev Decrypt Key?
But wait: did we really just commit the decrypt
key to the repository? Yes! That would normally be a no-no! Why would you go to the trouble of encrypting values... just to store the decryption key right next to them?
The reason we're doing exactly that is that this is our dev vault, which means we're only going to store values that are safe for all developers to look at. The dev
vault will only be used local development... and we want our teammates to be able to pull down the code and read those without any trouble.
Ok, at this point we have a dev
vault that Symfony will automatically use in the dev
environment. Next: let's create the prod vault, which will hold the truly secret values. We'll then learn relationship between vault secrets and environment variables... as well as an easy way to visualize all of this.
13 Comments


Seems it was obvious. For anybody as thick as me that ends up with the same quandary, the SYMFONY_DECRYPTION_SECRET needs to be in the .env file and not a server environment variable.

Hey @phpbutcher
I'd need to double-check but as far as I know, you should be able to set it as a server env var. Is it possible that you were overriding its value in the .env
or .env.local
file?
Cheers!


So I know I must be missing something simple but I've read the docs and I either missed it or I'm just not getting it. I was under the impression that once I added a variable to the secrets vault it would be available in my controller as $_ENV['MY_SECRET_VARIABLE'] but that doesn't seem to be the case. The only references I've seen in the doc were to use them in config files with '%env(MY_SECRET_VARIABLE)%'.
I'm hoping someone can explain either what I'm missing in the docs or what I need to do to use the secret variables directly in my controllers.
Thanks for any help
Hey @phpbutcher!
Yea, this is a good question. The secrets become "environment variables in Symfony", but I'm pretty sure that they're not written back to $_ENV
(and your experience confirms that). But to answer your question, to use a value directly in your controller, I would:
public function myAction(
#[Autowire(env: 'MY_SECRET_VARIABLE') string $mySecretVariable
)
{
}
That should do it :). The Autowire
attribute is relatively new (the env
argument is even newer), but this can be used for controller args or the __construct()
method in any service.
Let me know if that helps!
Cheers!


Thanks for the reply Ryan!
That would be an awesome suggestion except I lied a little in my OP. Some of the secret variables I am indeed trying to use in a controller that extends AbstractController but some are not. I did manage to solve my problem in those cases this morning by binding them in /config/services.yaml. I originally thought that wasn't working because I put the bind in like so ( for the future benefit of others like me) and it threw an error because it seems as soon as you put a bind variable in services.yaml it has to be used somewhere and I hadn't done that yet.
services:
_default:
bind:
$myVar: '%env(MY_SECRET)%'`
And then in my LoginFormAuthenticator class:
__construct(UserProvider $userProvider, RouterInterface $router, string $myVar)
If there's a better/easier way to do it I'd love to hear it.
Thanks again Ryan! I will make use of the Autowire(env: thing in my Controllers. It makes it much more obvious to others where that value is coming from.


Ryan,
It seems I didn't read your reply close enough. Your Autowire suggestion does work in both the Controller and LoginFormAuthenticator.
Thanks for taking the time to Respond. It makes the Symfony Casts so much more valuable.
Sweeet! Super happy it worked!


A tutorial on deployment might be an interesting idea :)
Hey Rufnex,
We do have a tutorial about deployment already! :) Take a look at Ansistrano tool: https://symfonycasts.com/screencast/ansistrano - it's based on Ansible automation language, but you're not required to know it to start this deployment course as its syntax is pretty descriptive. Moreover we explain it during the course well I think. But in case you're interested in Ansible to learn its syntax deeper - we also have a separate tutorial about it here: https://symfonycasts.com/screencast/ansible
Cheers!


Thank you Victor. I will check it out.
Hey Rufnex,
You're welcome! If you have any use cases that are not covered with that Ansistrano deploy tutorial - please, let us know in the comments! It would definitely help us to plan a new deploy tutorial in the future :)
Cheers!
Hey,
Thanks for the feedback, I'll put your idea in our list =)
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
}
}
Hi all,
I've been trying to use the base64 encrypted version of my private key for the secrets vault and I must be missing something. I have encrypted the password according to the docs
php -r 'echo base64_encode(require "config/secrets/prod/prod.decrypt.private.php");'
and set that value on the server as an environment variable SYMFONY_DECRYPTION_SECRET but the app still doesn't find the variables in the vault.
Am I missing something obvious?
Thanks!