laravel enviroment when on command line different to in browser - amazon-web-services

I have deployed my laravel app to an elastic beanstalk enviroment. This app detects its environment with this piece of code in bootstrap/start.php
$env = $app->detectEnvironment(function () {
return getenv('APP_ENV') ?: 'local';
});
When elastic beanstalk starts it runs its configuration files which I have set up to detect if a parameter is set. in this case I have set this parameter to development and the configuration files then set enviroment variables based on this namely
APP_ENV = development
DB_HOST = rds dev endpoint
DB_NAME = rds dev db name
DB_USERNAME = dev username
DB_PASSWORD = devdb pass
When I visit the app in the browser it is working as intended and it is correctly connecting to the dev db.
When I ssh into the server and try to run
php artisan migrate
I get a pdo exception no such file or directory
when I run
php artisan env
local is returned even though the environment variable APP_ENV is defined. I am doubly sure that this variable is defined because when laravel errors in the browser I can see the variable with the value development in the server/request data along with the other environment variables that are created on environment launch
what am I missing?
edited to include personalised solution based on antonios answer
.environment
<?php
if (getenv('PARAM1') === false) {
return false;
} else {
switch (getenv('PARAM1')) {
case 'development':
return array(
'APP_ENV' => 'development',
'DB_HOST' => '***',
'DB_NAME' => '***',
'DB_USERNAME' => '***',
'DB_PASSWORD' => '***',
);
break;
case 'staging':
return array(
'APP_ENV' => 'staging',
'DB_HOST' => '***',
'DB_NAME' => '***',
'DB_USERNAME' => '***',
'DB_PASSWORD' => '***',
);
break;
case 'production':
return array(
'APP_ENV' => 'production',
'DB_HOST' => '***',
'DB_NAME' => '***',
'DB_USERNAME' => '***',
'DB_PASSWORD' => '***',
);
break;
}
}
start.php
$env = require __DIR__.'/../.environment';
if ($env !== false) {
foreach ($env as $key => $value) {
putenv(sprintf('%s=%s', $key, $value));
}
}
$env = $app->detectEnvironment(function () {
return getenv('APP_ENV') ?: 'local';
});

When you run
php artisan migrate
php runs under a different user, not your web server, so you need to:
php artisan migrate --env=development
EDIT
Having trouble with cli and web is one of the reasons why I don't use those web servers env vars. This is how I do my environments:
Create a .environment file in the root of your application and define your environment:
<?php
return array(
'APP_ENV' => 'development',
'POSTGRESQL.HOST' => 'localhost',
'POSTGRESQL.DATABASE_NAME' => 'laraveldatabase',
'POSTGRESQL.DATABASE_USER' => 'laraveluser',
'POSTGRESQL.DATABASE_PASSWORD' => '!Bassw0rT',
);
Add it to your .gitignore application file, so you don't risk having your passwords sent to Github.
Right before $app->detectEnvironment, load the .environment file to PHP environment:
foreach(require __DIR__.'/../.environment' as $key => $value)
{
putenv(sprintf('%s=%s', $key, $value));
}
And then you just have to use it:
$env = $app->detectEnvironment(function () {
return getenv('APP_ENV');
});
It will work everywhere:
<?php
return array(
'connections' => array(
'postgresql' => array(
'driver' => 'pgsql',
'host' => getenv('POSTGRESQL.HOST'),
'database' => getenv('POSTGRESQL.DATABASE_NAME'),
'username' => getenv('POSTGRESQL.DATABASE_USER'),
'password' => getenv('POSTGRESQL.DATABASE_PASSWORD'),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
),
),
);
Note that I don't do
return getenv('APP_ENV') ?: 'local';
Because I want it to fail on every server I deploy my app to.

Related

How to connect to an RDS database from Yii2?

I have deployed a Yii2 based app onto AWS Elastic Beanstalk, also I have created the RDS instance with a database (it already has tables) on Elastic Beanstalk. However I received this error: "SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known"
All the files are uploaded correctly to the AWS instance.
The file /common/config/main-local.php has:
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=',
'dsn' => 'mysql:host=RDS_HOSTNAME:RDS_PORT;dbname=RDS_DB_NAME',
'username' => 'RDS_USERNAME',
'password' => 'RDS_PASSWORD',
'charset' => 'utf8',
],
What could be wrong? Thanks.
I am guessing that you want pass db information through environment variables. You may want to try to revise the code as below.
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=',
'dsn' => 'mysql:host='.$_SERVER['RDS_HOSTNAME'].':'.$_SERVER['RDS_PORT'].';dbname='.$_SERVER['RDS_DB_NAME'],
'username' => $_SERVER['RDS_USERNAME'],
'password' => $_SERVER['RDS_PASSWORD'],
'charset' => 'utf8',
],
You can reference http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/AWSHowTo.RDS.html#rds-external-ec2classic in To configure environment properties section to configure your environment variables. Hope this works.
You have 2 times your 'dsn' line and maybe the first one survives, so changing your config to this should work:
'components' => [
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=RDS_HOSTNAME:RDS_PORT;dbname=RDS_DB_NAME',
'username' => 'RDS_USERNAME',
'password' => 'RDS_PASSWORD',
'charset' => 'utf8',
],
(In addition I hope you are aware that you have to change RDS_* parameters :D)

Silex DoctrineServiceProvider not connecting

I'am building application on Silex, and I'am having some problems on very basic stuff. I used example from official documentation for using doctrine service provider, but no matter what i do $app[ 'db' ]->isConnected() returns false. Here is the code
$app = new Application();
$app->register(new DoctrineServiceProvider(), array(
'dbs.options' => array (
'mysql' => array(
'driver' => 'pdo_mysql',
'host' => 'localhost',
'dbname' => 'sevenbet',
'user' => 'root',
'password' => '',
'charset' => 'utf8',
)
),
));
Don't use multi dimension array, if you have one db config to provide, just use :
$app['db.options'] = array (
'driver' => 'pdo_mysql',
'host' => 'localhost',
'dbname' => 'mydb',
'user' => 'root',
'password' => 'root',
'charset' => 'utf8'
);

Unit-testing with CakePhP and PHPUnit

I`m trying to do unit-testing with CakePhP 2.3 and PHPUnit 2.7. I want to test the index function in my customer’s controller.
In my controller I have:
public function index() {
$this->Customer->recursive = -1;
$data = $this->paginate('Customer', array( 'Customer.status'=>'active'));
$this->set('customers', $data);
}
I tried to follow the examples in book.cakephp.org, so I created Fixture class in which I`m importing the Customer schema and all the records.
class CustomerFixture extends CakeTestFixture{
public $import = array('model' => 'Customer', 'records' => true);
}
And finally my test class looks like this:
class CustomersControllerTest extends ControllerTestCase {
public $fixtures = array('app.customer');
public function testIndex() {
$result = $this->testAction('/customers/index');
debug($result);
}
}
When I run my test I have the following error:
Database Error
Error: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '8' for key 'PRIMARY'
Do you have any ideas what can be the problem?
In your database.php in app/Config folder you have to add a $test variable.
For example
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => true,
'host' => 'localhost',
'port' => 3306,
'login' => 'root',
'password' => 'xxxx',
'database' => 'mydatabase',
'encoding' => 'utf8'
);
public $test = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'port' => 3306,
'login' => 'root',
'password' => 'xxxx',
'database' => 'mydatabase_test',
'encoding' => 'utf8'
);
}
Then your unit testing will use the mydatabase_test for testing your code. Because now it uses the default database.

get doctrine db config in zf2

I want to use doctrine db config to access to DBAL layer in doctrine, I have the following configuration in my doctrine db file config:
database.local.php
return array(
'doctrine' => array(
'connection' => array(
'orm_default' => array(
'driverClass' => 'Doctrine\DBAL\Driver\PDOPgSql\Driver',
'params' => array(
'host' => 'localhost',
'port' => '5432',
'user' => 'postgres',
'password' => '123456',
'dbname' => 'test'
)
)
)
)
);
and in my controller
IndexController.php
use Doctrine\DBAL\DriverManager;
public function testAction(){
$conn = DriverManager::getConnection($params, $config);
}
I want to use db config above in the getConnection function, is this possible?
If you've a db configuration in your local.php, so why don't you access it through the EntityManager ? Just like this :
public function testAction(){
$em = ->getServiceLocator()
->get('Doctrine\ORM\EntityManager');
$conn = $em->getConnection();
}
If you want to get it through the DriverManager :
$config = new \Doctrine\DBAL\Configuration();
$connectionParams = array(
'host' => 'localhost',
'port' => '5432',
'user' => 'postgres',
'password' => '123456',
'dbname' => 'test'
'driver' => 'pdo_pgsql',
);
$conn = DriverManager::getConnection($connectionParams, $config);
EDIT :
You can also get directly an instance of Doctrine\DBAL\Connection using the Registered Service names provided by Doctrine with your actual db configuration :
$conn = $this->getServiceLocator()->get('doctrine.connection.orm_default');
As the DriverManager::getConnection() method, this will return a Doctrine\DBAL\Connection which wraps the underlying driver connection.
Sure.
First of all you should use ServiceLocator
ServiceLocator are auto injected into classes that implements \Zend\ServiceManager\ServiceLocatorAwareInterface
AbstractActionController, of your zf2 controllers already implements this interface.
To use into a class (model by example) you should declare implements and two methods that are designed by interface, setServiceLocator and getServiceLocator.
<?php
namespace Security\Repository;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\ServiceManager\ServiceLocatorAwareInterface;
class Repository implements ServiceLocatorAwareInterface
{
protected $serviceLocator;
public function setServiceLocator(ServiceLocatorInterface $serviceLocator)
{
$this->serviceLocator = $serviceLocator;
}
public function getServiceLocator()
{
return $this->serviceLocator;
}
}
Using ServiceLocator are easy to do anything on ZF2. Try To understand how it works to get the fully power of zf2.
$configArray = $this->getServiceLocator()->get('config');
$config = new \Doctrine\DBAL\Configuration();
$connectionParams = $configArray['doctrine']['connection']['orm_default']['params']
$conn = DriverManager::getConnection($connectionParams, $config);

What credentials to use when configuring mysql db and memcache for Laravel 4 with EC2 on AWS

I have my Laravel 4 project up on my EC2 server in AWS, and the final step is to connect my db and memcache.
My question is what host, port and weight do I use for memcache in Laravel. I assume that the "host" is just the public DNS key: ec2-**-***-***-***.**-****-*.compute.amazonaws.com. But what do I use for the port and weight?
'memcached' => array(
array('host' => 'ec2-**-***-***-***.**-****-*.compute.amazonaws.com', 'port' => ?, 'weight' => ?),
),
but I am not sure what to use for port and weight. Is the port just 3306?
Also, for the mysql db. I was able to connect with my db using sql pro by ssh host. And I created a new db there "cs". What credentials would I use for this? Would it look like the below?:
'mysql' => array(
'driver' => 'mysql',
'host' => 'ec2-**-***-***-***.**-****-*.compute.amazonaws.com',
'database' => 'cs',
'username' => '****',
'password' => '************',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
'default' => array(
'host' => 'ec2-**-***-***-***.**-****-*.compute.amazonaws.com',
'port' => ?,
'database' => 0,
),
Again, what port to use?
Finally, how do I update the MySQL username and password on my server so they are not just root. Thank you for all of your help!
Unless your database and/or Memcached are on a separate instance, you should use localhost as the hostname for both.
The MySQL port should be 3306 by default unless you manually changed it in your MySQL configuration.
The Memcache port should be 11211 by default and weight should be 100 (default) and doesn't matter unless you use multiple cache servers.