Here’s what you do to set up an AWS Elastic Beanstalk instance and update it through GIT. So, you’ll need the correct access on your AWS account and here we’re going to use Elastic Beanstalk (EB), RDS, IAM, EB CLI, Github and GIT.

Setting up Laravel on Elastic Beanstalk

This setup is for an Ubuntu machine. Most of this comes from this url

  • Create a new private repository on Github (or wherever you want to store your GIT repo). It should be private because you will be adding your .env file.
  • Clone the repo on your local machine (in this case an Ubuntu Desktop).
  • In the directory, you’ve cloned the repo to you install a fresh version of Laravel. You may need to install it into another blank directory then copy the files across as the directory you want to install Laravel into isn’t empty.
  • Check that Laravel is working locally.
  • Once you have a working version of Laravel you can save the contents of the Laravel directory minus the vendor folder to a zip file using the command…
  • zip ../laravel-default.zip -r * .[^.]* -x "vendor/*"
  • Create a new EB instance and use the default application to begin with. Your EB url should now give you a holding page when you go to it in a browser.
  • Now to put your Laravel project onto the EB instance you click the “Upload and Deploy” button and select the “laravel-default.zip” you made previously.
  • Now, when you go to the EB url there may be an error, so instead put the “public” directory in the url, then it should work. To fix this, go to “Configuration” > “Software” and the “document root” is the first option on the form, make it “/public”.

Connecting Elastic Beanstalk to an RDS database

At this point, you should have a working version of Laravel on your EB that you have uploaded manually and that isn’t connected to a database.

  • To connect to a database modify “Database” in “Configuration”. This is where you can make an RDS instance for your website.
  • Once the RDS is made you’ll still need to allow access to the EB instance and your local machine. Go to the RDS instance and under the “Security” tab there should be a “VPC security groups” heading, click the url below it.
  • Having clicked on the link you should now see some tabs that include “Inbound” and “Outbound”. Click inbound and add “MySQL/Aurora” for your local IP this makes a rule for port 3306.
  • Also, to allow the EB instance to access the RDS DB you’ll need to add it’s security group. In the “source” field start typing “sg-” to get a list of all the available security groups and select the appropriate one then “save”.
  • You can now edit the “.env” file with your RDS information and it should be able to connect locally and from your EB instance.
  • Test out your new database by running the migration locally, if it works you can assume it should work from EB so update by making another zip with the updated files then “Upload and Deploy”.

Your AWS EB instance should now be able to chat with the database freely but you’re still updating with the zip files.

Deploying from GIT to your Elastic Beanstalk instance

Most of this comes from this url and this url

  • Update your .gitignore file then add everything you need from your project directory to the empty repo you set up on github at the start. Once again, the vendor file should be missing along with any junk from your IDE.
  • Install the latest version of Python 3.
  • Run this command to make sure the default value of Python is the one you want: python3 --version . If it isn’t you’ll have to follow something like this url. NB: python and python3 are different, make sure to follow the advice from the url but use python3 instead of python.
  • Once EB CLI is installed all you need to do is run eb init from your project directory to set up your GIT repo with EB. You’ll need to get an ID/secret from a user in IAM. Once you have created/clicked on the user you would go to “Security credentials” and create an access key. You’ll have to remember this info as you won’t be able to access the secret more than once.
  • Next, with EB successfully initiated all there is left to do is deploy. So, commit your current working Laravel site (and push to Github if you like). EB will be using the current version you have commited in your current branch. To do this run the command eb deploy --staged

Believe it or not, that should have deployed to your instance. Huzzah!!

Troubleshooting

If the Ubuntu machine you are developing on is a new build or has not been used recently for development you’ll need to update and upgrade. When installing Laravel you’ll need to install all the PHP modules it needs (in my case it was “mbstring” and “dom”), you’ll also need to make sure “mysql-server” is installed locally.

Summary

This process is not too bad at all. There are different ways to update an EB instance, e.g. using AWS CodePipeline, but if you prefer Github over AWS’s CodeCommit this method is very straightforward to setup. Using this method on a Production website as I’ve described it here would mean testing locally then only deploying once the work was tested locally. You could also set up a dev server and deploy there first for further testing before deploying to the live website.

This is a simple step-by-step guide to making a PHP composer package that can be listed publicly on packagist.org for anyone in the world to install. We’ll be using Github to update the package. We’ll also add some testing with PHPUnit.

Creating a Composer Package

The basic steps to creating a new composer package are as follows.

  1. Create a Github Repo for the project
  2. Clone the Github repo locally
  3. composer init
  4. composer install
  5. Write the PHP composer package, put the PHP into a src directory.
  6. Commit and push to Github
  7. Give the package a version by using git tag 0.0.1 then git push --tags
  8. Login to Packagist and add the new Github repo to your packagist account.
  9. Make sure all the info packagist.org needs is in your composer.json

After following these steps, your package should now be published on packagist. Any future changes you make should be pushed to Github and make a new tag like this… git tag 0.0.2 and git push --tags. You can list all the tags with git tag. Every time you update in this way, Github will get updated, and packagist will also get updated automatically.

Our class is called Bar, so our main PHP file has to be Bar.php (upper/lowercase matters!). We’ll put it in a directory called “src”…

<?php 
namespace Foo;
class Bar {
    public function helloworld(){
        return 'Hello, World!';
    }
}

Here is a sample composer.json file. Our namespace is “Foo” so we say that Foo is in the src directory in the composer.json…

{
    "name": "foo/bar",
    "license": "MIT",
    "require": {
        "php": "^7.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^5.7"
    },
    "autoload": {
        "psr-4": {
            "Foo\\": "src/"
        }
    }
}

To use the package, import it by copy/pasting the command line instructions from Packagist. It’ll be something like this… composer require foo/bar. Then, once the package has been installed into the vendor directory, you can start using it, like this, for example…

<?php

require_once 'vendor/autoload.php';

$test = new Foo\Bar();

$test->helloworld();

Updating the Package

For testing purposes. Each time you update you need to make sure the latest version is downloaded from Packagist.

Make sure the composer.json of the project you’re inporting the package into has a composer.json like this. You’ll need to make sure the package you’re testing is greater than or equals to >= instead of ^which specifies an exact version.

{
    "name": "neil/test",
    "authors": [
        {
            "name": "neil",
            "email": "[email protected]"
        }
    ],
    "require": {
        "foo/bar": ">=0.4.3",
        "phpunit/phpunit": "^6.5"
    }
}

But, even then composer update may still not do anything when you update the package. You may need to composer clearcache first, then update composer. Also, sometimes there is a short lag in Packagist updating so don’t get too worried if it doesn’t update straight away first time.

Testing the Package

To add testing you might want to use something like PHPUnit or PHPSpec. This is using PHPUnit 6.5 which runs with PHP 7.0…

composer require --dev phpunit/phpunit

Make a directory called tests and make a file called BarTest.php…

<?php
declare(strict_types=1);

use PHPUnit\Framework\TestCase;
use Foo\Bar;

final class BarTest extends TestCase
{

    public function testOutputsExpectedTestString()
    {
        $this->assertEquals(
            'Hello, World!',
            Bar::helloworld()
        );
    }
}

Then, making sure you’re using the “dev” packages you can run the test in the command line like so…

vendor/bin/phpunit --bootstrap vendor/foo/bar/src/Bar.php vendor/foo/bar/tests/BarTest

Unit tests will only work on public functions, not private functions.

Troubleshooting

The name of the class must be exactly the same as the filename, and vice versa. If your class is called SomeClass, the file must be SomeClass.php.

Errors can also come from not using git tag to create a version or not having all the info packagist needs in the composer.json.