Answers.Body: <p>We ended up writing to a .env file and using <code>vlucas/phpdotenv</code> to read it in at app start.  Getting the php-fpm process to access environment variables was otherwise too complicated:  The PHP process would need a login shell and source <code>/etc/environment</code> in addition to the above configuration.  Then, each variable would have to be defined in <code>www.conf</code>, pointing to the environment variable.</p>
  <p>Since we were writing variables out to <code>/etc/environment</code> at app server instance creation anyway, we just wrote out to <code>.env</code> instead and avoided the problem altogether.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-03-29T20:59:31.277Z
Answers.LastActivityDate: 2022-03-29T20:59:31.277Z
Answers.UserDisplayName: Micah Henning
Body: <p>Our new Craft CMS instance in the AWS cloud won't load the security key from an environment variable.  (We do not use a .env file.)</p>
  <pre class="lang-bash prettyprint-override"><code>$ curl http://localhost/actions/app/health-check
  An internal server error occurred.
  
  $ tail -n 50 /app/storage/logs/phperrors.log
  ...
  Next Twig\Error\RuntimeError: An exception has been thrown during the rendering of a template (&quot;craft\web\Request::cookieValidationKey must be configured with a secret key.&quot;). in /app/vendor/craftcms/cms/src/templates/_layouts/base.html:63
  Stack trace:
  #0 /app/vendor/twig/twig/src/Template.php(378): Twig\Template-&gt;displayWithErrorHandling()
  #1 /app/storage/runtime/compiled_templates/9e/9e97d03dbc595add011bcf027de03e51.php(48): Twig\Template-&gt;display()
  #2 /app/vendor/twig/twig/src/Template.php(405): __TwigTemplate_54cbc54ad2a53aab200b46bb9cdf59b5-&gt;doDisplay()
  #3 /app/vendor/twig/twig/src/Template.php(378): Twig\Template-&gt;displayWithErrorHandling()
  #4 /app/storage/runtime/compiled_templates/b7/b7bfcc96c0d5436ed2de6531041c624b.php(46): Twig\Template-&gt;display()
  #5 /app/vendor/twig/twig/src/Template.php(405): __TwigTemplate_b556258081d6ccb36bcd554f2672ce05-&gt;doDisplay()
  #6 /app/vendor/twig/twig/src/Template.php(378): Twig\Template-&gt;displayWithErrorHandling()
  #7 /app/vendor/twig/twig/src/Template.php(390): Twig\Template-&gt;display()
  #8 /app/vendor/twig/twig/src/TemplateWrapper.php(45): Twig\Template-&gt;render()
  #9 /app/vendor/twig/twig/src/Environment.php(318): Twig\TemplateWrapper-&gt;render()
  #10 /app/vendor/craftcms/cms/src/web/View.php(408): Twig\Environment-&gt;render()
  #11 /app/vendor/craftcms/cms/src/web/View.php(461): craft\web\View-&gt;renderTemplate()
  #12 /app/vendor/craftcms/cms/src/web/Controller.php(201): craft\web\View-&gt;renderPageTemplate()
  #13 /app/vendor/craftcms/cms/src/controllers/TemplatesController.php(233): craft\web\Controller-&gt;renderTemplate()
  #14 [internal function]: craft\controllers\TemplatesController-&gt;actionRenderError()
  #15 /app/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array()
  #16 /app/vendor/yiisoft/yii2/base/Controller.php(178): yii\base\InlineAction-&gt;runWithParams()
  #17 /app/vendor/yiisoft/yii2/base/Module.php(552): yii\base\Controller-&gt;runAction()
  #18 /app/vendor/craftcms/cms/src/web/Application.php(293): yii\base\Module-&gt;runAction()
  #19 /app/vendor/yiisoft/yii2/web/ErrorHandler.php(109): craft\web\Application-&gt;runAction()
  #20 /app/vendor/craftcms/cms/src/web/ErrorHandler.php(192): yii\web\ErrorHandler-&gt;renderException()
  #21 /app/vendor/yiisoft/yii2/base/ErrorHandler.php(135): craft\web\ErrorHandler-&gt;renderException()
  #22 /app/vendor/craftcms/cms/src/web/ErrorHandler.php(71): yii\base\ErrorHandler-&gt;handleException()
  #23 [internal function]: craft\web\ErrorHandler-&gt;handleException()
  #24 {main}
  Previous exception:
  craft\web\ServiceUnavailableHttpException in /app/vendor/craftcms/cms/src/web/Application.php:571
  Stack trace:
  #0 /app/vendor/craftcms/cms/src/web/Application.php(201): craft\web\Application-&gt;_processInstallRequest()
  #1 /app/vendor/yiisoft/yii2/base/Application.php(384): craft\web\Application-&gt;handleRequest()
  #2 /app/web/index.php(21): yii\base\Application-&gt;run()
  #3 {main}
  </code></pre>
  <h4><code>/app/config/general.php</code></h4>
  <pre class="lang-php prettyprint-override"><code>&lt;?php
  /**
   * General Configuration
   *
   * All of your system's general configuration settings go in here. You can see a
   * list of the available settings in vendor/craftcms/cms/src/config/GeneralConfig.php.
   *
   * @see \craft\config\GeneralConfig
   */
  
  return [
    // Global settings
    '*' =&gt; [
      // Default Week Start Day (0 = Sunday, 1 = Monday...)
      'defaultWeekStartDay' =&gt; 1,
  
      // Whether generated URLs should omit &quot;index.php&quot;
      'omitScriptNameInUrls' =&gt; true,
  
      // Control Panel access via environment variable
      'baseCpUrl' =&gt; craft\helpers\App::env('BASE_CP_URL') ?: null,
  
      // Control Panel trigger word
      'cpTrigger' =&gt; 'admin',
  
      // The secure key Craft will use for hashing and encrypting data
      'securityKey' =&gt; craft\helpers\App::env('SECURITY_KEY'),
  
      // Whether to save the project config out to config/project.yaml
      // (see https://docs.craftcms.com/v3/project-config.html)
      'useProjectConfigFile' =&gt; false,
  
      // dont set X-Powered-By server-side header
      'sendPoweredByHeader' =&gt; false,
  
      // account lockouts require admin to unlock
      'cooldownDuration' =&gt; 0,
  
      // set cookie attribute samesite to lax
      'sameSiteCookieValue' =&gt; 'Lax',
    ],
  
    // Dev environment settings
    'development' =&gt; [
      // Dev Mode (see https://craftcms.com/guides/what-dev-mode-does)
      'devMode' =&gt; true,
    ],
  
    // Staging environment settings
    'staging' =&gt; [
      // Set this to `false` to prevent administrative changes from being made on staging
      'allowAdminChanges' =&gt; false,
    ],
  
    // Production environment settings
    'production' =&gt; [
      // Set this to `false` to prevent administrative changes from being made on production
      'allowAdminChanges' =&gt; false,
    ],
  ];
  </code></pre>
  <h4>Configuration details</h4>
  <p>We have the default PHP systemd service loading <code>/etc/environment</code>, which contains variable <code>SECURITY_KEY</code>.  Craft CMS config file <code>/app/config/general.php</code> gets the security key from the environment.  PHP is configured to use environment variables first, and to not override them.  Furthermore, when I enter the PHP console and output the environment variables, I can see it in the list.</p>
  <pre class="lang-bash prettyprint-override"><code>$ cat /etc/systemd/system/multi-user.target.wants/php8.1-fpm.service 
  [Unit]
  Description=The PHP 8.1 FastCGI Process Manager
  Documentation=man:php-fpm8.1(8)
  After=network.target
  
  [Service]
  EnvironmentFile=/etc/environment
  Type=notify
  ExecStart=/usr/sbin/php-fpm8.1 --nodaemonize --fpm-config /etc/php/8.1/fpm/php-fpm.conf
  ExecStartPost=-/usr/lib/php/php-fpm-socket-helper install /run/php/php-fpm.sock /etc/php/8.1/fpm/pool.d/www.conf 81
  ExecStopPost=-/usr/lib/php/php-fpm-socket-helper remove /run/php/php-fpm.sock /etc/php/8.1/fpm/pool.d/www.conf 81
  ExecReload=/bin/kill -USR2 $MAINPID
  
  [Install]
  WantedBy=multi-user.target
  </code></pre>
  <pre class="lang-bash prettyprint-override"><code>$ cat /etc/environment | grep SEC
  SECURITY_KEY=tjsg6CzzuHBCNF9smvSA_5WKqA-5VJTl
  </code></pre>
  <pre class="lang-bash prettyprint-override"><code>$ cat /etc/php/8.1/fpm/php-fpm.conf | grep &quot;^[^;]&quot;
  [global]
  pid = /run/php/php-fpm.pid
  error_log = /var/log/php-fpm.log
  include=/etc/php/8.1/fpm/pool.d/*.conf
  </code></pre>
  <pre class="lang-bash prettyprint-override"><code>$ cat /etc/php/8.1/fpm/pool.d/www.conf | grep &quot;^[^;]&quot;
  [www]
  user = www-data
  group = www-data
  listen = /run/php/php-fpm.sock
  listen.owner = www-data
  listen.group = www-data
  pm = dynamic
  pm.max_children = 5
  pm.start_servers = 2
  pm.min_spare_servers = 1
  pm.max_spare_servers = 3
  clear_env = no
  </code></pre>
  <pre class="lang-bash prettyprint-override"><code>$ cat /etc/php/8.1/fpm/php.ini | grep variables_order\ =
  variables_order = &quot;EGPCS&quot;
  </code></pre>
  <pre class="lang-php prettyprint-override"><code>$ php -a
  Interactive shell
  
  php &gt; print_r(getenv());
  Array
  (
      // ...
      [SECURITY_KEY] =&gt; tjsg6CzzuHBCNF9smvSA_5WKqA-5VJTl
      // ...
  )
  </code></pre>
  <h4>Environment details</h4>
  <pre class="lang-bash prettyprint-override"><code>$ cat composer.json | grep craftcms/cms
      &quot;craftcms/cms&quot;: &quot;3.7.36&quot;,
  </code></pre>
  <pre class="lang-bash prettyprint-override"><code>$ echo $(which php)
  /usr/bin/php
  
  $ php --version
  PHP 8.1.3 (cli) (built: Feb 21 2022 14:48:42) (NTS)
  Copyright (c) The PHP Group
  Zend Engine v4.1.3, Copyright (c) Zend Technologies
      with Zend OPcache v8.1.3, Copyright (c), by Zend Technologies
  
  $ php --modules
  [PHP Modules]
  bcmath
  calendar
  Core
  ctype
  curl
  date
  dom
  exif
  FFI
  fileinfo
  filter
  ftp
  gettext
  hash
  iconv
  imagick
  intl
  json
  libxml
  mbstring
  mysqli
  mysqlnd
  openssl
  pcntl
  pcre
  PDO
  pdo_mysql
  Phar
  posix
  readline
  Reflection
  session
  shmop
  SimpleXML
  sockets
  sodium
  SPL
  standard
  sysvmsg
  sysvsem
  sysvshm
  tokenizer
  xml
  xmlreader
  xmlwriter
  xsl
  Zend OPcache
  zip
  zlib
  
  [Zend Modules]
  Zend OPcache
  </code></pre>
  <pre class="lang-bash prettyprint-override"><code>$ uname -a
  Linux ip-10-14-32-107 5.13.0-1017-aws #19~20.04.1-Ubuntu SMP Mon Mar 7 12:55:31 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
  </code></pre>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-03-21T11:10:23.447Z
Comments.Text: Which version of `vlucas/phpdotenv` do you use?
Comments.UserDisplayName: Oli
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-03-21T12:08:34.837Z
Comments.Text: @Oli thanks for your reply! `composer.lock` shows `vlucas/phpdotenv` at v3.6.10
Comments.UserDisplayName: Micah Henning
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-03-21T12:50:32.720Z
Comments.Text: Not sure it will work but could you update to `^5.4.0` then change the call in your `web/index.php` to [this](https://github.com/craftcms/craft/blob/main/bootstrap.php#L15).
Comments.UserDisplayName: Oli
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2022-03-21T17:45:53.287Z
Comments.Text: I updated the library and changed the call in `web/index.php` but am still getting the same error.  :(
Comments.UserDisplayName: Micah Henning
Tags: <craft3><php><deployment>
Title: Security Key Not Loading from Environment: Next Twig\Error\RuntimeError: craft\web\Request::cookieValidationKey must be configured with a secret key
ThreadText: # Security Key Not Loading from Environment: Next Twig\Error\RuntimeError: craft\web\Request::cookieValidationKey must be configured with a secret key
  
  (Asked by: username_0 on 2022-03-16)
  
  Our new Craft CMS instance in the AWS cloud won't load the security key from an environment variable. (We do not use a .env file.)
  
  ```bash
  $ curl http://localhost/actions/app/health-check
  An internal server error occurred.
  
  $ tail -n 50 /app/storage/logs/phperrors.log
  ...
  Next Twig\Error\RuntimeError: An exception has been thrown during the rendering of a template ("craft\web\Request::cookieValidationKey must be configured with a secret key."). in /app/vendor/craftcms/cms/src/templates/_layouts/base.html:63
  Stack trace:
  #0 /app/vendor/twig/twig/src/Template.php(378): Twig\Template->displayWithErrorHandling()
  #1 /app/storage/runtime/compiled_templates/9e/9e97d03dbc595add011bcf027de03e51.php(48): Twig\Template->display()
  #2 /app/vendor/twig/twig/src/Template.php(405): __TwigTemplate_54cbc54ad2a53aab200b46bb9cdf59b5->doDisplay()
  #3 /app/vendor/twig/twig/src/Template.php(378): Twig\Template->displayWithErrorHandling()
  #4 /app/storage/runtime/compiled_templates/b7/b7bfcc96c0d5436ed2de6531041c624b.php(46): Twig\Template->display()
  #5 /app/vendor/twig/twig/src/Template.php(405): __TwigTemplate_b556258081d6ccb36bcd554f2672ce05->doDisplay()
  #6 /app/vendor/twig/twig/src/Template.php(378): Twig\Template->displayWithErrorHandling()
  #7 /app/vendor/twig/twig/src/Template.php(390): Twig\Template->display()
  #8 /app/vendor/twig/twig/src/TemplateWrapper.php(45): Twig\Template->render()
  #9 /app/vendor/twig/twig/src/Environment.php(318): Twig\TemplateWrapper->render()
  #10 /app/vendor/craftcms/cms/src/web/View.php(408): Twig\Environment->render()
  #11 /app/vendor/craftcms/cms/src/web/View.php(461): craft\web\View->renderTemplate()
  #12 /app/vendor/craftcms/cms/src/web/Controller.php(201): craft\web\View->renderPageTemplate()
  #13 /app/vendor/craftcms/cms/src/controllers/TemplatesController.php(233): craft\web\Controller->renderTemplate()
  #14 [internal function]: craft\controllers\TemplatesController->actionRenderError()
  #15 /app/vendor/yiisoft/yii2/base/InlineAction.php(57): call_user_func_array()
  #16 /app/vendor/yiisoft/yii2/base/Controller.php(178): yii\base\InlineAction->runWithParams()
  #17 /app/vendor/yiisoft/yii2/base/Module.php(552): yii\base\Controller->runAction()
  #18 /app/vendor/craftcms/cms/src/web/Application.php(293): yii\base\Module->runAction()
  #19 /app/vendor/yiisoft/yii2/web/ErrorHandler.php(109): craft\web\Application->runAction()
  #20 /app/vendor/craftcms/cms/src/web/ErrorHandler.php(192): yii\web\ErrorHandler->renderException()
  #21 /app/vendor/yiisoft/yii2/base/ErrorHandler.php(135): craft\web\ErrorHandler->renderException()
  #22 /app/vendor/craftcms/cms/src/web/ErrorHandler.php(71): yii\base\ErrorHandler->handleException()
  #23 [internal function]: craft\web\ErrorHandler->handleException()
  #24 {main}
  Previous exception:
  craft\web\ServiceUnavailableHttpException in /app/vendor/craftcms/cms/src/web/Application.php:571
  Stack trace:
  #0 /app/vendor/craftcms/cms/src/web/Application.php(201): craft\web\Application->_processInstallRequest()
  #1 /app/vendor/yiisoft/yii2/base/Application.php(384): craft\web\Application->handleRequest()
  #2 /app/web/index.php(21): yii\base\Application->run()
  #3 {main}
  
  ```
  
  #### `/app/config/general.php`
  
  ```php
  <?php
  /**
   * General Configuration
   *
   * All of your system's general configuration settings go in here. You can see a
   * list of the available settings in vendor/craftcms/cms/src/config/GeneralConfig.php.
   *
   * @see \craft\config\GeneralConfig
   */
  
  return [
    // Global settings
    '*' => [
      // Default Week Start Day (0 = Sunday, 1 = Monday...)
      'defaultWeekStartDay' => 1,
  
      // Whether generated URLs should omit "index.php"
      'omitScriptNameInUrls' => true,
  
      // Control Panel access via environment variable
      'baseCpUrl' => craft\helpers\App::env('BASE_CP_URL') ?: null,
  
      // Control Panel trigger word
      'cpTrigger' => 'admin',
  
      // The secure key Craft will use for hashing and encrypting data
      'securityKey' => craft\helpers\App::env('SECURITY_KEY'),
  
      // Whether to save the project config out to config/project.yaml
      // (see https://docs.craftcms.com/v3/project-config.html)
      'useProjectConfigFile' => false,
  
      // dont set X-Powered-By server-side header
      'sendPoweredByHeader' => false,
  
      // account lockouts require admin to unlock
      'cooldownDuration' => 0,
  
      // set cookie attribute samesite to lax
      'sameSiteCookieValue' => 'Lax',
    ],
  
    // Dev environment settings
    'development' => [
      // Dev Mode (see https://craftcms.com/guides/what-dev-mode-does)
      'devMode' => true,
    ],
  
    // Staging environment settings
    'staging' => [
      // Set this to `false` to prevent administrative changes from being made on staging
      'allowAdminChanges' => false,
    ],
  
    // Production environment settings
    'production' => [
      // Set this to `false` to prevent administrative changes from being made on production
      'allowAdminChanges' => false,
    ],
  ];
  
  ```
  
  #### Configuration details
  
  We have the default PHP systemd service loading `/etc/environment`, which contains variable `SECURITY_KEY`. Craft CMS config file `/app/config/general.php` gets the security key from the environment. PHP is configured to use environment variables first, and to not override them. Furthermore, when I enter the PHP console and output the environment variables, I can see it in the list.
  
  ```bash
  $ cat /etc/systemd/system/multi-user.target.wants/php8.1-fpm.service 
  [Unit]
  Description=The PHP 8.1 FastCGI Process Manager
  Documentation=man:php-fpm8.1(8)
  After=network.target
  
  [Service]
  EnvironmentFile=/etc/environment
  Type=notify
  ExecStart=/usr/sbin/php-fpm8.1 --nodaemonize --fpm-config /etc/php/8.1/fpm/php-fpm.conf
  ExecStartPost=-/usr/lib/php/php-fpm-socket-helper install /run/php/php-fpm.sock /etc/php/8.1/fpm/pool.d/www.conf 81
  ExecStopPost=-/usr/lib/php/php-fpm-socket-helper remove /run/php/php-fpm.sock /etc/php/8.1/fpm/pool.d/www.conf 81
  ExecReload=/bin/kill -USR2 $MAINPID
  
  [Install]
  WantedBy=multi-user.target
  
  ```
  
  ```bash
  $ cat /etc/environment | grep SEC
  SECURITY_KEY=tjsg6CzzuHBCNF9smvSA_5WKqA-5VJTl
  
  ```
  
  ```bash
  $ cat /etc/php/8.1/fpm/php-fpm.conf | grep "^[^;]"
  [global]
  pid = /run/php/php-fpm.pid
  error_log = /var/log/php-fpm.log
  include=/etc/php/8.1/fpm/pool.d/*.conf
  
  ```
  
  ```bash
  $ cat /etc/php/8.1/fpm/pool.d/www.conf | grep "^[^;]"
  [www]
  user = www-data
  group = www-data
  listen = /run/php/php-fpm.sock
  listen.owner = www-data
  listen.group = www-data
  pm = dynamic
  pm.max_children = 5
  pm.start_servers = 2
  pm.min_spare_servers = 1
  pm.max_spare_servers = 3
  clear_env = no
  
  ```
  
  ```bash
  $ cat /etc/php/8.1/fpm/php.ini | grep variables_order\ =
  variables_order = "EGPCS"
  
  ```
  
  ```php
  $ php -a
  Interactive shell
  
  php > print_r(getenv());
  Array
  (
      // ...
      [SECURITY_KEY] => tjsg6CzzuHBCNF9smvSA_5WKqA-5VJTl
      // ...
  )
  
  ```
  
  #### Environment details
  
  ```bash
  $ cat composer.json | grep craftcms/cms
      "craftcms/cms": "3.7.36",
  
  ```
  
  ```bash
  $ echo $(which php)
  /usr/bin/php
  
  $ php --version
  PHP 8.1.3 (cli) (built: Feb 21 2022 14:48:42) (NTS)
  Copyright (c) The PHP Group
  Zend Engine v4.1.3, Copyright (c) Zend Technologies
      with Zend OPcache v8.1.3, Copyright (c), by Zend Technologies
  
  $ php --modules
  [PHP Modules]
  bcmath
  calendar
  Core
  ctype
  curl
  date
  dom
  exif
  FFI
  fileinfo
  filter
  ftp
  gettext
  hash
  iconv
  imagick
  intl
  json
  libxml
  mbstring
  mysqli
  mysqlnd
  openssl
  pcntl
  pcre
  PDO
  pdo_mysql
  Phar
  posix
  readline
  Reflection
  session
  shmop
  SimpleXML
  sockets
  sodium
  SPL
  standard
  sysvmsg
  sysvsem
  sysvshm
  tokenizer
  xml
  xmlreader
  xmlwriter
  xsl
  Zend OPcache
  zip
  zlib
  
  [Zend Modules]
  Zend OPcache
  
  ```
  
  ```bash
  $ uname -a
  Linux ip-10-14-32-107 5.13.0-1017-aws #19~20.04.1-Ubuntu SMP Mon Mar 7 12:55:31 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
  
  ```
  
  **Tags:** craft3, php, deployment
  
  > **Comments:**
  > **username_1**: Which version of `vlucas/phpdotenv` do you use?  
  > **username_0**: @username_1 thanks for your reply! `composer.lock` shows `vlucas/phpdotenv` at v3.6.10  
  > **username_1**: Not sure it will work but could you update to `^5.4.0` then change the call in your `web/index.php` to [this](https://github.com/craftcms/craft/blob/main/bootstrap.php#L15).  
  > **username_0**: I updated the library and changed the call in `web/index.php` but am still getting the same error.  :(  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2022-03-29. Score: 2 | Accepted answer
  
  We ended up writing to a .env file and using `vlucas/phpdotenv` to read it in at app start. Getting the php-fpm process to access environment variables was otherwise too complicated: The PHP process would need a login shell and source `/etc/environment` in addition to the above configuration. Then, each variable would have to be defined in `www.conf`, pointing to the environment variable.
  
  Since we were writing variables out to `/etc/environment` at app server instance creation anyway, we just wrote out to `.env` instead and avoided the problem altogether.
  
  
  ---
  
  