Guidance to setup ec2 instance to host production web service by apache + laravel
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)
, clickselect
- choose instance type
t3.small
and clickReview 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 insidemaria 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>
EOFsudo 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.