In this post we explore what it takes to provision a remote Linux server, and then deploy one or more Laravel project applications to it.
Note that by “project applications” I mean prototypes, interview homework projects, and the like.
In particular we’ll be deploying several instances of the Template Application we’ve been developing in this series.
Prerequisites and assumptions
For this post I assume you already know how to instantiate a Linux instance on the cloud provider of your choice, and that you <3 the command line. I also assume you’ve already gone ahead and spun up a server, and have full sudo access to it.
For reference here is what I’m working from for this write-up:
- Provider: Amazon AWS
- AMI: Ubuntu Server 18.04 LTS (HVM), SSD Volume Type - ami-05c1fa8df71875112 (64-bit x86) / ami-0606a0d9f566249d3 (64-bit Arm)
- Type: t2.micro
Security
I’m not going to delve much into security in this post, as that’s a whole other write-up unto itself. I would suggest; however, that at a minimum reviewing a quick-start guide such as this one.
The process
We first need to access the server, update it, and then install the core components we’ll need.
Adding swap space
First thing we’ll do is enable some swap space. The t2.micro instances don’t start out with any, and it causes issues later with npm if we don’t do it now. (Reference)
From the command terminal:
sudo /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
sudo /sbin/mkswap /var/swap.1
sudo /sbin/swapon /var/swap.1
Example:
ubuntu@ip-172-31-23-22:$ sudo /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 13.4465 s, 79.9 MB/s
ubuntu@ip-172-31-23-22:$ sudo /sbin/mkswap /var/swap.1
mkswap: /var/swap.1: insecure permissions 0644, 0600 suggested.
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=0a0c61cf-ace9-48e8-8b30-0dbcd98a3fa3
ubuntu@ip-172-31-23-22:$ sudo /sbin/swapon /var/swap.1
swapon: /var/swap.1: insecure permissions 0644, 0600 suggested.
ubuntu@ip-172-31-23-22:$ free
total used free shared buff/cache available
Mem: 1007520 271128 68516 2356 667876 588200
Swap: 1048572 0 1048572
ubuntu@ip-172-31-23-22:/var/www/html/AppTemplate$
Install dev tools
It seems like every time I don’t install build-essential something requires it, so let’s go ahead and take care of that now. The tree package isn’t required, but I often find myself using it.
sudo apt-get update && sudo apt-get upgrade
sudo apt-get install build-essential tree
Install LAMP
From the command terminal:
sudo apt install lamp-server^
This will of course install Apache, MySQL, and PHP.
Install PHP extensions, composer, and npm
From the command terminal:
sudo apt-get install php-mbstring php-xml php-zip
sudo apt-get install composer
sudo apt-get install npm
Configure Apache
Enable Apache module mod_rewrite
From the docs:
The mod_rewrite module uses a rule-based rewriting engine, based on a PCRE regular-expression parser, to rewrite requested URLs on the fly. By default, mod_rewrite maps a URL to a filesystem path. However, it can also be used to redirect one URL to another URL, or to invoke an internal proxy fetch.
mod_rewrite provides a flexible and powerful way to manipulate URLs using an unlimited number of rules. Each rule can have an unlimited number of attached rule conditions, to allow you to rewrite URL based on server variables, environment variables, HTTP headers, or time stamps.
mod_rewrite operates on the full URL path, including the path-info section. A rewrite rule can be invoked in httpd.conf or in .htaccess. The path generated by a rewrite rule can include a query string, or can lead to internal sub-processing, external request redirection, or internal proxy throughput.
To enable it from the command line:
sudo a2enmod rewrite
Update /etc/apache2/sites-available/000-default.conf
Next we want to configure Apache to serve the multiple Laravel applications we want to deploy. At first it may seem like we’d want to use Name-based Virtual Hosts, but I can assure you after hours of tinkering and reading posts from other people struggling to make it work the following method will help retain more of your sanity.
Edit the /etc/apache2/sites-available/000-default.conf and replace its contents with the following:
DocumentRoot /var/www/html
Alias /part-one /var/www/html/part-one/public
Alias /part-two /var/www/html/part-two/public
Alias /part-three /var/www/html/part-three/public
<Directory /var/www/html/part-one/public/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
Require all granted
</Directory>
<Directory /var/www/html/part-two/public/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
Require all granted
</Directory>
<Directory /var/www/html/part-three/public/>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
Require all granted
</Directory>
LogLevel debug
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
So in the example above we are setting Apache up to serve three instances of our App Template Laravel application. We’ll link each instance to a different version of the App Template, and this will allow us to view what the application looks like for the first, second, and third parts. Clearly you could easily add additional instances of other Laravel applications and/or projects as you see fit.
We’ll wrap up this section by restarting Apache:
sudo systemctl restart apache2
Deploy the first application instance
We are now ready to deploy the first application instance:
Deploy application source code
We start by deploying the Laravel application source code onto the server. For this post we’ll be deploying the Application Template project code we’ve been working on in previous posts. (You can find the first article in the series here.) Since each post in the series adds new functionality, it would be nice if we could run each stage of development as a separate application instance. We could then view the progress of the application by interacting with the versions live.
Clone from git
From the command terminal:
cd /var/www/html/
sudo git clone -b PartOne https://github.com/nrasch/AppTemplate.git part-one
This places a copy of the PartOne branch into the /var/www/html/part-one directory, which we created an alias for in the /etc/apache2/sites-available/000-default.conf file above.
Configure
From the command terminal:
cd /var/www/html/part-one
sudo chown -R ubuntu:ubuntu ./
find ./ -type f -exec chmod 644 {} \;
find ./ -type d -exec chmod 755 {} \;
sudo chgrp -R www-data storage bootstrap/cache
chmod -R ug+rwx storage bootstrap/cache
This will set the proper permissions on the Laravel folders.
We also need to enable base rewriting. Edit the the public/.htaccess file, and ensure you have the following two lines:
RewriteEngine On
RewriteBase "/part-one/"
Install composer and npm packages
Next run the following commands to install the composer and npm packages:
composer update
npm install
npm run dev
composer dump-autoload && php artisan cache:clear
Create and update the .env file
We also need to create an .env file, and configure it for the application instance.
From the command terminal:
cp .env.example .env
Edit the new .env file and update APP and DB sections as follows:
APP_NAME='Application Template Part One'
APP_ENV=local
APP_KEY=base64:WVOLcnrIHJebzm3WOexSohpDxYN/3tlMx4YnGss65FY=
APP_DEBUG=true
APP_URL=http://<YOUR_IP>/part-one/
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=app_template_part_one
DB_USERNAME=app_template
DB_PASSWORD=!app_template!
And wrap up with the following command:
php artisan key:generate
Configure the database
At this point the source code has been deployed and configured, but we still need to modify the database to support the application.
Open a SQL CLI with the sudo mysql command, and execute the following statements:
CREATE DATABASE app_template_part_one CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE USER 'app_template'@'localhost' IDENTIFIED BY '!app_template!';
GRANT ALL PRIVILEGES ON app_template_part_one.* TO 'app_template'@'localhost';
FLUSH PRIVILEGES;
quit;
This creates the database, database user, and permissions the Laravel application will utilize for database operations, storage, etc.
Seed the database
To wrap up we’ll seed the database. From the command prompt:
php artisan migrate --seed
Test the deployment
At this point you should be able to open a browser, point it at http://__YOUR_IP__/part-one, and see an instance of the application template load.
Ex:
Deploy the second application instance
We can now deploy the second Laravel application instance. For this example we’ll deploy the third part of the Application Template series. The steps are almost exactly the same as before, so we’ll simply paste the commands in a single code block for reference:
# Deploy the source code
cd /var/www/html/
sudo git clone -b PartThree https://github.com/nrasch/AppTemplate.git part-three
# Set the permissions
cd /var/www/html/part-three/
sudo chown -R ubuntu:ubuntu ./
find ./ -type f -exec chmod 644 {} \;
find ./ -type d -exec chmod 755 {} \;
sudo chgrp -R www-data storage bootstrap/cache
chmod -R ug+rwx storage bootstrap/cache
# Edit the public/.htaccess file
vim public/.htaccess
RewriteEngine On
RewriteBase "/part-three/"
# Create a new .env file
cp .env.example .env
# Edit the .env file
vim .env
APP_NAME='Application Template Part Three'
APP_ENV=local
APP_KEY=base64:WVOLcnrIHJebzm3WOexSohpDxYN/3tlMx4YnGss65FY=
APP_DEBUG=true
APP_URL=http://<YOUR_IP>/part-three/
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=app_template_part_three
DB_USERNAME=app_template
DB_PASSWORD=!app_template!
# Create the database for the application
sudo mysql
CREATE DATABASE app_template_part_three CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL PRIVILEGES ON app_template_part_three.* TO 'app_template'@'localhost';
FLUSH PRIVILEGES;
quit;
# Install the composer and npm packages
composer update
npm install
npm run dev
# Reload Laravel and clear out cache
composer dump-autoload && php artisan cache:clear
# Seed the database
php artisan migrate --seed
# Create a new application key
php artisan key:generate
You would simply repeat this process for each new Laravel application instance you wanted to deploy.
And finally, let’s test it out:
Summary
This post has covered the steps to instantiate and configure a Linux server running on the cloud that is able to serve multiple Laravel project applications. We were able to clone and deploy two such items, and we were also able to browse to and interact with them.
If you have any comments or questions please don’t hesitate to reach out.
Thanks!
Comments