Skip to content

Instantly share code, notes, and snippets.

@rsuper
Last active February 5, 2019 09:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rsuper/1a7c47e57141b49652a19ac978f68959 to your computer and use it in GitHub Desktop.
Save rsuper/1a7c47e57141b49652a19ac978f68959 to your computer and use it in GitHub Desktop.
AWS install PHP FPM 7.2 with nginx

Server installation

Short manual on how to configure the server, so all instances are the same:

  • PHP FPM
  • nginx
  • SSL configuration
  • port configuration
  • Uses the public folder for Symfony projects, modify paths to suit your needs
  • MySQL

First, update the repo

sudo yum update -y

PHP-FPM

Install PHP-FPM 7.2

sudo yum install php72-fpm -y

Edit PHP FPM config
File is located at /etc/php-fpm.d/www.conf. (Use sudo)
Everything is a symlink, so it doesn't really matter which www.conf file you edit.

[www]
user = apache
group = apache
listen = 127.0.0.1:9001
listen.allowed_clients = 127.0.0.1
pm = dynamic
pm.max_children = 16
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.process_idle_timeout = 30s;
pm.max_requests = 100

Webserver

Install nginx

sudo yum install nginx -y

Modify nginx config
File is located at /etc/nginx/nginx.conf. (Use sudo)
Basically the server node has been removed and a denying server added to block direct IP access on port 80. Also, some headers have been added and some have been removed.

nginx.conf:

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
  worker_connections 1024;
}

http {
    server_tokens off;
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Frame-Options SAMEORIGIN;
    
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    
    access_log  /var/log/nginx/access.log  main;
    
    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;
    
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
    
    # This will be the default server
    server {
      return      444;
    }
    
    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;
    
    index   index.html index.htm index.php;
}

nginx vhosts

VHost and PHP processing

PHP processing

This can be done by creating a reusable config file (in case of multiple vhosts). Alternative is to configure a section per vhost.

Example
File located at /etc/nginx/default.d/php.conf. (Use sudo)
Again, this is a symlink to the versioned filename in the same directory. It doesn't really matter what file you edit.

index index.php index.html index.htm;

location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9001;
    fastcgi_split_path_info ^(.+\.php)(/.*)$;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;

    fastcgi_buffers 8 16k;
    fastcgi_buffer_size 32k;
    fastcgi_connect_timeout 60s;
    fastcgi_send_timeout 600s;
    fastcgi_read_timeout 600s;

    internal;
}

Edit php.ini
File is located at /etc/php.ini. (Use sudo)
This file is a symlink.

Disable PHP exposure in the response headers:

[PHP]
expose_php = Off

[Date]
date.timezone = Europe/Amsterdam

Creating a vhost

Filename: /etc/nginx/conf.d/{domain}.conf

For port 80:

server {
    root /var/www/{domain}/public;
    server_name {domain};
    listen 80;

    include /etc/nginx/default.d/php.conf;

    # This is for those who use .htaccess in their projects
    location ~ /\.ht {
        deny all;
    }
    
    location / {
        try_files $uri /index.php$is_args$args;
    }
}

For SSL:

server {
    root /var/www/{domain}/public;
    server_name {domain};
    listen 80;
    listen 443 ssl http2;

    ssl_certificate      /etc/ssl/certs/{domain}-bundle.crt;
    ssl_certificate_key  /etc/ssl/certs/{keyfile}.key;
    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_protocols        TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers          'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS';
    ssl_prefer_server_ciphers on;

    include /etc/nginx/default.d/php.conf;

    location ~ /\.ht {
        deny all;
    }
    
    location / {
        try_files $uri /index.php$is_args$args;
    }
}

Make sure the certificate chain file is valid and exists. The ssl_certificate file should contain (in order):

  1. Domain certificate
  2. Intermediate certificate
  3. Root certificate

Create the web path

Create a domain path, with public folder:

mkdir -p /var/www/{domain}/public

Add yourself to the apache user group, this prevents file permission conflicts:

sudo usermod -a -G apache ec2-user

Update the permissions for the www folder:

sudo chown -R ec2-user:apache /var/www

Enable and start FPM and nginx

Run nginx -t to see if there are no configuration errors.
Then:

sudo chkconfig nginx on

sudo chkconfig php-fpm on

sudo service php-fpm start

sudo service nginx start

Missing packages

PDO is probably missing, install it:

sudo yum -y install php72-pdo

In case you get an error "could not find driver", install mysql for PHP:

sudo yum -y install php72-mysqlnd

MySQL

It is better to use a separate RDS server, but if you want to save costs or have a simple project, installing MySQL works just fine. Be sure to make backups though!

sudo yum install -y mysql57-server

Autostart and launch the MySQL server:

sudo chkconfig mysqld on

sudo service mysqld start

Run the secure installation:

sudo mysql_secure_installation

Install Composer

See the Composer website for the latest version.
Copy the lines that look like the ones below. Note that below code will nog work because the file hash is different.

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('SHA384', 'composer-setup.php') === '544e09ee996cdf60ece3804abc52599c22b1f40f4323403c44d44fdfdd586475ca9813a858088ffbc1f233e9b180f061') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

To install it globally, do the following

sudo mv composer.phar /usr/local/bin/composer

More config

https://gist.github.com/plentz/6737338

Extra: MySQL configuration

Creating a user with database and allowing remote login:

CREATE USER '<username>'@'%' IDENTIFIED BY '<password>';
CREATE DATABASE IF NOT EXISTS <database-name>;
GRANT ALL ON <database-name>.* TO '<username>'@'%';
FLUSH PRIVILEGES;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment