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.

Basic Steps After Installing Laravel 5.4

You have successfully installed Laravel 5.4 and you have directed the domain name at the public directory and you can see then Laravel test page. What next? Assuming that you are going to be using a database to run your website, here are some basic steps in how to build a Laravel website from the Laravel test page.

For this simple example, this guide may work for Laravel 5.x but this guide is specifically for Laravel 5.4.

Contents

Useful Commands
1) The Database
2) The .env file
3) The Model
4) The Migration
5) The Route
6) The Controller
7) The View
Conclusion
Errors and Solutions

Useful Commands

If you want to clear Composer cache (-o flag means optimized)… composer dump-autoload -o

Die and dump, like var_dump($variable); would be this in Laravel… dd($variable);

List all Artisan commands help… php artisan list then look at the help file for a specific command php artisan help controller:make

Run tinker… php artisan tinker. Then, exit with “q” or CTRL-C.

1) The Database

Create the database and give it a user.

2) The .env file

Add the database login info to the .env file which should be in your root (the level below “public“).

While you’re there you may aswell update as much of the info in the .env file as you can. If the name of the website has a space in it remember to use quotes. Not using quotes will cause an error.

You can also update the config/app.php file. If you get errors after updating this file double-check the permissions and ownerships and you may need to run composer dump-autoload -o afterwards if errors persist.

3) The Model

Laravel is an MVC framework. It is designed to use Models, Controllers and Views.

In this simple example, we’re just going to list some data from a database onto the page. The data we want to display are some names. One way to make a Controller for “names” is using Artisan like this… php artisan make:controller NameController. You can make the Model and the Controller separately, but we also need a Migration, why not make all three together in Artisan like this…

php artisan make:model Name -mc

The -mc literally means to create a Migration and a Controller at the same time as the Model.

If the Model is Name (capitalized and singular), the Controller would be NameController (camelcase), the Migration would be create_names_table, and the resulting table would be names (lowercase, plural). The Models are in the app directory.

Using this method the Model is already using Laravel’s database engine, Eloquent, and because of the naming convention, the Model knows which database it is connected to so we do not have to add it manually.

The Model can contain relationships and scopes, but in this simple example, we will not alter it at all.

4) The Migration

The Migration files are created for you in Step 3, they will be in the database/migrations directory. Now, you have to modify them for the data you want to use. I only want each name to have an ID and the name itself in this example, so I can modify the Migration to look like this using Laravel’s Schema…

public function up()
{
Schema::create('names', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
});
}

Here, id is an incremental integer and name is a string. For more database column types you can use in Migrations see Adding Columns. You can also specify indexes, foreign keys and set a default value for a column in the Database: Migrations.

Then, php artisan migrate builds the info from the Migration tables in the database.

If you change the migrations you can rollback and then make the migrations again with

php artisan migrate:refresh

5) The Route

Once you have a Controller and Model you can make a simple route. The routes directory has a file called “web.php”…

Route::get('/', '[email protected]');

'/' means when the URL is the root domain Laravel will call the Controller and method in the second parameter.

NameController is the name of the Controller that was created in Step 3.

index is the method we want to use. There are up to 7 default behaviours that a Controller should have: index, create, store, show, edit, update, and destroy. These methods within a Controller are called actions. If you find that your controller needs more than these 7 actions it may be a good idea to create a new Controller.

6) The Controller

The Controller is the file “NameController.php” that lives in the app/Http/Controllers directory. From Step 5, we said that we wanted to use the index method because we just want to list all the names. To do this we can use Eloquent and the all() function to simply grab all the rows from the table…

use App\Name;
public function index ()
{
$names= Name::all();
return view ( 'names.index', compact('names') );
}

If you “use” the Model in this way at the top, use App\Name;, you can refer to the Model in the methods like this Name::all(); as opposed to App/Name::all();. Instead of using all() you could also use Eloquent but order the results differently using get()

$names = Name::orderBy('name', 'desc')->get();

The same thing as all() but not using Eloquent would be…

$names= \DB::table('names')->get();

The \ is needed in front of the DB because you are inside the Controller and the DB class exists outside of it. Or, just “use” DB at the top of the controller, see Queries.

Out of these two different ways to interact with the database, it is better to use Eloquent and to keep most of the database-related logic inside the Model. In more complex projects than this example, the Model would contain Scopes and Statics that can be referred to from other places, such as Controllers.

The 'names.index' is the View we want to use and compact('names') is a way to pass the $names array into the View, alternative ways are listed in Passing Data to Views, for example…

return view('names.index')->with('name', $name);

7) The View

In the Controller we said the View we wanted to use was names.index. This means that Laravel will be looking in the resources/views/names/ directory for the file: “index.blade.php“. So make this file.

The View uses the Blade templating engine so ideally, the contents will be a mixture of HTML and simple logic. You can either use normal PHP, like <?php if($names){ ?>. Or, it may be better to use the blade templating system and write it using Blade like this @if ($names). With Blade you do not have to keep opening and closing the PHP making it a lot easier to write and cleaner to look at than normal PHP mixed into the HTML would be.

We want to display all our names on the page using Blade. In step 4, we gave the table 2 columns in the migration, “id” and “name”, and, in step 6, we got all the data from the “names” database. Now, they can be displayed very simply in a list like this within HTML using Blade…

@if ($names)
<ul>
@foreach ($names as $name)
<li>{{ $name->id }} - {{ $name->name }}</li>
@endforeach
</ul>
@endif

Now, when you go to the root domain of the Laravel website the Route sends you to the correct method of the Controller, which uses the Model and the View to grab the names and display them (assuming you have also inserted some rows to the database).

Conclusion

The 7 steps of this very simple beginners tutorial use the route, model, controller and view parts of Laravel.

  • The Route links the URL with a specific control and method, and can pass variables through to them.
  • The Model just links the table in the database to the controller in this simple example. In more complex examples the Model interacts with the database more and specifies relationships.
  • The Controller does what we want the page to do, in this case, it is to fetch the list of names from the Model (database) and it also says which view will display the data.
  • The View takes the data from the Controller and displays it on the page.

Errors and Solutions

An Artisan command produces an error like this…
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table users add unique users_email_unique(email))

Edit your “AppServiceProvider.php” file in the app/Providers directory and add to the boot method a default string length. You also have to make sure to “use” the Schema at the top.

use Illuminate\Support\Facades\Schema;
function boot()
{
Schema::defaultStringLength(191);
}

****************************
If migrate:refresh produces an error like…

[Illuminate\Database\QueryException]
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'users' alre
ady exists...

Manually drop the tables in tinker by running tinker (see Useful Commands) and running the command…
Schema::drop('users')

Now, you can now run php artisan migrate to migrate all the tables.

****************************
Pages aren’t loading at all (fatal error), looking at the logs gives the error message…
Fatal error: Uncaught exception 'UnexpectedValueException' with message 'The stream or file...

Solution, make the Laravel log files writable…
sudo chmod -R 777 storage/logs

I was unable to find a single tutorial that would show exactly how to install Laravel on Debian, possibly because I was using PHP 7.0 on Debian, which no other examples seemed to use. As such, I had to take bits and pieces from different websites to make this tutorial on installing Laravel on Debian. The same tutorial will also work for Ubuntu but I found that on Ubuntu 16.04 a lot of the dependencies were already installed out of the box, Debian may require more care to make sure everything is present. Once you have all the requirements installed it should be easy to install composer, and once composer is installed Laravel should also be fairly simple if you are doing the right things.

I found that some methods of installing Laravel did not work on my setup, this may have been because it was Debian or because I’d missed a requirement. This is the method that worked for me, and also works on Ubuntu.

Installing Composer

Before starting the most important thing is to make sure to apt-get upgrade and apt-get update… and also, make sure all the Laravel server requirements are installed. Once that’s done, restart/reload and begin. From here, you can install composer by typing these commands into the Linux terminal…

curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

Installing Laravel

Then navigate to where you want to put the new website and create a new project. The name of the project will be the name of the directory, so here I’ve called it example.com, because it is a shared server…

cd /var/www
sudo composer create-project laravel/laravel example.com --prefer-dist

This way you can easily specify the directory name. There is an alternative method here.

After installation, the last thing it should tell you is what the encryption key is. A good thing to do right away would be to check that this is the same as the value in the .env file. If the installation was successful it should be there, but it is good to check and also to have a first encounter with the .env file!

Configuring your Website to Run Laravel

Now, set up this new domain as normal on your webserver, making sure that instead of pointing to the /var/www/example.com directory, you point to /var/www/example.com/public.

Next, one thing that I was not prepared for with Laravel was the need for the ownerships and permissions to be correct. All the files will probably be owned by the root user, so change them to whichever user they should be (i.e. not root). So, navigate to your web directory and change the owner as follows…

cd /var/www
sudo chown -R youruser example.com

Then, after that navigate to the public folder in your directory and it may not work. First make sure the storage directory has the correct owner, group and permissions…

cd /var/www/example.com
sudo chown -R youruser:www-data storage
sudo chmod -R ug+rwx storage

Changing storage may fix the problem, or if there are still problems you can also do this for the bootstrap/cache directory.

Now, make sure your site is pointing at the public directory and it should be working now and showing you the Laravel welcome page…

Laravel Welcome Page

If you see a page like this in your browser in the public directory, Laravel was installed and is working.

If not check the requirements are installed, then the permissions, owners, and groups. In particular, if it is a brand new web server with no other websites already running on it, check things like MySQL and all the requirements for both Composer and Laravel.

Finishing Up

From this stage, if you see the Laravel welcome page you’re all set up. You can set up a database and a database user in MySQL and enter the information in the .env file. You should also make sure that mod_rewrite is installed and that your Virtual host config file is allowing it to work.

Troubleshooting

If you run the composer create-project command but you get an error, maybe you have some missing dependencies, the files will be in the new directory but nothing will be installed yet. To install you’ll need to install the dependencies then run the command composer update laravel which will complete the installation. I got this error on Ubuntu 16.04 because PHPUnit was not installed.

If after following this guide you get an error like… No application encryption key has been specified. Run this command to generate a key (automatically adds it to the .ENV file)… php artisan key:generate