How to set up different environments on Laravel 4? - php

I am trying to set up multiple environments on a Laravel 4 app, and naturally different Databases depending on which environment we are on.
For my local machine, I set up a virtual host for "local.elders.dev"
Unfortunately, for some reason the following code is not working.
$env = $app->detectEnvironment(array(
'local' => array('http://local.elders.dev'),
));
Maybe I need to run an artisan command or something else. I feel I am close, but not quite there yet !
Thanks to all !

Another method is to use the name of the folder the project is in. This works in console and web. I found this to be the only reliable way if different environments are hosted on the same server.
$env = $app->detectEnvironment(array(
'staging' => strpos(getcwd(), '/staging')>-1,
'acceptance' => strpos(getcwd(), '/acceptance')>-1,
'production' => strpos(getcwd(), '/production')>-1,
));
A big advantage is that you can move staging to production by simply renaming or copying the project folder without changing files, db records or environment variables.

I know this is answered but for others looking for a solution...
My environment detection setting looks like this:
$env = $app->detectEnvironment(array(
// Development
// any machine name with the term "local" will use the local environment
'local' => array('*local*'),
// Stage
// any machine name with the term "stage" will use the stage environment
'stage' => array('*stage*')
// Production
// production is default, so we don't need to specify any detection
));
This is handy because it will work on any project as long as I use "local" for development (like "localhost", "localhost:8000", "my.app.local", etc.). Same goes for "stage". And production is default so anything without "local" or "stage" works for production.

Handling multiple environments on the same machine with Laravel 4x
What if you wanted to run multiple environments on the same machine with the same name- for example, a staging and production AND local environment?
There is a better solution for handling environments in Laravel 4x- and it can be done by adding a one liner to you vhosts file- or .htaccess:
Set local environment variable
In vhost or .htaccess add for your local installation, for staging, for example add:
SetEnv LARAVEL_ENV staging
and the same in your production .htaccess or vhost:
SetEnv LARAVEL_ENV production
Then the usual detectEnvironment() function in start.php.
$env = $app->detectEnvironment(function()
{
// Default to local if LARAVEL_ENV is not set
return getenv('LARAVEL_ENV') ?: 'local';
});
We didn't forget local... and that's the the cool part-- your installation will default to local if neither environment variable is found in vhost or .htaccess, as they would be found in the other installations.

OK ! I just solved the issue... The code was actually working ok ! The problem is that I was using
$_SERVER['DB1_HOST'] //for Pagodabox.
Of course this was not set on my local environment, which pretty much broke the app...
I fixed by simply doing :
isset($_SERVER['DB1_HOST']) ? $_SERVER['DB1_HOST'] : '';
Thanks to #jeroen and #theshiftexchange :)

Try replacing it with 'local.elders.dev', I'm not 100% sure but it's probably matching hostnames, not full paths.

Laravel 4 detects the environments through the machine names specified in the "bootstrap/start.php" file.
For example, in my case the config becomes:
$env = $app->detectEnvironment(array(
'local' => array('Victor.local', 'Victor-PC'),
));
This means that Laravel will use the 'local' environment settings for both machines: 'Victor.local' (a Mac) and 'Victor-PC' (Windows).
In order to know the current machine name, you can use the following PHP code:
<?php echo gethostname(); ?>
For each environment you can create a folder in app/config and replace the desired configuration files and properties.
Regards!

Related

Symfony4: Access DEV environment on production server

In Symfony3, when I want to browse the website in DEV environment on the "live" server, I just enter my ip address in /web/app_dev.php and open http://www.example.com/app_dev.php/ in the browser.
Since in Symfony4, the environment is now set in /.env, how can I see the DEV environment on the production machine?
EDIT: I'm looking for a solution that works in production, so applying any global changes (like e.g. setting APP_ENV=dev in /.env) is not an option.
You can change inside your .env file APP_ENV to dev like this:
APP_ENV=dev
If you set that variable symfony load the system into dev enviroment because inside Kernel.php there is this line that check that variable:
$kernel = new Kernel($_SERVER['APP_ENV'] ?? 'dev', $_SERVER['APP_DEBUG'] ?? false);
If you want to do it without change .env file you can for example set a variable in the Apache vhost or Nginx FastCgi configuration, based on the URL you are visiting from - such as APP_ENV=/home/user/app-name/dev.env or on a live server: APP_ENV=/etc/app-name.prod.env
So in this case you have many .env file but you can use rule based on url
At first this is a bad idea and that's why it wasn't possible by default to access app_dev.php on production server (symfony < 4). You're giving a lot of internal information to public and especially to attackers.
From symfony docs:
After you deploy to production, make sure that you cannot access the app_dev.php or config.php scripts (i.e. http://example.com/app_dev.php and http://example.com/config.php). If you can access these, be sure to remove the DEV section from the above configuration.
You should be able to debug most of the things from logs.
But if you really want to do it, you can just remove public/index.php and create public/app.php and public/app_dev.php like it was in symfony 3 and make it work with env variables. - https://github.com/symfony/symfony-standard/tree/3.4/web
EDIT: To be clear: you can just remove public/index.php, create public/app.php, public/app_dev.php (copies of index.php). And get inspiration from symfony 3 standard edition to adjust it to your needs.
EDIT2: As #Cerad mentioned it's a better idea to have index.php and index_dev.php file names (following Symfony4 decisions).

Missing the point: Laravel 5 environment setup

So, for my application I see 4 types of environments it can run under:
Local on my machine
Local on my VM where I am using Homestead
Staging
Production
Each environment differs in the database connectivity (type of DB, connectivity to the DB credentials, etc).
In my bootstrap/start.php I have set up this:
$env = $app->detectEnvironment(array(
'local' => array('localhost'),
'localStaging' => array('mylocalStage.dev'),
'staging' => array('myapp-stage.com'),
'production' => array('myapp.com'),
));
How do I enforce those settings? where do I set up that when I'm on 'local' I will use some local settings? Currently when I use
php artisan env
on my root application folder I get:
Current application environment: production
why isn't it picking up I'm 'local'?
After discussing the issue in the comments and in the chat, the conclusion was to use the new .ENV approach which have been introduced in laravel 5.
Which means, you should have an .env file in your root directory with the current environment's settings.
So for local env, your .env file would have different settings than your production's env .env file.
As default you should have a .env.example file, in case you don't have one - you can copy the default content from the git (.env.example#git).
Please notice that when you're updating (pushing) your local version to staging (for instance), that you don't overwrite the .env file. In order to prevent those kind of issues you can use git ignore (so it will skip that file).

Trying to Migrate in Development Mode

I'm trying to figure out how I can get my environment set to development mode inside my Laravel application.
bootstrap/start.php
$env = $app->detectEnvironment(array(
'development' => array('blog.app'),
'production' => array('')
));
Inside my routes file I have the following:
Route::get('/', function()
{
dd(App::environment());
});
When I go to blog.app it says its set to production and I'm not sure why. The purpose of figuring out why its giving me production instead of development is because I am attempt to run the command "php artisan migrate" and its giving me the following.
My-iMac:blog my$ php artisan migrate
**************************************
* Application In Production! *
**************************************
Do you really wish to run this command?
So I need help understanding why its still saying application is in production mode when I'm attempting to be in development mode.
Go inside your project directory. Then navigate to bootstrap/start.php.
Edit the local array specified in $app->detectEnvironment with your machine name.
Laravel will automatically check you machine name every time and know that it is a local environment and use the local configuration files instead. To use the local config files you can navigate to app/config/local and edit the files there. The files in app/config belong to the production environment. You can copy these files in the local folder and then edit them accordingly, for example you database configuration probably will differ on your local machine and the server.
You can simply edit the files in the config folders and Laravel will detect automatically the environment according to the array in the start.php and use the config files related to the machine on which you are working. You can also specify more environments and create their entries in the start.php file and then go and create a folder by the same name in the app/config folder and create config files for that environment in that folder.
Example: If you want to have two local environments you can edit you start.php file like so
$env = $app->detectEnvironment(array(
'local' => array('Machine1', 'Machine2'),.
'local2' => array('Machine3', 'Machine4'),
));
And then navigate to the app/config folder and create two folders like local and local2 and have separate files for each of them. Now the machines with names Machine1 and Machine2 will automatically use config files present in local folder and Machine3 and Machine4 will use config files in local2 folder. This way Laravel provides great flexibility in setting environments.
For more information check out the Environments and Configuration Episode on Laracasts.
You need to figure out your machine name. In order to do that, run this code anywhere:
echo gethostname();
exit;
More info about the function: http://php.net/manual/en/function.gethostname.php
It will output your machine name, then you need to paste it in the 'development' array.

Setup different public path in laravel 4 for testing environment

I have set up a test environment in start.php:
$env = $app->detectEnvironment(array(
'local' => array('http://localhost*', '*.dev'),
));
Now I want to define a different public path for local environment
production: 'public' => DIR.'/../../../www/',
local: 'public' => DIR.'/../../../www/local',
but the paths.php locates in bootstrap folder instead of app, so how can I set up a different public path?
you have access to the $env variable in your paths.php (since it just gets included from start.php). so you can build in a switch:
'public' => ($env == 'local') ? __DIR__.'/../public' : __DIR__ . '/some/where/else/public',
works for me in production.
You don't.
That's not how environments are supposed to work. Environments allow you to have different configuration values based on the environment your in. As an example, you might use the native session driver on your local environment, but on your production environment you want to use the redis driver.
The official documentation covers the configuration of environments. When you use environments it's strongly recommended (from a security point of view) to use the machine name rather then a URL.
Just had the same problem few days ago : I needed to change the public directory name from 'public' to 'www' for production, as it is on shared hosting and I can't change it.
I searched a way to configure that while sticking to the configuration files system.
Here's how I did it : created a new file /app/start/production.php, and put inside :
if ('production' === $app['env'])
{
$app->instance('path.public', str_replace('public', 'www', $app['path.public']));
}
That file (specific to your environment) is called during the bootstrap process, so this small hack shouldn't cause problems.
The call itself is done in /vendor/laravel/framework/src/Illuminate/Foundation/start.php on line 256.
Note: this has not yet been tested in production (deployment scheduled this week), but tested for the local environment
Hope it helps.

What is the right way to maintain a "version for the server" - with only config files changed, in Git?

I sometimes work with Codeigniter, and after I'm done developing on the local site, I need to migrate the files to the server. All the files in the /config/ folder need to be changed to match the Server settings. It's not right to make an entire commit for these changes, do I simply make Git ignore these files altogether, or is there a way to track these changes and apply them with Git at the right moment?
You could keep versioned:
two "value config files", with the right values for each environment
a template config file, with value placeholder in it (for instance, ##PORT_NUMBER##)
a script able to generate the actual config file depending on the current environment
a content filter driver which, on checkout, will trigger the script in order to generate the right config file.
Note: that supposes your template config file has a recognizable content (the filter doesn't have a name or path of the file). See "Git equivalent of subversion's $URL$ keyword expansion" for more on the limitation of git content filter driver).
It depends on Your needs. In my company we use other approach.
We've created several environments (where the asterix is internal project name):
devel - site runs on domain **.local.com*
test - site run on domain test.*.company.com
beta - beta.*.company.com
production - every other domain.
Based on the domain name we switch automatically configurations.
Basicly config file looks like:
<?php
return array(
'_env' => array(
'devel' => array(
// config for devel
),
'production' => array(
// config for production
)
)
);
?>
Some frameworks (AFAIR Zend) set the environment name in Virtual Host config (or .htaccess). You should look at: zend framework auto switch production staging test .. etc
Have You looked at CI documentation? There's a section about it.
Create two folders in the config folder. One is called development and the other is production. Now copy config.php, database.php etc to each of these folders. Now when you are on production server, CodeIgniter will first check the production folder for the files. If it is not there, then it uses the default file in the config folder. And if you are on development environment, CodeIgniter will first check the development folder.
If you want to keep any config file identical to the production and development environment, keep it in config folder.
If you want to set the environment then add the following code in .htaccess file:
#This code for Development Environment
SetEnv CI_ENV development
and
#This code for Production Environment
SetEnv CI_ENV production

Categories