diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php
index 7fa12757e..bd45c09c6 100644
--- a/app/Jobs/ApplicationDeploymentJob.php
+++ b/app/Jobs/ApplicationDeploymentJob.php
@@ -18,6 +18,7 @@ use App\Models\StandaloneDocker;
use App\Models\SwarmDocker;
use App\Notifications\Application\DeploymentFailed;
use App\Notifications\Application\DeploymentSuccess;
+use App\Traits\EnvironmentVariableAnalyzer;
use App\Traits\ExecuteRemoteCommand;
use Carbon\Carbon;
use Exception;
@@ -39,7 +40,7 @@ use Yosymfony\Toml\Toml;
class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
{
- use Dispatchable, ExecuteRemoteCommand, InteractsWithQueue, Queueable, SerializesModels;
+ use Dispatchable, EnvironmentVariableAnalyzer, ExecuteRemoteCommand, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 1;
@@ -2710,6 +2711,30 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
$this->application_deployment_queue->addLogEntry('New container started.');
}
+ private function analyzeBuildTimeVariables($variables)
+ {
+ $variablesArray = $variables->toArray();
+ $warnings = self::analyzeBuildVariables($variablesArray);
+
+ if (empty($warnings)) {
+ return;
+ }
+ $this->application_deployment_queue->addLogEntry('----------------------------------------');
+ foreach ($warnings as $warning) {
+ $messages = self::formatBuildWarning($warning);
+ foreach ($messages as $message) {
+ $this->application_deployment_queue->addLogEntry($message, type: 'warning');
+ }
+ $this->application_deployment_queue->addLogEntry('');
+ }
+
+ // Add general advice
+ $this->application_deployment_queue->addLogEntry('💡 Tips to resolve build issues:', type: 'info');
+ $this->application_deployment_queue->addLogEntry(' 1. Set these variables as "Runtime only" in the environment variables settings', type: 'info');
+ $this->application_deployment_queue->addLogEntry(' 2. Use different values for build-time (e.g., NODE_ENV=development for build)', type: 'info');
+ $this->application_deployment_queue->addLogEntry(' 3. Consider using multi-stage Docker builds to separate build and runtime environments', type: 'info');
+ }
+
private function generate_build_env_variables()
{
if ($this->application->build_pack === 'nixpacks') {
@@ -2719,6 +2744,11 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
$variables = collect([])->merge($this->env_args);
}
+ // Analyze build variables for potential issues
+ if ($variables->isNotEmpty()) {
+ $this->analyzeBuildTimeVariables($variables);
+ }
+
if ($this->dockerBuildkitSupported && $this->application->settings->use_build_secrets) {
$this->generate_build_secrets($variables);
$this->build_args = '';
diff --git a/app/Livewire/Project/Shared/EnvironmentVariable/Add.php b/app/Livewire/Project/Shared/EnvironmentVariable/Add.php
index 23a2cd59d..5f5e12e0a 100644
--- a/app/Livewire/Project/Shared/EnvironmentVariable/Add.php
+++ b/app/Livewire/Project/Shared/EnvironmentVariable/Add.php
@@ -2,12 +2,13 @@
namespace App\Livewire\Project\Shared\EnvironmentVariable;
+use App\Traits\EnvironmentVariableAnalyzer;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Component;
class Add extends Component
{
- use AuthorizesRequests;
+ use AuthorizesRequests, EnvironmentVariableAnalyzer;
public $parameters;
@@ -27,6 +28,8 @@ class Add extends Component
public bool $is_buildtime = true;
+ public array $problematicVariables = [];
+
protected $listeners = ['clearAddEnv' => 'clear'];
protected $rules = [
@@ -50,6 +53,7 @@ class Add extends Component
public function mount()
{
$this->parameters = get_route_parameters();
+ $this->problematicVariables = self::getProblematicVariablesForFrontend();
}
public function submit()
diff --git a/app/Livewire/Project/Shared/EnvironmentVariable/Show.php b/app/Livewire/Project/Shared/EnvironmentVariable/Show.php
index 0d0467c13..3b8d244cc 100644
--- a/app/Livewire/Project/Shared/EnvironmentVariable/Show.php
+++ b/app/Livewire/Project/Shared/EnvironmentVariable/Show.php
@@ -4,13 +4,14 @@ namespace App\Livewire\Project\Shared\EnvironmentVariable;
use App\Models\EnvironmentVariable as ModelsEnvironmentVariable;
use App\Models\SharedEnvironmentVariable;
+use App\Traits\EnvironmentVariableAnalyzer;
use App\Traits\EnvironmentVariableProtection;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Component;
class Show extends Component
{
- use AuthorizesRequests, EnvironmentVariableProtection;
+ use AuthorizesRequests, EnvironmentVariableAnalyzer, EnvironmentVariableProtection;
public $parameters;
@@ -48,6 +49,8 @@ class Show extends Component
public bool $is_redis_credential = false;
+ public array $problematicVariables = [];
+
protected $listeners = [
'refreshEnvs' => 'refresh',
'refresh',
@@ -77,6 +80,7 @@ class Show extends Component
if ($this->type === 'standalone-redis' && ($this->env->key === 'REDIS_PASSWORD' || $this->env->key === 'REDIS_USERNAME')) {
$this->is_redis_credential = true;
}
+ $this->problematicVariables = self::getProblematicVariablesForFrontend();
}
public function getResourceProperty()
diff --git a/app/Traits/EnvironmentVariableAnalyzer.php b/app/Traits/EnvironmentVariableAnalyzer.php
new file mode 100644
index 000000000..a2fe0eeba
--- /dev/null
+++ b/app/Traits/EnvironmentVariableAnalyzer.php
@@ -0,0 +1,221 @@
+ [
+ 'problematic_values' => ['production', 'prod'],
+ 'affects' => 'Node.js/npm/yarn',
+ 'issue' => 'Skips devDependencies installation which are often required for building (webpack, typescript, etc.)',
+ 'recommendation' => 'Uncheck "Available at Buildtime" or use "development" during build',
+ ],
+ 'NPM_CONFIG_PRODUCTION' => [
+ 'problematic_values' => ['true', '1', 'yes'],
+ 'affects' => 'npm',
+ 'issue' => 'Forces npm to skip devDependencies',
+ 'recommendation' => 'Remove from build-time variables or set to false',
+ ],
+ 'YARN_PRODUCTION' => [
+ 'problematic_values' => ['true', '1', 'yes'],
+ 'affects' => 'Yarn',
+ 'issue' => 'Forces yarn to skip devDependencies',
+ 'recommendation' => 'Remove from build-time variables or set to false',
+ ],
+ 'COMPOSER_NO_DEV' => [
+ 'problematic_values' => ['1', 'true', 'yes'],
+ 'affects' => 'PHP/Composer',
+ 'issue' => 'Skips require-dev packages which may include build tools',
+ 'recommendation' => 'Set as "Runtime only" or remove from build-time variables',
+ ],
+ 'MIX_ENV' => [
+ 'problematic_values' => ['prod', 'production'],
+ 'affects' => 'Elixir/Phoenix',
+ 'issue' => 'Production mode may skip development dependencies needed for compilation',
+ 'recommendation' => 'Use "dev" for build or set as "Runtime only"',
+ ],
+ 'RAILS_ENV' => [
+ 'problematic_values' => ['production'],
+ 'affects' => 'Ruby on Rails',
+ 'issue' => 'May affect asset precompilation and dependency handling',
+ 'recommendation' => 'Consider using "development" for build phase',
+ ],
+ 'RACK_ENV' => [
+ 'problematic_values' => ['production'],
+ 'affects' => 'Ruby/Rack',
+ 'issue' => 'May affect dependency handling and build behavior',
+ 'recommendation' => 'Consider using "development" for build phase',
+ ],
+ 'BUNDLE_WITHOUT' => [
+ 'problematic_values' => ['development', 'test', 'development:test'],
+ 'affects' => 'Ruby/Bundler',
+ 'issue' => 'Excludes gem groups that may contain build dependencies',
+ 'recommendation' => 'Remove from build-time variables or adjust groups',
+ ],
+ 'FLASK_ENV' => [
+ 'problematic_values' => ['production'],
+ 'affects' => 'Python/Flask',
+ 'issue' => 'May affect debug mode and development tools availability',
+ 'recommendation' => 'Usually safe, but consider "development" for complex builds',
+ ],
+ 'DJANGO_SETTINGS_MODULE' => [
+ 'problematic_values' => [], // Check if contains 'production' or 'prod'
+ 'affects' => 'Python/Django',
+ 'issue' => 'Production settings may disable debug tools needed during build',
+ 'recommendation' => 'Use development settings for build phase',
+ 'check_function' => 'checkDjangoSettings',
+ ],
+ 'APP_ENV' => [
+ 'problematic_values' => ['production', 'prod'],
+ 'affects' => 'Laravel/Symfony',
+ 'issue' => 'May affect dependency installation and build optimizations',
+ 'recommendation' => 'Consider using "local" or "development" for build',
+ ],
+ 'ASPNETCORE_ENVIRONMENT' => [
+ 'problematic_values' => ['Production'],
+ 'affects' => '.NET/ASP.NET Core',
+ 'issue' => 'May affect build-time configurations and optimizations',
+ 'recommendation' => 'Usually safe, but verify build requirements',
+ ],
+ 'CI' => [
+ 'problematic_values' => ['true', '1', 'yes'],
+ 'affects' => 'Various tools',
+ 'issue' => 'Changes behavior in many tools (disables interactivity, changes caching)',
+ 'recommendation' => 'Usually beneficial for builds, but be aware of behavior changes',
+ ],
+ ];
+ }
+
+ /**
+ * Analyze an environment variable for potential build issues.
+ * Always returns a warning if the key is in our list, regardless of value.
+ */
+ public static function analyzeBuildVariable(string $key, string $value): ?array
+ {
+ $problematicVars = self::getProblematicBuildVariables();
+
+ // Direct key match
+ if (isset($problematicVars[$key])) {
+ $config = $problematicVars[$key];
+
+ // Check if it has a custom check function
+ if (isset($config['check_function'])) {
+ $method = $config['check_function'];
+ if (method_exists(self::class, $method)) {
+ return self::$method($key, $value, $config);
+ }
+ }
+
+ // Always return warning for known problematic variables
+ return [
+ 'variable' => $key,
+ 'value' => $value,
+ 'affects' => $config['affects'],
+ 'issue' => $config['issue'],
+ 'recommendation' => $config['recommendation'],
+ ];
+ }
+
+ return null;
+ }
+
+ /**
+ * Analyze multiple environment variables for potential build issues.
+ */
+ public static function analyzeBuildVariables(array $variables): array
+ {
+ $warnings = [];
+
+ foreach ($variables as $key => $value) {
+ $warning = self::analyzeBuildVariable($key, $value);
+ if ($warning) {
+ $warnings[] = $warning;
+ }
+ }
+
+ return $warnings;
+ }
+
+ /**
+ * Custom check for Django settings module.
+ */
+ protected static function checkDjangoSettings(string $key, string $value, array $config): ?array
+ {
+ // Always return warning for DJANGO_SETTINGS_MODULE when it's set as build-time
+ return [
+ 'variable' => $key,
+ 'value' => $value,
+ 'affects' => $config['affects'],
+ 'issue' => $config['issue'],
+ 'recommendation' => $config['recommendation'],
+ ];
+ }
+
+ /**
+ * Generate a formatted warning message for deployment logs.
+ */
+ public static function formatBuildWarning(array $warning): array
+ {
+ $messages = [
+ "⚠️ Build-time environment variable warning: {$warning['variable']}={$warning['value']}",
+ " Affects: {$warning['affects']}",
+ " Issue: {$warning['issue']}",
+ " Recommendation: {$warning['recommendation']}",
+ ];
+
+ return $messages;
+ }
+
+ /**
+ * Check if a variable should show a warning in the UI.
+ */
+ public static function shouldShowBuildWarning(string $key): bool
+ {
+ return isset(self::getProblematicBuildVariables()[$key]);
+ }
+
+ /**
+ * Get UI warning message for a specific variable.
+ */
+ public static function getUIWarningMessage(string $key): ?string
+ {
+ $problematicVars = self::getProblematicBuildVariables();
+
+ if (! isset($problematicVars[$key])) {
+ return null;
+ }
+
+ $config = $problematicVars[$key];
+ $problematicValuesStr = implode(', ', $config['problematic_values']);
+
+ return "Setting {$key} to {$problematicValuesStr} as a build-time variable may cause issues. {$config['issue']} Consider: {$config['recommendation']}";
+ }
+
+ /**
+ * Get problematic variables configuration for frontend use.
+ */
+ public static function getProblematicVariablesForFrontend(): array
+ {
+ $vars = self::getProblematicBuildVariables();
+ $result = [];
+
+ foreach ($vars as $key => $config) {
+ // Skip the check_function as it's PHP-specific
+ $result[$key] = [
+ 'problematic_values' => $config['problematic_values'],
+ 'affects' => $config['affects'],
+ 'issue' => $config['issue'],
+ 'recommendation' => $config['recommendation'],
+ ];
+ }
+
+ return $result;
+ }
+}
diff --git a/resources/views/components/environment-variable-warning.blade.php b/resources/views/components/environment-variable-warning.blade.php
new file mode 100644
index 000000000..ab7cab555
--- /dev/null
+++ b/resources/views/components/environment-variable-warning.blade.php
@@ -0,0 +1,32 @@
+@props(['problematicVariables' => []])
+
+
+
+
diff --git a/resources/views/livewire/project/shared/environment-variable/add.blade.php b/resources/views/livewire/project/shared/environment-variable/add.blade.php
index 104cb8003..2978e2b35 100644
--- a/resources/views/livewire/project/shared/environment-variable/add.blade.php
+++ b/resources/views/livewire/project/shared/environment-variable/add.blade.php
@@ -3,11 +3,15 @@
+
@if (!$shared || $isNixpacks)
-
+
+
+
@if ($isDisabled)
Update