Setting Bolt Configuration Per Environment - php

The Bolt documentation mentions setting up configuration files for each environment, but doesn't explain how to make it happen.
When you have multiple environments for the same site, like development, staging, or production, you’ll want parts of the config to be the same, and some different per environment. You’ll probably have different database info and debug settings. This can be accomplished by splitting the config.yml file. Put all settings you share over all environments in the default config.yml, you can commit this in your version control system if wanted. Every setting which is different per environment, or which you do not want in version control (like database info), you put in config_local.yml. First config.yml is loaded and then config_local.yml, so that config_local.yml can override any setting in config.yml.
Of course I have no problem creating an additional config file, but how do I tell Bolt which environment it's running in and which file it ought to load?

Turns out Bolt is completely unaware of its environment. It always loads config.yml followed by config_local.yml, regardless of domain name.
From Config.php, starting at line 226:
protected function parseGeneral()
{
// Read the config and merge it. (note: We use temp variables to prevent
// "Only variables should be passed by reference")
$tempconfig = $this->parseConfigYaml('config.yml');
$tempconfiglocal = $this->parseConfigYaml('config_local.yml');
$general = Arr::mergeRecursiveDistinct($tempconfig, $tempconfiglocal);
The solution to my problem is to never allow config_local.yml to get deployed.

The config_local.yml file is intended for development use so that you can override configuration setting that might be committed to your VCS in production use.

Related

symfony server:start always taking prod configuration

I have a weird issue with Symfony, in my local environment when I run symfony server:start it's taking production configuration not dev configuration.
I have two index files in the public folder index.php and index_dev.php. I also added a .env.local with APP_ENV=dev
Also, I tried to set environment variables as the following.
export SYMFONY_ENV=dev
But index.php is always loaded, and not index_dev.php as I expected.
How I can fix this?
It seems you are copying the app_dev.php pattern, which is how it used to be in olden times (up to Symfony 3).
Fortunately, that's no longer how things are done. Since Symfony 4, you should have a single front-controller.
All requests should go through the same entry script (index.php, generally), and there you can implement whatever logic you need taking into account the different environments.
The default index.php file already has some logic to account for the APP_DEBUG environment variable being set, you could always modify this file to add other behaviour depending on the environment.

Apache2 mod_php in virtual machine shared folder code using non existent file

I tried to setup a development environment where my server environment is emulated by virtual machine running centos 6.3 and development is done from host OS. The application code (codeigniter app) is in a shared folder mounted to /home/foo/Desktop/code/app and I have created a virtual host in apache to serve this application.
On the development side, git is used as the VCS .
The problem is that when loading a helper two files are being included. Eg, I have a helper in application/helper named my_date_helper. It has two functions. I autoload this helper.
When running this application php throws this error
Fatal error: Cannot redeclare time12to24() (previously declared in /home/mlakhara/code/cosys/application/helpers/my_date_helper.php:9) in /home/mlakhara/code/cosys/application/helpers/MY_date_helper.php on line 11
When I comment the function, it says the functions are undefined.
Also the time related functions throw a warning telling me to set a timezone which I have already in the php.ini file using date.timezone option.
I assumed that these two files can be same included twice with different names, but the line numbers suggest something else.. (function is declared at different lines).
The application functions correctly when served from normal folder (non shared). I removed git from the vn and tried but it did not make any difference.
What can be the problem ?
---------------EDIT -----------------------
Taking hints from Magnus Eriksson's answer, I found that I was autoloading these 'extended' helpers instead of loading the actual path and date helpers. This lead to getting two copies of the same function. However the problem with timezone setting still persists.
As a corrective measure I added the time value to my .htaccess file as well. However is there any better way to do it.
Try removing "my_" in the filename. CodeIgniter uses "MY_" to extend the core and might test with both lower and upper case and thus loading the same file twice.
Either way, as Rob W pointed out, always wrap your helper functions in if (!function_exists()) {}
About the timezone problem: Since I haven't seen your php.ini or your setup, I can't say why it isn't working.
One solution should be to add date_default_timezone_set('UTC'); (or what timezone you want) first thing in index.php.
Since I don't always have access to modify php.ini on clients production servers, I usually add that in.
You are defining the function twice. When including the files, try using require_once('path/to/file.php') instead of include or require. Otherwise, in the source file, you can do:
if(!function_exists("time12to24")) {
function time12to24() [...]
}

What is wrong with having a dynamic configuration file in PHP?

I have recently taken to converting my websites files into ones that work on any path. I am working on using Virtual Hosts to be able to maintain the same .htaccess file as on the main production server. My initialize file that includes all my models is written dynamically to find out the exact system file path and update the website accordingly so I can upload the whole website anywhere.
The trouble lies in the config file. Depending on whether I am on dev or on prod, I connect to a differert database. Therefore I have a small check first to see if I am running a local server. I do this by storing my naming conventions for my dev in an array and by looping through the array to see if the HTTP_HOST matches a value.
Example:
$dev_names = array('localhost','.dev');
However, when I mentioned this on Chat the other day, a respected user told me that he never does this. Instead he has 2 config files and includes the right one at the right time? I didn't get though what was wrong with my approach?
Can you point out to me the flaws in my plan to help me understand the experts?
(PS. For a bonus you can give me a quick run down on how a bootstrap works, heard that word being thrown around, not sure if it is written in PHP or whatever.)
I dont see anything wrong with your approach, and I cannot think of a good reason not to do it.
Personally I do this in my php file;
if ($_SERVER['SERVER_NAME'] == 'localhost')
{
define('ENVIRONMENT', 'development');
}
else
{
define('ENVIRONMENT', 'production');
}
And then all my configs hang off that. Works extremely well - means I literally have zero config changes when moving between Dev & production
I suspect what he was getting at is that your attempt to make your site portable isn't in fact all that portable. If you move it to a new server you'll have to edit your configuration file.
Specifically this becomes an issue when you're checking the config file into some sort of version control system and will be affecting someone else.
Ideally, you'll use something like this:
<?php // global config file which is checked into VCS
$SETTING = "FOO";
#include "config/local_settings.php"; // overrides go here
?>
You put all your local setting overrides in the local file, and don't commit it to the VCS. It's perfectly common to commit something like local_settings_example.php though, to give other users a heads-up as to what they need to customise. You can fill it with commented examples if you're feeling generous.
I can only throw in my 2 cents on a setup I prefer. Mainly to avoid undesired version control overwrites or conflicts. To my point of view, it is the server that should decide if it's a production or development server, not a variable in a script that should be changed. An approach like the example below make it even possible to set an environment for an individual on a complete different development setup.
Starting by setting the variable
$_SERVER['SERVER_ADMIN'];
to check for production or development environments. Locally to your own name with a dummy domain like #dev.elop.loc (e.g. dbf#dev.elop.loc) that would never exist for real. A function like so
// environment development check
function __env_dev($check) {
return substr($_SERVER['SERVER_ADMIN'], -(strlen($check))) === $check;
}
// false = production
// true = development
__env_dev("#dev.elop.loc");
can determine the environment. To my experience, production servers always have a SERVER_ADMIN variable set (if not, they really should, even if it has to be the default you#example.com) to a real address, avoiding default you#example.com. If the support for the live server is in your own service/maintenance, it's not a big deal changing it to a real address to distinguish it from a development server ;)

How can I use Git with different database configurations between developers?

I am developing an application in Code Igniter with a friend. Because both of us have different database logins on our machines, we have different "config/database.php" files.
How can I tell Git that both of us have different database configurations? Right now, we are getting merge conflicts every time we pull because "config/database.php" differs for us.
I usually rename the /application/config/database.php file to /application/config/database.default.php (versioned) and add the original path to the .gitignore file. Then, each developer copies the default (unversioned file) back to the original path and edits per their local settings.
This becomes an extra step in the server setup process, but it saves the grief you mention.
Have a single file that selects config based on an environmental variable. Set that variable in your server's config.
<?php
if (getenv('WHOS_CONFIG') == 'mine') { … } else { … }
and in server config (which you wouldn't verison, otherwise same problem arises again :)
e.g. for Apache:
<VirtualHost *>
SetEnv WHOS_CONFIG mine
…
Alternatively, have a common database.php config file that includes database.local.php file that is not versioned. The latter would override variables you need.
Two options are:
Don't version control this file anymore (I leave git-command to your research)
Use the .gitignore file
As result you'll have file on old place, butit will not interfere with "another" file anymore
We usually put database configuration files in the .gitignore file to avoid these issues. It's a good idea anyway not to put these config files with their user/passwords in git.
We'll frequently keep a config/database.yml.template file (we're using rails) as the basis for folks to copy to config/database.yml and then edit to their local machine. The database.yml filename is put in the .gitignore file (which is shared under version control).
Basics on gitignore can be seen here.
Additional info, including pitfalls to avoid at: Ignore files that have already been committed to a Git repository

Can I configure environment specific content?

In the same way that you can generate specific content based on browser type is there a way to generate specific content based on the server running PHP without reference to the server or site name?
For example, a way for PHP to automatically detect the environment it was in and configure things like DB connections, ini_set for errors etc. depending if it was a development, ITS, UAT or production environment.
The 2 ways I thought of were to recognise an HTTP header indicating development and QA environments or to have custom properties in php.ini.
I have woken up slightly and found out the php function to read the http headers but php overrides anything I set in the web server and I do not know if they can be set in php.ini at all.
I have no idea if it is possible to add custom values to php.ini but I had a test and ini_get would not find it (I had restarted the web server after changing php.ini of course).
you can specify an environment variable in apache (conf, vhost, .htaccess or as an httpd daem) and then acces it via the ˆ$_ENVˆsuperglobal
I use the following to load different settings for different servers:
switch ($_SERVER['SERVER_NAME']) {
case 'web-host': case '10.0.0.208':
# Set DB Settings
case 'mydomain.com': default:
# Live server settings
}
Not had a problem with it so far
$_ENV / http://www.php.net/manual/en/reserved.variables.environment.php
Using FastCGI on IIS you can set Environment variables. They do not seem to be available to $_ENV but can be retrieved with getenv("varname").
To configure FastCGI environment variables in IIS 5 or 6 you need to edit:
C:\%systemdrive%\system32\inetsrv\fcgiext.ini
For example:
[Types]
php=d:\Dev\PHP\php-cgi.exe
php:1=PHP Site 1
*=Wildcard Mapping
[d:\Dev\PHP\php-cgi.exe]
QueueLength=999
MaxInstances=20
InstanceMaxRequests=500
[PHP Site 1]
ExePath=d:\Dev\PHP\php-cgi.exe
EnvironmentVars=PHPRC:d:\Dev\PHP\,SiteType:Developer
In this instance it is IIS 5 so there is only one site and the site ID is 1 as indicated in line 2 of [Types].
On IIS 6 you may have multiple sites and the following link tells you how to find the Site ID: http://weblogs.asp.net/owscott/archive/2005/07/29/how-to-find-the-siteid-in-iis5-and-iis6.aspx.
IIS 7 can be configured via the UI apparently once the Administration Pack for IIS 7 has been installed.
Another alternative that hasn't been mentioned yet would be to create a server-specific (but with the same name) configuration file that would be included in the beginning of your site script. In that server-specific config file you could set configuration variables as constants. That way, if there was a 'generic' configuration file loaded later, its values could be overridden in the server-specific configuration file as constants can't be redefined. You would want to either exclude the server-specific configuration file name from the synchronizations, or keep it in a path outside of the main content so that it is not accidentally overwritten.
For this purpose you can even configure Constant Arrays with help of Constant Array 2 class.
When server-specific configuration files are used you don't have to worry about the current SERVER_NAME -- this makes it easier for you to define the intended environment regardless of the current system name which could be handy also for QA purposes.

Categories