Amazon Linux AMI setup for AWS EC2 micro instance. The fast way. (LEMP Stack, PHP 7.3, MySql 5.7)
After a few years of using EC2 boxes for development and production, this has become my routine setup for micro and small instances.
If you need to start up a new instance, take a look at my previous post.
I'm assuming you're already ssh-ed into your instance, so.. Let's go!
Let's make sure you have all the latest goodness.
Running the update with --changelog
will allow you to keep track of what's changing.
$ sudo yum install yum-plugin-changelog
$ sudo yum update --changelog
SWAP FILE
We only have 1 GB of memory available and no virtual memory to extend it. That alone is a major cause of server crashes and hangups. Simply creating a swap file is a well-known, effective micro instance tweak.
Create and activate a 2 GB swap file with the following:
$ sudo dd if=/dev/zero of=/swapfile bs=1M count=2048
$ sudo mkswap /swapfile
$ sudo chmod 0600 /swapfile
$ sudo swapon /swapfile
We generate the file with dd
, make a swap filesystem with mkswap
, set proper permissions with chmod
, and mount it with swapon
.
Add the following line to /etc/fstab to make it persist over reboot:
$ sudo vim /etc/fstab
/swapfile swap swap defaults 0 0
Feel free to use any other editor than VIM.
However VIM is very simple. Press i
to be able to insert/paste text. esc
to exit a mode, :x
to save and quit.
Now that we have virtual memory, let's double check it.
Type $ free
and you should see the following.
You can see the last line, with our 2Gb of swap file!
NGINX and PHP
$ sudo amazon-linux-extras enable php7.3 nginx1.12
$ sudo yum install nginx php-cli php-pdo php-fpm php-json php-odbc php-soap php-mbstring php-bcmath php-ldap php-gd php-mcrypt php-mysqlnd
PHP-FPM configuration. (FastCGI Process Manager)
Add the following to the end of /etc/php-fpm.d/www.conf:
$ sudo vim /etc/php-fpm.d/www.conf
Look for this line (towards the beginning) listen.acl_users = apache,nginx
and put a semicolon in front of it, like the following: ;listen.acl_users = apache,nginx
.
Now scroll to the end of the file and copy and paste this configuration:
[global]
emergency_restart_threshold = 10
emergency_restart_interval = 1m
process_control_timeout = 10s
[www]
listen = /var/run/php-fpm/php-fpm.sock
listen.owner = nginx
listen.group = www
listen.mode = 0664
user = nginx
group = www
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 200
php_admin_value[memory_limit] = 256M
Nginx is setup to work with the group www
. We need to create the group and set the proper permission schema.
Type in $ groups
and verify that www
doesn't already exist.
We can easily add it with the following commands.
$ sudo groupadd www
$ sudo usermod -a -G www ec2-user
$ exit
- this will terminate your ssh session. Ssh in again and type,
$ groups
to verify that the new www
group has been added.
Let's create our www
directory.
$ sudo mkdir /var/www
Set write permissions to /var/www
for www
group.
$ sudo chown -R root:www /var/www
We need to change the web root directory permissions so that the www
group has write permissions:
$ sudo chmod 2775 /var/www
We also need to set the same permissions for any future subdirectories:
$ find /var/www -type d -exec sudo chmod 2775 {} +
Then we do the same for files within those directories and subdirectories:
$ find /var/www -type f -exec sudo chmod 0664 {} +
Now we're good to configure your website and the location where your project will be. Feel free to customize this part with your own domain and project name.
$ sudo mkdir /etc/nginx/sites-enabled
$ sudo vim /etc/nginx/sites-enabled/example.com.conf
server {
listen 80;
server_name example.com;
root /var/www/example/public;
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log /var/log/nginx/example.com_access.log;
error_log /var/log/nginx/example.com_error.log;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
include fastcgi.conf;
}
location ~ /\.ht {
deny all;
}
}
server {
listen 80;
server_name www.example.com;
return 301 http://example.com$request_uri;
}
To allow us to manage multiple domain or subdomain on the same server, we need to tell Nginx to load all the files under sites-enabled folder.
To do so, type:
$ sudo vim /etc/nginx/nginx.conf
After include /etc/nginx/conf.d/*.conf;
add:
include /etc/nginx/sites-enabled/*.conf;
and save.
Before we start our services, we need to create our project folder.
$ sudo mkdir -p /var/www/example
To test things out, let's put a piece of php in it.
$ cd /var/www/example
$ sudo mkdir public
$ cd public
$ sudo vim index.php
Copy and paste the following.
<?php
echo 'Hello Human!';
Comment out the section as shown, we're gonna disable the default "Welcome to NGINX" screen.
# server {
# listen 80 default_server;
# listen [::]:80 default_server;
# server_name _;
# root /usr/share/nginx/html;
# Load configuration files for the default server block.
# include /etc/nginx/default.d/*.conf;
# location / {
# }
# error_page 404 /404.html;
# location = /40x.html {
# }
# error_page 500 502 503 504 /50x.html;
# location = /50x.html {
# }
# }
Save the file and exit.
Now let's start the engines!
$ sudo chkconfig nginx on
— Set autostart.
$ sudo chkconfig php-fpm on
— Set autostart.
$ sudo service nginx start
$ sudo service php-fpm start
If you want to run a quick test, you can type in http://your-public-ip-address in your browser and you should see:
Take a moment, to congratulate yourself!
MYSQL
Install MySql server with:
$ sudo yum install mariadb-server
Like before, start it up with:
$ sudo chkconfig mysqld on
— Set autostart.
$ sudo service mysqld start
To secure your database installation type:
$ sudo mysql_secure_installation
Set a root password and accept the remaining steps.
Consider your need for remote access. If you need it, say no when asked: "Disallow root login remotely?".
Enjoy your new server!