Guidance to setup ec2 instance to host production web service by apache + laravel

Stanley Liang
5 min readMar 23, 2022

--

Photo by Sigmund on Unsplash

Introduction

The primary scope of my current job is to focusing on frontend development. Recently I have a opportunity to be a consultant to help a sibling company to enhance their e-commerce product. That’s the reason why I start from scratch to setup an ec2 instance to host the web service.

NOTE: if you are interested in how to setup a development environment, this might helps: https://stanely01.medium.com/build-up-a-laravel-development-environment-by-vagrant-3e46ca0ddff1

Techs involved

Actually the sibling company didn’t take much fancy techs, the following are the techs involved in the e-commerce product:

  • EC2 service of AWS
  • Maria DB, It’s made by the original developers of MySQL and guaranteed to stay open source
  • Laravel, a MVC web framework based on php
  • Apache, an open-source HTTP server for modern operating systems
  • https setup by Let’s encrypt

The detailed steps will be specified in the below sections

Create EC2 instance

The fundamental step is to create the ec2 instance to install and setup all techs required.

  • access https://ap-southeast-1.console.aws.amazon.com/ec2/v2/home
  • click new instance
  • select AMI Amazon Linux 2 AMI (HVM) - Kernel 4.14, SSD Volume Type 64-bit (x86), click select
  • choose instance type t3.small and click Review and Launch. Actually you can choose the type you prefer.
  • The wizard will warn you to setup the security group, click to setup it up
  • ensure port 22 (ssh), 80 (http), and 443 (https) are allowed in the security group. You can also restrict the request for certain IPs for security purpose.
  • Launch the instance
  • The wizard ask you to create a key pair. Create one and download it. NOTE: It’s very important to download and keep the key securely because there is no other entry to download it again.
  • Then, you can find the instance you just setup in the aws console
  • Verify the ssh connection by the IP assigned and the key you just downloaded, for example:
ssh ec2-user@<the ip of instance> -i <key downloaded>.pem
  • welcome to onboard the instance
  • update yum libraries in the instance
sudo yum update -y
  • ensure your instance is assigned a static ip by elastic ip
  • create a domain by aws route 53 to redirect the requests to the elastic ip, ensure the domain name you created is updated into the virtual host file we create above

Setup Maria DB

  • update the yum repo to install stable release of maria db
sudo tee /etc/yum.repos.d/mariadb.repo<<EOF
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.5/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1
EOF
  • it’s time to install maria db service
sudo yum makecache 
sudo yum install MariaDB-server MariaDB-client -y
sudo systemctl enable --now mariadb
  • verify it by cli
sudo mysql
  • If you switch maria db cli, it’s installed succesfully
  • change the password of user root to access the db, here you get to type the command inside maria db cli
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('mypassword');
  • you can change the password to anyone you like, ensure it’s copied to the .env of the laravel project
  • create the database by maria db cli
create database mydb;
  • you can change the database name as well, and ensure it’s copied to the .env file.

Setup Laravel

install php7.4

sudo amazon-linux-extras enable php7.4
sudo yum clean metadata
yum install php php-mbstring php-zip php-cli php-pdo php-fpm php-json php-mysqlnd php-xml

install composer of php

composer is the library management of php eco-system.

cd ~
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer

install nodejs

Yes, nodejs is required because we have laravel mix which is a mix way to implement ui by both templates and FE frameworks / libraries.

Here we adopt n to install nodejs

cd ~
curl -L https://raw.githubusercontent.com/tj/n/master/bin/n -o n
sudo bash n lts
sudo ln -s /usr/local/bin/node /usr/bin/node
sudo ln -s /usr/local/lib/node /usr/lib/node
sudo ln -s /usr/local/bin/npm /usr/bin/npm
sudo ln -s /usr/local/bin/node-waf /usr/bin/node-waf

prepare the project

  • clone the laravel project by github repo or any other mechanisms you prefer
cd ~
https://github.com/mygit/myproject.git
  • copy the project in the cloned repo to the apache working folder
cp -rf myproject /var/www/html/
  • install laravel (ya, don’t hesitate, you get to use npm as well)
cd /var/www/html/myproject
composer install --ignore-platform-reqs
npm install
npm run production
  • prepare the .env file, the following variables are necessary
DB_CONNECTION=mysqlDB_HOST=127.0.0.1DB_PORT=3306DB_DATABASE=mydbDB_USERNAME=rootDB_PASSWORD=mypassword
  • run steps for production
php artisan key:generate
php artisan migrate
php artisan db:seed
php artisan passport:install
php artisan view:cache
  • set permission of the laravel storage folders or the request will be 500 as you make post requests because laravel cannot logs
cd /var/www/html/myproject
chown -R $USER:apache storage
chown -R $USER:apache bootstrap/cache/
chmod -R 775 storage
chmod -R 775 bootstrap/cache

Later we will setup Apache service to host the web service we prepared.

Setup Apache

  • install apache service
sudo yum install httpd -y 
sudo systemctl enable httpd
setup the permissions of folders
  • sudo systemctl restart httpd
sudo usermod -a -G apache ec2-user
sudo chown -R ec2-user:apache /var/www
sudo chmod 2775 /var/www
find /var/www -type d -exec sudo chmod 2775 {} \;
find /var/www -type f -exec sudo chmod 0664 {} \;

setup apache virtual host to have our lavavel engine handle the http / https request

About the virtual host, you can think it as we tell apache to know the folders where we host we apps

sudo tee /etc/httpd/conf.d/myweb.conf<<EOF
<VirtualHost *:80>
ServerName www.mydomain.com
DocumentRoot "/var/www/html/myproject/public"
DirectoryIndex index.php
<Directory /var/www/html/myproject/public>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
EOF
sudo systemctl restart httpd

Setup https by Let’s Encrypt

A nonprofit Certificate Authority providing TLS certificates to websites. Setting up https is never an easy task. Let’s Encrypt ease the process.

  • ensure your instance is assigned a static ip by elastic ip
  • ensure there is a domain name (e.g www.mydomain.com) mapping to the static ip assigned above.
  • assign the certbot repo by yum
cd ~
sudo wget -r --no-parent -A 'epel-release-*.rpm' https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/
sudo rpm -Uvh dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-*.rpm
sudo yum-config-manager --enable epel*
sudo yum install -y certbot python2-certbot-apache
  • setup https by certbot and answer the questions
sudo certbot
  • it might take some time to complete the https by certbot, 1 ~ 5 mins
  • verify https by browser, e.g https://www.mydomain.com

Schedule to renew the ssl

sudo crontab -e// append the following contents
39 1,13 * * * root certbot renew --no-self-upgrade

Summary

Hopefully this helps you to prepare your proudction server to host Laravel app.

--

--

Stanley Liang
Stanley Liang

Written by Stanley Liang

Located in Tawian, loving web development to help any kind of business. Surfing, Beer, Coffee, who could reject them!!??

No responses yet