20

We're starting to adopt Symfony 2 for projects here at work, which is great, but there's a challenge I'm working to solve that I've almost got, but not quite.

Symfony treats the concept of an environment as a separate runtime on a single server. This is great because you can switch between runtimes with different front controllers (web) or using the env switch (cli) at a whim.

However, our code is deployed across many servers as part of the development process. Everybody has a local VM, then code propagates up through Integration, QA, Staging, and finally Production.

So, our concept of an environment is server (virtual or physical). Here are the goals with this custom configuration

  1. Maintain Symfony's ootb functionality in respect to runtime environment switching
  2. Allow for public (i.e., developer controlled) configuration per-server
  3. Maintain private (i.e., sysad controlled) configuration per-server
  4. Will work for both web and cli

This means we can't just 100% rely on parameters.ini or any statically-named file, for that matter, since the developer will need control over configuration for each server plus all this files will be living next to eachother in git.

So, what I'd like to do is this. Add a new value to parameters.ini that sets the server environment. Something like this

app/config/parameters.ini

[parameters]
    server="int"

And then, in the kernel, load an additional configuration file based on that value. For example, I'd love for this to work but it doesn't (since the container doesn't yet exist at this step)

app/AppKernel.php

public function registerContainerConfiguration(LoaderInterface $loader)
{
  $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');

  // Per-server config
  $server = $this->getContainer()->getParameter( 'server' );        
  if ( $server )
  {
    $loader->load(__DIR__.'/config/server/'.$server.'.yml');
  }
}

This would enable the usage of a file like app/config/server/int.yml that the developer can use to control non-private (i.e., not parameters.ini) configuration values.

Thanks for reading, and let me know if anything is confusing.

EDIT

For clarification, things I can't use or rely on

  • *nix environment variables from the user's profile or via export. Why? Integration, QA, and Staging might all be on the same box
  • Anything in the vhost config (won't work for cli)
  • A statically-named file (i.e., something just named server.ini won't work)
4
  • Why do you think you need to use the Symfony2 environment to handle your server environments? Commented Apr 4, 2012 at 15:39
  • I'm not, per-se. I'm just trying to figure out the best way to load per-server configuration that will still be under control of the developers. Commented Apr 4, 2012 at 15:44
  • You still can parse the parameters.ini using parse_ini_file method. Although I didn't understand your problem clearly. Are you saying that each server config file will have different routing/security configuration? Commented Apr 4, 2012 at 19:01
  • You can read my solution below. It's a hard scenario to describe, hopefully the solution makes it more clear. Commented Apr 4, 2012 at 21:15

1 Answer 1

29

Ok, I finally figured out what to do for this. Really just required a basic modification to the AppKernel

app/AppKernel.php

public function registerContainerConfiguration(LoaderInterface $loader)
{

  // Symfony environment config
  $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');

  // Load server config, if it exists
  $parameters = parse_ini_file( __DIR__.'/config/parameters.ini', true );
  if ( $parameters && isset( $parameters['parameters']['server.env'] ) )
  {
    $serverConfig = __DIR__.'/config/server/'.$parameters['parameters']['server.env'].'.yml';
    if ( file_exists( $serverConfig ) )
    {
      $loader->load( $serverConfig );
    } else {
      error_log( 'Server config defined, but no config file found. Looked for ' . $serverConfig );
    }
  }
}

app/config/parameters.ini

[parameters]
    # ...
    server.env="int"
    server.title="Integration"
    server.name="Int 1"

And now I can just create %server.env%.yml files in app/config/server/ as needed.

Thanks to those that read this - I was originally thinking of something much more complicated which made this simple solution invisible for a while ;)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.