Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

rjv's avatar
Level 7

Server provisioned with Forge not detecting environment properly

Hello everyone. I posted this over at the Laravel.io forums and got little response.. seeing if I have better luck here.

I've been struggling with this particular issue for a few hours. I created a basic server on DigitalOcean through Laravel Forge. I created a site on the server that has an instance of Laravel 4.2. To detect my environment, I'm using a closure (taken from this article). Here is my exact code:

// start.php
$env = $app->detectEnvironment(function() {
    if (getenv('APP_NAME_ENV')) {
        return getenv('APP_NAME_ENV');
    } else {
        return 'local';
    }
});

Using Forge, I updated my environment variables on my site and set "APP_NAME_ENV" to be "staging". I did not fill in anything for the "environment" field.

Next, I SSH'd into my server and navigated to my site's root directory. First, I tried just executing "php artisan env", which returned "local". Next, I used artisan tinker to execute "App::environment();", which again turned up "local".

I restarted both nginx and the entire server, tried the above steps again and it still comes back with "local". Based on the environment variable that I set, I expect to see "staging".

I don't think I've done anything out of the ordinary here.. I've read up on this issue and others seem to have success doing the same exact thing I'm doing. Can anyone offer any insight or have clues about where I can investigate next? I'd really prefer to use the closure technique rather than explicitly identify my hostnames for environment detection.

Thanks!

0 likes
12 replies
RayRutjes's avatar

When using artisan, you can specify the environment like so:

php artisan migrate --env=staging

In forge, you can set the environement variables directly from the interface. This will: - Make the variables available in cli mode by creating a .env..php file - Set the corresponding environement variables in the nginx config

You can also update the .env* files directly by sshing the server and manually adjusting the nginx server config. In that case, you can no more rely on the GUI for handling your variables.

Finally, note that you can adjust your deployment script. Do not forget to add the environement variables there when needed: php artisan migrate --env=staging

I'd be glad to help you more, I have been struggling with this quite a bit when I started trying out Forge.

rjv's avatar
Level 7

@rem I think my main issue is that no matter what I set my "APP_NAME_ENV" environment variable to (through Forge's interface), my environment always comes out to be "local". The only way I have been able to use environment variables in my app is if I upload .env.local.php to my server.

Any thoughts as to why my closure always returns "local"?

henrique's avatar

I'm not sure how Forge sets APP_NAME_ENV, but last time I played with environment variables, it was only set for apache (or in the case of forge, nginx), so accessing from a browser would work but not from terminal.

olyckne's avatar

Yeah, for me the environment variable works in the browser but not when using artisan. I need to use ---env=production on my deployment scripts and cron jobs so Laravel knows to read the correct .env.php file.

Chukky Nze's avatar

Given that Laravel lets you set environment specific variables with .env.*.php files, and that only one of these files 'should' exist on a particular server at a time, I've found success by using these files as a way to 'identify' the environment:

@dannielssousa Thanks

$env    =   $app->detectEnvironment(function()
        {
            $allowedEnvironments    =   [
                'homestead',
                'development',
                'staging',
                'production',
            ];

            if(in_array(getenv('APPLICATION_ENV'), $allowedEnvironments)){
                return getenv('APPLICATION_ENV');
            }

            foreach ($allowedEnvironments as $allowedEnvironment)
            {
                if (file_exists(__DIR__ . "/../.env." . $allowedEnvironment . ".php")){
                    return $allowedEnvironment;
                }
            }

            if(file_exists(__DIR__ . "/../.env.php")){
                return 'production';
            }

            throw new \Exception("Invalid environment, check configurations");
        });

This works for me on Homestead and Forge provisioning DigitalOcean Servers and takes care of those annoying "{"error":{"type":"ErrorException","message":"Undefined index:" errors.

As a note on Forge for the CLI to work you do have to set the environment variables yourself. This is easily done by following this tutorial: https://laracasts.com/series/server-management-with-forge/episodes/5

Valorin's avatar
Valorin
Best Answer
Level 4

@rjv, "I think my main issue is that no matter what I set my "APP_NAME_ENV" environment variable to (through Forge's interface), my environment always comes out to be "local"."

This is because Forge cannot set environmental variables for your command line session, only for nginx (http requests). The ways to get around this are:

  1. Set the default environment to be your forge environment, and manually specify it in other environments (updated).
  2. Use --env=staging in all of your artisan commands.
  3. Update your env detection closure to look for a file you know only exists on Forge, and return staging when it's found.

Make sense?

2 likes
rjv's avatar
Level 7

@Valorin, Thank you for the descriptive answer. It wasn't clear that the environment variables are handled differently based on the client.

Valorin's avatar

No worries :-)

Although I just realized that option #1 wont work with your custom env code. It should say: make the forge environment the default environment.

simplenotezy's avatar

I have been stuck now with this issue, and found a way to deal with the choice of environment. Now this works, hurray! But then.... This means I cannot run "php artisan migrate" either, because the database connections is ALSO stored in Envoirment Variables (from forge) like this http://laravel.io/bin/LN8Pl.. Now - what do I do? I

Chukky Nze's avatar

You CAN use "php artisan migrate". Just add --env=development (or whatever your environment name is). Actually, for my script above laravel is "forced" to determine the environment based on the existence of the .env file. I don't append --env to my artisan commands and they work just fine

danielsousa's avatar

@Chuckky you can improve with


$env = $app->detectEnvironment(function () { $allowedEnvironments = [ 'homestead', 'development', 'staging', 'production', ]; if (in_array(getenv('APPLICATION_ENV'), $allowedEnvironments)) { return getenv('APPLICATION_ENV'); } foreach ($allowedEnvironments as $allowedEnvironment) { if (file_exists(__DIR__ . "/../.env." . $allowedEnvironment . ".php")) { return $allowedEnvironment; } } if (file_exists(__DIR__ . "/../.env.php")) { return 'production'; } throw new \Exception("Invalid environment, check configurations"); });
1 like

Please or to participate in this conversation.