Skip to content

Deploy hooks inherit APP_ENV=dev from dploy's embedded .env.local, overriding the application's .env (Laravel/Symfony) #10

Description

@oogabrielgodoy

Summary

Commands executed by dploy (before_commands / after_commands) inherit APP_ENV=dev (and APP_DEBUG=1) from dploy's own Symfony runtime. For Laravel/Symfony applications, real environment variables take precedence over the application's .env file, so a php artisan optimize deploy hook caches the application config with env=dev and debug=true — in production.

Impact

  • Laravel apps deployed with the stock laravel template end up running with APP_ENV=dev and debug mode enabled, even when the overlay .env correctly sets APP_ENV=production / APP_DEBUG=false.
  • Debug mode in production exposes stack traces and environment values on error pages, so this is effectively a security issue.
  • It is very confusing to diagnose: running the exact same php artisan optimize manually as the site user produces the correct result. Only commands executed through dploy are affected.

Root cause

  1. The dploy PHAR ships its own .env.local containing APP_ENV=dev:
    https://github.com/cloudpanel-io/dploy/blob/master/.env.local
  2. The Symfony Runtime loads it and populates APP_ENV (deriving APP_DEBUG=1 for the dev environment) into the process environment of the running PHAR.
  3. CommandExecutor runs the hooks via Process::fromShellCommandline(...) without cleaning the environment, so child processes inherit APP_ENV / APP_DEBUG:
    https://github.com/cloudpanel-io/dploy/blob/master/src/Deployment/Command/CommandExecutor.php
  4. In Laravel (and Symfony) applications, real environment variables win over the .env file, so the deployed app gets configured as dev with debug enabled.

Steps to reproduce

  1. dploy init laravel for any Laravel app; put a production .env (APP_ENV=production, APP_DEBUG=false) in ~/.dploy/overlays/.env.
  2. Keep the template's php8.x artisan optimize as a before_command.
  3. Run dploy deploy main.
  4. In the new release: php artisan about shows Environment: dev / Debug Mode: ENABLED (from the cached config), while the .env in the very same directory says production.
  5. Run php artisan optimize manually inside the release: php artisan about now correctly shows production / OFF.

Workaround

Prefix the hook commands with env -u APP_ENV -u APP_DEBUG ... (or call a shell script that does unset APP_ENV APP_DEBUG before running artisan/console commands).

Suggested fix

Execute before_commands / after_commands with a cleaned environment — e.g. strip the PHAR runtime's own variables (APP_ENV, APP_DEBUG, APP_SECRET, APP_VERSION, SYMFONY_DOTENV_VARS, ...) before Process::run(), or start the process with an explicit environment instead of inheriting the parent's.

Environment

  • dploy: latest release (July 2026)
  • CloudPanel v2 on Debian, PHP 8.4 site (FPM)
  • Application: Laravel 12 using the stock laravel template

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions