After my last blog post I decided that it was time to deploy Gastropoda to Amazon Web Services - namely Elastic Beanstalk, which utilizes an EC2 instance (reserved) and an RDS DB instance.
I started last Saturday. I’ve just now gotten something running that seems on par with what I have on my vagrant box. I have decided to put together a post of random tips for myself so that I never have to go through this nightmare again the next time I have to set up a new Elastic Beanstalk app or environment.
I started off mostly following these very helpful Laravel deployment instructions. These set me off on the right track, but there were so many obstacles that I ran into that just following this wasn’t really enough.
So…notes.
Differences from instructions above
- The environment config file in the above ended up not working for me. The environment that was created with
eb start
was a t1.micro instance instead of the specified t2.micro. This led me to think that other settings probably weren’t taking either. I ended up creating an environment manually through the Elastic Beanstalk dashboard. - The
environmentVariables
config was also for some reason not being applied, specifically - not finding theDB_HOST
environment variable. I ended up creating a new set of configs for a development environment inapp/config
alongside the local config and set my db login information there. Thenbootstrap/start.php
I added the development environment to detect:
$env = $app->detectEnvironment(array(
'local' => array('homestead'),
'development' => array('hostnamehere'),
));
{:lang=“php”}
- To get the hostname, remote into the EC2 instance and run
hostname
- However, this wasn’t working consistently, so to be safe I also forced a specific environment in
.ebextensions/02artisan.config
:
container_commands:
01migrateSeed:
command: "php artisan migrate --env=development --force"
02seed:
command: "php artisan db:seed --force"
Migrating and Seeding Database
- I used Xethron’s Migrations Generator to generate a migration from my existing DB schema on the vagrant box. This was quick and painless.
- What wasn’t so painless was the migration’s inability to run foreign key commands. There were all kinds of foreign key dependency errors, so I removed all foreign key migrations because by this point I wanted to rip my hair out.
- I then created seeders for all of my template tables, which are:
- race_terrains
- snail_history_templates
- item_types
- item_templates
- item_nutrition
- recurring_events
- Seeder example:
class RaceTerrainTableSeeder extends Seeder {
public function run()
{
DB::table('race_terrains')->delete();
$statement = "
ALTER TABLE race_terrains AUTO_INCREMENT = 1;
";
DB::unprepared($statement);
DB::table('race_terrains')->insert(array(
array(
'name' => 'Plastic Tabletop',
'description' => 'A smooth, plastic tabletop - lightly misted with water'
)
)
);
}
}
{:lang=“php”}
The $statement
above is very important. Before I added this, the auto-incremeneted primary key would keep counting up from the previous batch each time I deployed a new version of the app. This broke everything, since I had code and other tables referring specifically to various IDs. This makes sure the IDs increment back from 1 each time the table is seeded.
- I started off using MySQLWorkbench, but am now using a trial version of Navicat MySQL to connect via SSH - much better
Cron job
- I had to set up a cron job for Dispatcher to run various events (like recurring store restocking and deliveries, race events, breeding events, etc). I ended up doing this in
.ebextensions/01composer.config
:
container_commands:
01optimize:
command: "/usr/bin/composer.phar dump-autoload --optimize"
02dispatcher:
command: "cat .ebextensions/dispatcherJob.txt > /etc/cron.d/dispatcherJob && chmod 644 /etc/cron.d/dispatcherJob"
leader_only: true
- dispatcherJob.txt looks like this. Remember that it requires exact path to php and artisan and must have a newline at the end:
* * * * * root /usr/bin/php /var/www/html/artisan scheduled:run > /dev/null
Logs and Storage
- To get logs from EC2 instance, use this example:
scp -i path/to/.pem ec2-user@public-ec2-instance-ip:/var/www/html/app/storage/logs/error.log .
- The chmod to the storage directory keeps getting reset with each deployment. Currently adding this command to
.ebextensions/01composer.config
undercontainer_commands
seems to have worked. I know, I shouldn’t use 777…will try to lower this as much as possible and see what happens.
03chmodStorage:
command: sudo chmod -R 777 /var/www/html/app/storage
More most likely to come…