Category Archives: how-to

How-to: Setup Laravel 5 on Amazon Linux (w/ PHP5.4 and Apache2.4)

After playing around with node for a couple of years I’ve recently decided to switch back to PHP for a project and have chosen to learn Laravel. It looks sleek, is apparently pretty easy to learn and has lots of features.

It’s 2015 though and I couldn’t find a simple install guide for my scenario: AWS EC2 using Amazon Linux. I eventually found this guide and this guide, and this one which together with my limited knowledge and some troubleshooting became my setup guide below to building my standard Laravel base build. You’ll end up with Amazon Linux with Laravel 5, PHP 5.4 and Apache 2.4.

1. Prep the linux packages, start Apache and set it to autostart.

sudo yum -y update
//sudo ln -sf /usr/share/zoneinfo/Australia/Sydney/etc/localtime
sudo yum install -y gcc make gcc-c++
sudo yum install -y git
sudo yum install -y httpd24 php56 php56-devel php56-mysql php56-pdo php56-mbstring php56-mcrypt
sudo yum install -y php-pear
sudo pear install Log
sudo service httpd start
sudo yum install -y php56-pecl-apc
sudo chkconfig httpd on
sudo service httpd restart

2. Check that you have PHP 5.6 and Apache 2.4, check phpinfo() for loaded modules.

check versions:
  php -v
  httpd -v
sudo chown -R ec2-user /var/www
cd /var/www
vim html/info.php and enter:
<?php phpinfo(); ?>
save and exit, then:
  sudo service httpd restart
then browse to your website URL + /info.php, read loaded modules (use find) and you should see mod_rewrite in the list. If not, you need to enable it.

3. Install Laravel and add a route.

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

(in /var/www) Download and extract Laravel:
  wget https://github.com/laravel/laravel/archive/master.zip
  unzip master.zip && cd laravel-master/ && mv * ../ && cd ..
  rm -r laravel-master && rm master.zip
sudo vim /etc/httpd/conf/httpd.conf and:
  find "AllowOverride None" (its there two times with capitals) and change them all to AllowOverride All
  find "DocumentRoot /var/www/html" and "<Directory /var/www/html" and change both paths to /var/www/public
Save and exit, then:
  sudo service httpd restart
composer install
sudo chmod -R 777 storage
sudo service httpd restart
Browse to your URL, you should see a Laravel 5 welcome image hooray!
One simple change to prove its working, vim app/Http/routes.php and under "Route::get('home'..." enter:
Route::get('/mytest', function()
{
    return "Oh yeah, this really works !";
});  
save and exit, then:
  sudo service httpd restart
Then browse to your URL + /mytest and you should see "Oh yeah, this really works !"
Now you can go explore Laravel ;)

Installing Redis as a service for the session db, and adding AWS RDS (MySql) for the database. The latest ‘Stable’ Redis at time of writing is 3.0.1.

wget http://download.redis.io/releases/redis-3.0.1.tar.gz
tar xzf redis-3.0.1.tar.gz
cd redis-3.0.1
make

sudo mkdir /etc/redis /var/lib/redis
sudo cp src/redis-server src/redis-cli /usr/local/bin
sudo cp redis.conf /etc/redis

sudo vim /etc/redis/redis.conf
[..]
daemonize yes
[..]
[..]
bind 127.0.0.1
[..]
[..]
dir /var/lib/redis
[..]

wget https://raw.github.com/saxenap/install-redis-amazon-linux-centos/master/redis-server

sudo mv redis-server /etc/init.d
sudo chmod 755 /etc/init.d/redis-server
sudo vim /etc/init.d/redis-server

redis="/usr/local/bin/redis-server"

sudo chkconfig --add redis-server
sudo chkconfig --level 345 redis-server on

cd ..
rm -rf redis*

composer require predis/predis

vim config/cache.php

 'default' => env('CACHE_DRIVER', 'redis'),

vim config/session.php

  'default' => env('CACHE_DRIVER', 'redis'),

//first, add a user record to db and make a new page to login auth::attempt
As a test update our /mytest to this:
Route::get('/mytest', function()
{

    if (Auth::check())
    {
      // The user is logged in...
      return "Good golly, you're logged in !";
    }

    return "Dagnamit, you're not logged in buddy !";
});

sudo service restart

Everything should work... is now using Redis for cache and session.

This exact process works flawlessly for me as at 02/06/15 using the standard Amazon Linux PV image and a t1.micro instance, hopefully it does for you too.

How-to: Run multiple Ghost blogs (domains) on one machine

So, from the last post we’ve got our Amazon Linux EC2 instance running our Ghost blog. Its now running on port 80 and will auto start when the server boots. This guide will show you how to add more Ghost blogs to your EC2 instance using the same port.

Every web server listens to requests, and responds with resources on aport. Only one running process can use a given port at any time, so in order to have multiple Ghost blogs using port 80 we setup a proxy which will use port 80 (3000 actually, if you remember from the last guide) and pass traffic onto our blogs on ports 3001 and 3002.

Make sense?… Hopefully. Regardless, these steps should help you get it setup and learn through experience. You should do some research later on what http-proxy is capable of, and other options that are available to you.

The steps to do this:

  • Setup http-proxy
  • Adjust our existing blog’s config
  • Setup a 2nd blog

Let’s do this 🙂

Setup http-proxy

We’ll start by adding a new Node app for our proxy:

  • cd /home/ec2-user
  • mkdir http-proxy
  • cd http-proxy
  • vim app.js and add this javascript to the file:
    var http = require('http'),
        httpProxy = require('http-proxy');
    
    var options = {
      hostnameOnly: true,
      router: {
        'www.myblog1.com': '127.0.0.1:3001',
        'www.myblog2.com': '127.0.0.1:3002'
      }
    };
    
    var proxyServer = httpProxy.createServer(options);
    proxyServer.listen('3000');
    
  • npm install http-proxyThis installs the ‘http-proxy’ NPM module, like we installed forever in the last guide.
  • forever stopallThis stops running forever processes
  • node app.jsOk, you should see that the Node process starts fine. Go to your browser and browse to your blog url. You’ll see an error like this “An error has occurred: {“code”:”ECONNREFUSED”,”errno”:”ECONNREFUSED”,”syscall”:”connect”}” which is good. Its because we’ve setup the proxy but haven’t yet changed the config of the blog itself. Lastly, ctrl+c to exit Node.

Adjust our existing blog’s config

So port 80 is redirected to port 3000. We’ve configured the proxy to use port 3000 and we’ll now adjust our blog’s config to use port 3001 (as we’ve already configured the proxy to forward traffic for www.blog1.com to port 3001).

  • cd ../ghost
  • vim config.jsYour production server config should look like this:
    server: {
                // Host to be passed to node's `net.Server#listen()`
                host: '127.0.0.1', 
                // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
                port: '3001'
    

Ok, save (Esc, :w) and exit (:q). Type the following:

  • NODE_ENV=production forever start index.jsWe’ve started our blog’s Node process again.
  • cd ../http-proxy
  • forever start app.jsWe’ve started our http-proxy’s Node process again.

Browse to your blog, it should appear correctly this time. If so, we have the blog operating correctly through the proxy. It’s time to add another blog!

Setup a 2nd blog

It’s almost the same as the first time we setup Ghost, except that we need to configure it on port 3002. Below are the steps:

  • cd /home/ec2-user
  • mkdir ghost2Use the name of your 2nd blog instead of ghost2!
  • cd ghost2
  • wget https://ghost.org/zip/ghost-0.3.3.zip
  • unzip *zip
  • rm -rf *zip
  • npm install –production
  • cp ../ghost/config.js .
  • vim config.js
    server: {
                // Host to be passed to node's `net.Server#listen()`
                host: '127.0.0.1', 
                // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
                port: '3002'
    

Also edit the url to your blog address e.g. “http://www.bybigs.com“. To save and exit press Esc, :w, :q

If you now run “NODE_ENV=production forever start index.js” your blog will be accessible on your domain. If that’s true, then you now have two blogs operating through the http-proxy, both on port 80!!

The final step to ensure this setup remains after a reboot is to edit the shell script we created in the last guide. We’re nearly there.. the steps are below!

 

    • sudo vim /etc/profile.d/ghost.shEditing our shell script which runs on startup

Add the 2 lines before “fi”. These will auto-start our new Node server processes, the http-proxy and our 2nd blog. If you have more bogs, repeat the steps for adding the 2nd blog over, and over (and over…)

#!/bin/sh

if [ $(ps aux | grep $USER | grep node | grep -v grep | wc -l | tr -s "\n") -eq 0 ]
then
  sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 2368 >/home/ec2-user/iptables.log 2>&1
  export PATH=/usr/local/bin:$PATH
  export NODE_ENV=production
  cd /home/ec2-user/ghost && forever --spinSleepTime 10000 start index.js >> forever.log 2>&1
  cd /home/ec2-user/ghost2 && forever --spinSleepTime 10000 start index.js >> forever.log 2>&1
  cd /home/ec2-user/http-proxy && forever --spinSleepTime 10000 start index.js >> forever.log 2>&1
fi

Next guide I write will probably be on making your own theme. Until then…….. Enjoy.

How-to: Fine tune your Ghost blog instance

Ok, if you’re new to Ghost and looking for a guide on how to setup an Amazon Linux EC2 (free tier) instance very easily, then go here.

Read on if you’ve done that already and this scenario sounds familiar:

My new blog is great but I want to use port 80, and I want it to start automatically whenever the server reboots.

Every web site serves resources to it’s clients over a port. For http:// websites this is usually port 80, for https:// its usually port 443 and Ghost’s default production port is 2368, as in,http://www.myghostblog.com:2368. Now that we have a working Ghost blog it makes sense that we may want to run it on port 80.

The immediate issue with this is that in Linux you need elevated privileges to use port 80, which means running the Node server using root. There are security risks associated with that, so below is another method to achieve the same thing securely.

We’ll also add a script to our server so that if it reboots the Node server restarts automatically.

Assuming you have your first Ghost instance running successfully on port 2368 there are 2 further steps:

  • Redirect port 80 to port 2368
  • Create the bootup script

Redirect port 80 to 2368

Following the initial setup guide we have one Ghost instance running in our /home/ec2-user/ghost directory on port 2368.

So, from the command line type this:

  • sudo iptables -t nat -A PREROUTING -i eth0 -p tcp –dport 80 -j REDIRECT –to-port 2368This command adds a firewall rule on the server that simply says any traffic for port 80 forward to port 2368, and it needs to be executed as root (hence ‘sudo’). Its forwarding traffic to our default port rather than us having to run Ghost as root to use port 80 – nice.

If you restart your Node server instance you’ll be able to connect on port 80, like, http://www.myblog.com

Create the bootup script

Ok we’re going to kill two birds with one stone here. The script above is only in effect until the next reboot, so as well as starting our Ghost blog (Node server) on boot we’ll also insert this rule.

There are a few ways to do this, using rc.local or a crontab but the best way I found was to use a shell script.

Using the shell script method do the following:

  • sudo vim /etc/profile.d/ghost.sh
  • Add the following code:
    #!/bin/sh
    
    if [ $(ps aux | grep $USER | grep node | grep -v grep | wc -l | tr -s "\n") -eq 0 ]
    then
      sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 2368 >/home/ec2-user/iptables.log 2>&1
      export PATH=/usr/local/bin:$PATH
      export NODE_ENV=production
      cd /home/ec2-user/ghost && forever --spinSleepTime 10000 start index.js >> forever.log 2>&1
    fi

    ..then save and exit. This script runs on boot and does a few things. It adds the iptables rule and logs the output, it adds node’s path to the system path then runs forever to start your blog (and keep it running), and logs any output to forever.log. If you run into issues check out the logs to see what’s going wrong.

Do a reboot and then “forever list” to confirm its running or fire up your blog in the browser.

Next guide I’ll show you How-to: Run multiple Ghost blogs (domains) on one machine on the one Amazon Linux instance! Until then…

How-to: Setting up a Ghost blog on AWS

This is a guide to help you setup a Ghost blog manually, using Amazon Web Services infrastructure, in the most simple steps.

If you didn’t know, Ghost is a new blogging platform based on Node, andjavascript. I’ll assume for this guide that you have access to and the basic knowledge to setup an Amazon Web Services EC2 Amazon Linux (t1.micro) instance, an Elastic IP, redirect your public DNS, and to connect to EC2 using SSH (putty).

I highly recommend reading Gregg Housh's guide as well, he provides some excellent security additions to the setup process that have not been included here.

 

Step 1: Setup EC2 instance

Log into Amazon Web Services (I’ll refer to this as AWS from now on). Go to the EC2 section and Launch a new instance.

Choose Amazon Linux 64bit, choose a relevant Security Group that has port 22 open to your IP, choose a relevant keypair that you have stored in an accessible but secure place. Launch!

Step 2: Connect and configure Linux

Log into your new instance using Putty or other SSH tool.

Note: I usually connect an AWS ‘elastic’ (public) IP to the instance as soon as I launch it, and therefore always connect to the same IP. Elastic IP’s aren’t free however.

Once you have a command prompt, follow these commands…

  • Type: sudo yum updateThis updates the linux components to their latest versions. Choose ‘y’ when asked to proceed.
  • sudo yum install gcc-c++ make
  • sudo yum install openssl-devel
  • sudo yum install gitThese install dev tools to build the node stack.
  • git clone git://github.com/joyent/node.git
  • cd nodeThis downloads Node, next we’ll build it.
  • sudo git checkout v0.10.22

    At time of writing this was the latest stable Node build. Ghost requires a v0.10.x, you should be able to take a later one if it exists

  • ./configure
  • sudo make

    Go make a coffee.. this may take up to 30 mins

  • sudo make installNode is now installed.
  • sudo vim /etc/sudoersPage down until you find this line:Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/binMove to the end of the line, press i and you should be in insert mode, paste this::/usr/local/bin

    There should be no spaces in the line. Now press Esc, then :w!, then :q

    Next we install NPM which is package manager for Node, and is also required for Ghost.

  • sudo git clone https://github.com/isaacs/npm.git
  • cd npm
  • sudo make install

    I’ve found that if you run this as root you get permissions errors. The best way is to run it as the ec2-user using sudo. If you need to fix it up after the fact, running this section as ec2-user should fix it: sudo node cli.js install -g -f

 

Step 3: Installing Ghost!

You’ll need to create a directory that your Ghost blog will sit under. I usually do this elsewhere but we’ll use the ec2-user’s home dir for this example, /home/ec2-user. If you type “cd ../..” we’re back at the home dir.

Updated 18-11-13: Thanks to jgillich for pointing out the initial security issue in this guide that has been corrected.

  • mkdir ghostThe blog dir is now created, time to download and install Ghost
  • wget https://ghost.org/zip/ghost-0.3.3.zip
  • unzip *zip
  • rm -rf *zipOnce completed you have the base Ghost install. (There’s more to do though)
  • npm install –productionThis installs module dependencies via NPM, the Node package manager
  • npm start

    You should see a few lines indicating the server is running – good news! Press ctrl+c to return to the command line.

  • vim config.jsWe’ll edit the config settings here for your specific blog. Using page up/down scroll through the file and find the sections relating the dev and production. Each have a server IP, url and port associated with them. You need to change the url to your blog e.g. “http://www.bybigs.com“, leave the port but remember the number, and change the server IP to the private IP of your instance. In your AWS console you’ll find it by selecting your instance and finding “Public IPs” amongst the other instance details at the bottom. To save and exit press Esc, :w, :q

If you now run “npm start” again your blog will be accessible on your domain and correct port e.g. http://www.bybigs.com:2368. If you want it to be accessible once you close the SSH session (most likely!) then we need to install forever – another NPM module.

So, type “npm install forever -g” and once that’s done you can start the server by typing “NODE_ENV=production forever start index.js”, and you can close the SSH window.

Abracadabra!

Next up, How-to: Fine tune your Ghost blog instance!