Setting up a CentOS 7.7 webserver on EC2

This is my entire setup process from start to finish. Although there are lots of guides on setting up a webserver with the basic software, they don't often cover the more practical decisions like where web files should be stored and how they are updated. Hopefully this guide should be of some help, if only to show how I have chosen to go.

EC2

I have used the official " CentOS 7 (x86_64) with Updates HVM" AMI. I will leave setting up and booting an EC2 image to other guides.

http://

Initial

	
		login as: centos
		# Authenticating with public key...
		sudo yum update
		# Install your favourite text editor
		sudo yum install nano
	

Root User

	
		# Check that root login and password auth is disabled as using SSH keys
		sudo nano /etc/ssh/sshd_config
		# PermitRootLogin no
		# PasswordAuthentication no
		sudo nano /root/.ssh/authorized_keys
		# Here you will find a message telling you to login with user 'centos' rather than root, followed by the SSH key
		# Remove this whole line and paste in a secondary root SSH key
		# The remaining guide will assume you are logged in as root
		nano ~/.bashrc
		export VISUAL=nano
		export EDITOR="$VISUAL"
	

Swap Memory

	
		# Small EC2 instances come with very limited memory, without a swap file everything will work fine until you run out of memory and then suddenly grind to a halt!
		dd if=/dev/zero of=/var/swapfile bs=1M count=2048
		chmod 600 /var/swapfile
		mkswap /var/swapfile
		echo /var/swapfile swap swap sw 0 0 | sudo tee -a /etc/fstab
		swapon -a
		swapon -s
		# Filename                                Type            Size    Used    Priority
		# /var/swapfile                           file    2097148 4       -1
	

Apache

	
		sudo yum install -y httpd
		# Start and enable at boot
		sudo systemctl enabme --now httpd.service
	

PHP 7.3

	
		yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
		yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm
		yum install -y yum-utils
			yum-config-manager --enable remi-php73
		# ==== repo: remi-php73 ====
		[remi-php73]
		...
		yum install php
		php -v
		# PHP 7.3...
	

MariaDB 10.4

	
		# https://downloads.mariadb.org/mariadb/repositories/#mirror=digitalocean-lon&distro=CentOS&distro_release=centos7-amd64--centos7&version=10.0
		nano /etc/yum.repos.d/mariadb10.repo
		yum install MariaDB-server MariaDB-client
		# Set the default encoding to utf8
		nano /etc/my.cnf
		[client]
		default-character-set=utf8
		[mysqld]
		character-set-server=utf8
		collation-server = utf8_unicode_ci
		init-connect='SET NAMES utf8'
		systemctl enable --now mariadb.service
		# mysql.service is not a native service, redirecting to /sbin/chkconfig...
		# Although it looks like an error it has worked!
		# Run mariadb initial secure script to go through setting up root password etc. https://mariadb.com/blog/installing-mariadb-10-centos-7-rhel-7
		mysql_secure_installation
		# Test root login
		mysql -u root -p
	

phpMyAdmin

	
		yum-config-manager --enable remi
		yum install phpMyAdmin
		# allow remote access
		nano /etc/httpd/conf.d/phpMyAdmin.conf
		# Fill in your IP, if you do not have a static IP then you should use other methods of security, such as SSH access or htpasswd
	
	
		
			<IfModule mod_authz_core.c>
				# Apache 2.4
				Require ip XXX.XXX.XXX.XXX
			</IfModule>
		
	
	
				systemctl reload httpd.service
		# GoTo http://chrishewett.com/phpmyadmin/
	

Users

I like to use a new user for each site I host on the server. For this small site the development and production versions of the website will be hosted on the same server. This makes it necessary to do virtual sites (which I think you should always use from the beginning anyway)

	
		mkdir /home/sites/
		sudo useradd chrishewett_com -d /home/sites/chrishewett_com -m
		# To remove the need to run an FTP server to update the files I will be using SFTP so users need an ssh key adding
		sudo su -c "mkdir -p /home/sites/chrishewett_com/.ssh/" chrishewett_com
		sudo su -c "nano /home/sites/chrishewett_com/.ssh/authorized_keys" chrishewett_com
		# Paste in public key from puttygen etc.
		# Set the correct rw permissions
		sudo chmod go-w /home/sites/chrishewett_com/ /home/sites/chrishewett_com/.ssh/ /home/sites/chrishewett_com/.ssh/authorized_keys
		# Set the correct SELINUX permissions
		sudo chcon -v -R --type=ssh_home_t /home/sites/chrishewett_com/.ssh/
	

Folders

Although tempting, it is not a good idea to create the app folder structure in the root of the users directory. This contains linux user specific items e.g. .bashrc and .ssh/ which would have to be manually ignored when copying / adding to version control.

	
		# Add app folder
		sudo su -c "mkdir -p /home/sites/chrishewett_com/web/" chrishewett_com
		# set SELinux permissions
		sudo chcon -v --type=httpd_sys_content_t /home/sites/chrishewett_com/ /home/sites/chrishewett_com/web/
		# set directory permissions
		sudo chmod  755 /home/sites/chrishewett_com/ /home/sites/chrishewett_com/web/
		# add test page to site
		sudo su -c "nano /home/sites/chrishewett_com/web/index.php" chrishewett_com
		# <?= 1; //add this line to the file - if it shows '1' as the output then php is parsing
	

httpd.conf

	
		nano /etc/httpd/conf/httpd.conf
	
	
		
		<VirtualHost *:80>
			ServerName chrishewett.com
			ServerAlias www.chrishewett.com
			DocumentRoot /home/sites/chrishewett_com/web
			DirectoryIndex index.php
			<Directory /home/sites/chrishewett_com/web/>
				AddType application/x-httpd-php .php
				Options +ExecCGI +Indexes +IncludesNOEXEC +SymLinksIfOwnerMatch
				AllowOverride All
				Require all granted
				#uncomment to restrict the site to a single ip until it is ready to go live
				#<RequireAny>
				#    Require ip XXX.XXX.XXX.XXX
				#</RequireAny>
			</Directory>
		</VirtualHost>
		
	
	
		systemctl reload httpd.service
		# Add the site to your hosts file with the correct IP and browse to chrishewett.com, you should see '1'
	

SSL

See my dedicated setup instructions here.

GIT

See my dedicated setup instructions here.

Edits

  • January 2020: Removed outdated GIT push to production instruction
  • December 2019: Update MariaDB to v10.4, PHP to v7.3
  • December 2017: Update MariaDB to v10.2
  • December 2017: Removed specific dev subdomain setup, added PHP 5.6 setup, added swap memory setup

Addendum

	
		# Upgrading MariaDB 10.0 to 10.2
		mysql -uroot -p -e"SET GLOBAL innodb_fast_shutdown = 0"
		service mysql stop
		yum remove MariaDB-server MariaDB-client
		nano /etc/yum.repos.d/mariadb10.repo
		# change repo to latest version
		yum install MariaDB-server MariaDB-client
		service mysql start
		mysql_upgrade -p
		service mysql restart
	
Load Comments...