For the sake of this tutorial, we will write a simple application that reads a list of cities from a database and displays it on a web page, this way we will demonstrate a basic, but working, PHP application.
This guide assumes that you have Docker-CE already installed and at least a minimal working knowledge of docker. For that matter you may review the following tutorials:
A real life docker-based application will typically be composed of several containers. Managing these manually can easily become quite messy and cumbersome. That’s where docker-compose comes into play. It helps you to manage a number of containers through a simple yaml
configuration file.
Install docker-compose.
curl -L https://github.com/docker/compose/releases/download/1.19.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
Create a folder to hold all the necessary files of this example and then cd
into it. From now on, this is our working directory and every command will be executed inside this folder and every path will be referenced relative to it. This folder may be referenced later as WORKING_DIR
.
mkdir ~/docker
cd ~/docker
Now create three more folders.
mkdir php nginx app
The php
folder is where we will build our custom PHP image, the nginx
folder will hold the necessary files for our custom nginx image and the app
folder is where we will be putting the source code and configuration of our sample application.
In this example, we are going to use php-fpm
to connect to the Nginx webserver. We will be using the official PHP base image. However, we also need to install and enable some extensions so that we may access the database. Inside the php
folder create a file named Dockerfile
and put the following contents into it.
FROM php:7.1-fpm-alpine3.4
RUN apk update --no-cache \
&& apk add --no-cache $PHPIZE_DEPS \
&& apk add --no-cache mysql-dev \
&& docker-php-ext-install pdo pdo_mysql
Note that we are using the Alpine version of the official PHP image. Alpine is a very tiny distribution targeted towards containers by providing much smaller footprints. Also, note the use of the command docker-php-ext-install
, the official PHP image provides this command to ease the process of installing and configuring PHP extensions.
Now, let’s build this Docker image by issuing the following (inside our WORKING_DIR
):
docker build -t aklwebhost-php php/
docker-compose.yml
fileAs already mentioned, docker-compose
allows you to manage a number of containers through a simple configuration file. This configuration file is typically named docker-compose.yml
. Create this file inside the app
folder.
touch app/docker-compose.yml
Now put the following contents into this file.
version: '2'
services:
php:
image: aklwebhost-php
volumes:
- ./:/app
working_dir: /app
We will explain this syntax. First, note the first line.
version: '2'
This specifies the version of the docker-compose.yml
configuration file used. The next line specifies the services, or in other words, the containers to be provisioned.
services:
php:
image: aklwebhost-php
volumes:
- ./:/app
working_dir: /app
Note that every service has a specific key inside the services
block. The name specified here will be used to reference this specific container later. Also note that inside the php
configuration, we define the image used to run the container (this is the image we built previously). We also define a volume mapping.
volumes:
- ./:/app
This tells docker-compose
to map the current directory (./
) to the /app
directory inside the container. The last line sets the /app
folder inside the container as the working directory, which means that this is the folder where all future commands inside a container are by default executed from.
We can now orchestrate our containers.
cd ~/docker/app
docker-compose up -d
You can run the following command to make sure that the PHP container was executed:
docker ps
Still inside the app
folder, we can run any command inside a defined service container with the help of the docker-compose
command.
docker-compose exec [service] [command]
The [service]
placeholder refers to the service key. In our case, this was php
. Let’s run a command inside the container to check our PHP version.
docker-compose exec php php -v
You will see the following output.
PHP 7.1.14 (cli) (built: Feb 7 2018 00:40:45) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2018 Zend Technologies
Just like the PHP container, we need to create a custom image for the webserver. But in this case, we just need to provide a configuration for our virtual host
. Make sure you are inside our WORKING_DIR
and create a Dockerfile
inside the nginx
folder:
cd ~/docker
touch nginx/Dockerfile
Now put the following contents into this Dockerfile
:
FROM nginx:1.13.8-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf
We are using the default Nginx image based on Alpine. On this Docker file we simply copy a configuration file into our application setup. Before building this image, create a configuration file.
touch nginx/default.conf
Now populate it with this content.
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
root /app;
index index.php;
#server_name server_domain_or_IP;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri /index.php =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
Note that at the fastcgi_pass php:9000
line we are referencing the PHP container by it’s name inside the service
block of the docker-compose.yml
configuration file. Internally docker-compose
creates a network and assigns the service name as the host name to each of the services defined. We can now build the Nginx image.
docker build -t aklwebhost-nginx nginx/
docker-compose.yml
Now update the app/docker-compose.yml
file.
version: '2'
services:
php:
image: aklwebhost-php
volumes:
- ./:/app
working_dir: /app
web:
image: aklwebhost-nginx
volumes:
- ./:/app
depends_on:
- php
ports:
- 80:80
We have only added a new service. The configuration is nearly the same, except for the following.
depends_on:
- php
ports:
- 80:80
Once the Nginx container needs the PHP service to be fully initialized, we force this requirement in the depends_on
option. The ports
configuration key maps a host port to a container port, here we map the port 80
in the host to the port 80
in the container.
Now create a file called index.php
inside the app
folder and put the following in it.
<?php phpinfo();
Make sure the port 80
is accessible through your firewall and execute the following.
cd ~/docker/app
docker-compose up -d
Once again, double check that the service is up.
docker ps
Open a browser and access [aklwebhost-instance-ip]
. You may find out your AKLWEB HOST instance IP address by running the following.
hostname -I
You will see the PHP info page.
The official MySQL image allows you to configure the container through simple environment variables. This can be done with an environment
option inside the service block definition. Update the ~/docker/app/docker-compose.yml
file to the following.
version: '2'
services:
php:
image: aklwebhost-php
volumes:
- ./:/app
working_dir: /app
web:
image: aklwebhost-nginx
volumes:
- ./:/app
depends_on:
- php
ports:
- 80:80
mysql:
image: mysql:5.7.21
volumes:
- ./:/app
- dbdata:/var/lib/mysql
environment:
- MYSQL_DATABASE=world
- MYSQL_ROOT_PASSWORD=root
working_dir: /app
volumes:
dbdata:
Now we’ve defined a new service for the database. Notice the line dbdata:/var/lib/mysql
. This mounts the path on the container /var/lib/mysql
to a persistent volume managed by Docker, this way the database data persists after the container is removed. This volume needs to be defined in a top-level block as you can see in the end of the file.
Before orchestrating our new configuration, let’s download a sample MySQL database. The official MySQL documentation provides some sample databases. We will be using the well-known world database. This database provides a listing of countries and cities. To download this sample, execute the following inside our app folder.
curl -L http://downloads.mysql.com/docs/world.sql.gz -o world.sql.gz
gunzip world.sql.gz
Now lets orchestrate our containers.
docker-compose up -d
As you may have already noticed, the docker-compose up
command starts only the containers that are not already started. It checks for the differences between your docker-compose.yml
file and the current configuration of running containers.
One more time, check that the MySQL container was started.
docker ps
Now populate the world database.
docker-compose exec -T mysql mysql -uroot -proot world < world.sql
You can verify that the database was populated by selecting data directly from the database. First access the MySQL prompt inside the container.
docker-compose exec mysql mysql -uroot -proot world
In the MySQL prompt, run the following.
select * from city limit 10;
You will see a list of cities. Now quit the MySQL prompt.
mysql> exit
Now that all of the necessary containers are up and running, we can focus on our sample application. Update the app/index.php
file to the following.
<?php
$pdo = new PDO('mysql:host=mysql;dbname=world;charset=utf8', 'root', 'root');
$stmt = $pdo->prepare("
select city.Name, city.District, country.Name as Country, city.Population
from city
left join country on city.CountryCode = country.Code
order by Population desc
limit 10
");
$stmt->execute();
$cities = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>AKLWEB HOST Rocks!</title>
</head>
<body>
<h2>Most Populous Cities In The World</h2>
<table>
<thead>
<tr>
<th>Name</th>
<th>Country</th>
<th>District</th>
<th>Population</th>
</tr>
</thead>
<tbody>
<?php foreach($cities as $city): ?>
<tr>
<td><?=$city['Name']?></td>
<td><?=$city['Country']?></td>
<td><?=$city['District']?></td>
<td><?=number_format($city['Population'], 0)?></td>
</tr>
<?php endforeach ?>
</tbody>
</table>
</body>
</html>
If you access [aklwebhost-instance-ip]
in a web browser, you will see a list of the most populous cities in the world. Congratulations, you have deployed a fully working PHP application using docker.
In this tutorial, I have demonstrated step by step how to configuring a fully working PHP application. We built custom images for PHP and Nginx, and configured docker-compose to orchestrate our containers. Despite being very basic and simple, this setup reflects a real life scenario.
In this guide, we have built and tagged our images locally. For a more flexible setup, you can push these images to a docker registry. You may push to the official docker registry or even setup your own docker registry. In any case, this will allow you to build your images on one host and use them on another.
For a more detailed usage of docker-compose
, you should refer to the official documentation.
Depending on your application requirements and the PHP framework you use, you may want to add more extensions. This can easily be done by modifying the Dockerfile
used to build our custom PHP image. However, some extensions need extra dependencies to be installed in the container. You should refer to the list of extensions in the PHP official documentation to review the basic requirements of each extension.
/var/www/html
.Since CentOS 7 is a 64-bit Linux distribution, you should download the ionCube 64-bit Linux package as follows:
cd
wget https://downloads.ioncube.com/loader_downloads/ioncube_loaders_lin_x86-64.tar.gz
sudo tar -zxvf ioncube_loaders_lin_x86-64.tar.gz -C /usr/lib64/php/modules
sudo chown -R root:root /usr/lib64/php/modules/ioncube
sudo cp /usr/local/ioncube/loader-wizard.php /var/www/html
sudo systemctl restart httpd.service
Now, an ionCube Loader setup script loader-wizard.php
has been copied to the web root directory /var/www/html
. We will use that script to Configure and test ionCube Loader on the server.
Note: This tutorial assumes your Document Root is /var/www/html
. If you have your web server configured differently, you need to place loader-wizard.php
in a directory where you can access it via your web browser.
http://203.0.113.1/loader-wizard.php
to enter the ionCube Loader Wizard
interface.ionCube
Loader Wizard
interface, choose the Dedicated or VPS (server with full root ssh access)
option.AKLWEB HOST
https://www.aklwebhost.com
Next
button.Note: If your version of PHP is different from PHP 7.1, you should specify the proper ionCube Loader file in above command accordingly. Use the command php -v
to confirm the PHP version.
ionCube Loader Wizard
interface, and then use the link click here to test the Loader
to test your installation.Loader Installed Successfully
message.That’s all. Having the ionCube Loader module properly installed, you are eligible to install any app licensed with ionCube on your server now. Enjoy it.
]]>As a starter guide, this article explains how to install Apache Tomcat 8, the latest stable version of Apache Tomcat, onto an AKLWEB HOST CentOS 7 server instance.
Before further reading, you need to:
First things first, you need to update the system to the latest stable status:
sudo yum install epel-release
sudo yum update -y && sudo reboot
Use the same sudo user to log into the system after the reboot finishes.
You need to install Java SE 7.0 or later before Apache Tomcat can run properly. Here, I will install OpenJDK Runtime Environment 1.8.0 using YUM:
sudo yum install java-1.8.0-openjdk.x86_64
Now, you can confirm your installation with:
java -version
The output will resemble the following:
openjdk version "1.8.0_91"
OpenJDK Runtime Environment (build 1.8.0_91-b14)
OpenJDK 64-Bit Server VM (build 25.91-b14, mixed mode)
For security purposes, you need to create a dedicated non-root user “tomcat” who belongs to the “tomcat” group:
sudo groupadd tomcat
sudo mkdir /opt/tomcat
sudo useradd -s /bin/nologin -g tomcat -d /opt/tomcat tomcat
In this fashion, you created a user “tomcat” who belongs to the group “tomcat”. You cannot use this user account to log into the system. The home directory is /opt/tomcat
, which is where the Apache Tomcat program will reside.
You can always find the latest stable version of Apache Tomcat 8 from its official download page, which is 8.0.33 as of writing.
Under the “Binary Distributions” section and then the “Core” list, use the link pointing to the “tar.gz” archive to compose a wget command:
cd ~
wget http://www-us.apache.org/dist/tomcat/tomcat-8/v8.0.33/bin/apache-tomcat-8.0.33.tar.gz
sudo tar -zxvf apache-tomcat-8.0.33.tar.gz -C /opt/tomcat --strip-components=1
Before you can run Apache Tomcat, you need to setup proper permissions for several directories:
cd /opt/tomcat
sudo chgrp -R tomcat conf
sudo chmod g+rwx conf
sudo chmod g+r conf/*
sudo chown -R tomcat logs/ temp/ webapps/ work/
sudo chgrp -R tomcat bin
sudo chgrp -R tomcat lib
sudo chmod g+rwx bin
sudo chmod g+r bin/*
As a matter of convenience, you should setup a Systemd unit file for Apache Tomcat:
sudo vi /etc/systemd/system/tomcat.service
Populate the file with:
[Unit]
Description=Apache Tomcat Web Application Container
After=syslog.target network.target
[Service]
Type=forking
Environment=JAVA_HOME=/usr/lib/jvm/jre
Environment=CATALINA_PID=/opt/tomcat/temp/tomcat.pid
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
Environment='CATALINA_OPTS=-Xms512M -Xmx1024M -server -XX:+UseParallelGC'
Environment='JAVA_OPTS=-Djava.awt.headless=true -Djava.security.egd=file:/dev/./urandom'
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/bin/kill -15 $MAINPID
User=tomcat
Group=tomcat
[Install]
WantedBy=multi-user.target
Save and quit:
:wq
For security purposes, you should install haveged as well:
sudo yum install haveged
sudo systemctl start haveged.service
sudo systemctl enable haveged.service
Now, start the Apache Tomcat service and set it run on system boot:
sudo systemctl start tomcat.service
sudo systemctl enable tomcat.service
In order to test Apache Tomcat in a web browser, you need to modify the firewall rules:
sudo firewall-cmd --zone=public --permanent --add-port=8080/tcp
sudo firewall-cmd --reload
Then, you can test your installation of Apache Tomcat by visiting the following URL from a web browser:
http://[your-Vultr-server-IP]:8080
If nothing goes wrong, you will see the default Apache Tomcat front page.
In order to use the “Manager App” and the “Host manager” in the Apache Tomcat web interface, you need to create an admin user for your Apache Tomcat server:
sudo vi /opt/tomcat/conf/tomcat-users.xml
Within the </tomcat-users ...>...</tomcat-users>
segment, insert a line to define a admin user:
<user username="yourusername" password="yourpassword" roles="manager-gui,admin-gui"/>
Remember to replace “yourusername” and “yourpassword” with your own ones, the less common the better.
Save and quit:
:wq
Restart Apache Tomcat to put your modifications into effect:
sudo systemctl restart tomcat.service
Refresh the Apache Tomcat front page from your web browser. Log in the “Manager App” and the “Host manager” using the credentials you had setup earlier.
The Apache Tomcat setup is complete. You can now use it to deploy your own applications.
]]>First, update the list of packages:
sudo apt-get update -y
Next, install the updates:
sudo apt-get upgrade -y
Ubuntu ships with sudo
installed, so the first step will be to simply add a new user:
adduser <username>
You will be asked to set information about this user:
Enter the new value, or press ENTER for the default
Full Name []: Test User
Room Number []: 01
Work Phone []: 5555555
Home Phone []: 5555555
Other []:
You can fill these fields in, or press ENTER to leave them default. After this press Y and then ENTER to verify that the information is correct.
Next, add the new user to the sudo
group:
usermod -aG sudo <username>
You can now log out, and log back in as your new user. To test that the user was added correctly, use the following command once you have logged back in as the new user:
ls -la /root
You will receive the following notice:
ls: cannot open directory '/root': Permission denied
When you append the previous command with sudo
, you will be asked for your password and receive a list of the /root
directory:
sudo ls -la /root
You can now move onto updating Ubuntu.
You can use Apache or Nginx as your webserver.
To install and start Apache:
sudo apt-get install apache2 -y
sudo systemctl start apache2.service
To install and start Nginx:
sudo apt-get install nginx -y
sudo systemctl start nginx.service
PHP 7.2 is included in the default Ubuntu repository for 18.04. You can list each of the available PHP 7.2 packages with the following command:
apt-cache pkgnames | grep php7.2
Next, install the packages that your application requires:
sudo apt-get install php -y
sudo apt-get install php-{bcmath,bz2,intl,gd,mbstring,mysql,zip,fpm} -y
Finally, restart your webserver to allow PHP to run.
For Apache, use the following:
systemctl restart apache2.service
Alternatively, use the following for Nginx:
systemctl restart nginx.service
Confirm the PHP version:
php -v
The output will resemble the following:
PHP 7.2.10-0ubuntu0.18.04.1 (cli) (built: Sep 13 2018 13:45:02) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.10-0ubuntu0.18.04.1, Copyright (c) 1999-2018, by Zend Technologies
The main config file of PHP 7.2 will be saved as /etc/php/7.2/fpm/php.ini
. You can use the vi
text editor to modify relevant settings in that file:
sudo vi /etc/php/7.2/fpm/php.ini
Note: Remember to restart Apache or Nginx if you make any changes to that file or any other PHP config files.
You have successfully set up PHP 7.2 on Ubuntu 18.04 to work with either Nginx or Apache. You are now ready to customize your configurations and deploy your apps.
]]>Running an HTTP server will allow you to host a web site and put up files for download. Apache is open-source software and one of the top HTTP servers available.
If you just want to get a Web server running quickly, you can install one of the ready-made packages such as XAMPP which include Apache, PHP, MySQL, and an easy to control interface. Even when using such a package, there are no constraints when it comes to modifying the server configuration. However, for an advanced setup, you may want to manually install your web server.
Download the Windows MSI installer from the Apache download page and fill in the details. Choose “All Users” and “Service” mode. You will most likely want to leave the port at 80, but you can change it. You simply need to make sure that this port is opened in the Windows Firewall.
After running the installer, the Apache Monitor will have been installed. You can control the status of Apache services from this application – using start, stop, and restart. You can also do so from Windows’ services.msc
. By now, you should be able to contact your server on http://127.0.0.1
and see the default Apache page.
You can add, edit, and remove web files from your web server by changing the htdocs
folder within the Apache
folder. This is the default location for web files. Alternatively, you could make use of virtual hosts in order to use other directories, or set up sub-domains.
Apache has two important configuration files: .htaccess
, which applies on a directory-by-directory basis within the web files, and httpd.conf
inside Apache’s conf
folder, which addresses the main configuration.
PHP allows you to make use of PHP scripts on your web server and display the results to users.
Download the Windows version of PHP from PHP Windows downloads. Download the proper version and then extract the zip file to c:\php
.
Next, edit Apache’s httpd.conf
to include the following:
LoadModule php5_module "c:/php/php5apache2_2.dll"
AddType application/x-httpd-php .php
PHPIniDir "C:/php"
You should then restart the Apache server. In order to test PHP, create a test.php
file in your htdocs
folder with the following content:
<?php phpinfo() ?>
… then check the output at http://127.0.0.1/test.php
.
Your Windows/Apache setup is complete.
]]>Installing IIS is incredibly simple; in fact, the only thing you have to do is enable it. To enable IIS, go to “Server Manager -> Manage -> Add Roles and Features”. Select where you want to install IIS. In the “Select server roles” screen, enable “Web Server (IIS)”. Click “Next” to finish the install.
Using IIS with multiple sites is very easy. Let’s go ahead and add our first site! What you need to do is open the “IIS Manager”. This application is where IIS and all sites are managed. You will see all of your servers in the sidebar. Expand your server by double-clicking on its name, then expand “Sites”. All sites hosted by IIS are shown here.
In order to add a new site, simply right-click on the screen that appeared and select “Add Website…”. Here you will be asked for a number of things: the site name, application pool, physical path, binding, and host name.
The site name can be anything you want. It’s up to you what you put there. If you just want to host a website, don’t worry about the application pool; you won’t need to change it.
The physical path is where the website files are stored. The path for this should be: C:\inetpub\wwwroot
. If you host multiple websites on your IIS server, then add a folder for each website in the wwwroot
folder.
For the binding, select if you’re going to use either http://
or https://
for your website. The IP address should be the external IP of your server. IIS will detect that automatically. The port specified is the port that you want to host your website on; usually, this is port 80.
The host name is the domain name for your website. Say that you want to host “http://example.com”, you put “example.com” there.
With IIS, you can easily disable websites by “stopping” them. This can be done by going to the website, under “Sites -> Website Name”, then clicking “Stop” in the sidebar.
You can “Start” or “Restart” a website in the same fashion.
You can upload files from your computer to install a web application. If you want to use a CMS (such as WordPress or Joomla!), then installing it with the Web Platform Installer would be logical. You can compare the Web Platform Installer with Softaculous. Web Platform Installer also allows you to install other applications, such as PHP and SQL Server.
To install an application with the Web Platform Installer, find “Deploy” in the sidebar. Then click “Install Applications From Gallery”. You will now be able to search for applications and easily install them by clicking on the “Add” or “Install” button.
You may only want certain people to have permission to access your website. For this, you can use HTTP authentication. The most popular type of HTTP authentication is “Basic Authentication”.
Authentication can be enabled by clicking “Authentication” under “IIS”. When enabling basic authentication, users with an account on your server will be able to access your website. Active Directory accounts can be used as well.
By default, anonymous authentication is enabled. This means that authentication is not required.
If you have an application such as WordPress or Joomla installed, they will probably send users some emails. For this to work, we need to setup SMTP. To install SMTP with IIS, go to “Server Manager -> Manage -> Add Roles and Features”. You can skip selecting the roles, instead you’re going to tick “SMTP server” when it asks you to select the features you want to install.
The icon “SMTP E-mail” will now show up in IIS under “ASP.NET”. Here you can set the email address that emails are sent from.
You probably want to enable compression. Compression will make your website faster. To enable compression, simply click “Compression” under “IIS”.
If you’re used to using the .htaccess
, then you’ll need to learn how to use the web.config
. The web.config
file is basically the equivalent of .htaccess
. It provides a lot of the same features, but has a different format.
In order to enable SSL, you’ll need an SSL certificate.
The first thing that we have to do is change the binding of the site from http://
to https://
.
Click on your server name in the sidebar and click on “Server Certificates” under “IIS”. In the sidebar, you will see the option “Import…”. Use this to import your SSL certificate.
When you have imported your SSL certificate successfully, right-click on your site name in the sidebar and click “Edit Bindings…”. We’re going to add a binding. Click “Add…”. Instead of http://
, choose https://
. The IP address and host name will be the same; however the port will be set to 443. When you set the site to use https://
, an option called “SSL certificate” will appear. Select your SSL certificate here. Click “OK”. When you see the new binding appear, click “Close”. Your website now uses SSL.
NGINX is a “reverse proxy first, web server second”. It is a popular and growing alternative to Apache, offering greater flexibility and better performance in many instances. In this tutorial, we will be using it as our web server.
Fire up your favorite SSH client and login to your server. For Windows users, “PuTTY” is a free and lightweight SSH client. Linux and Mac users can use the terminal included by default with their operating system. For this tutorial, we will assume that you are logged in to your server as the “root” user.
For starters, let’s just make sure everything is up to date. Type the following to check for and then install updates.
apt-get update && apt-get upgrade
We’ll be editing our configuration files in vim. Vim is not installed by default, so let’s install it!
apt-get install vim
Now it’s time to install NGINX. We’ll want to install the latest version of NGINX from the official NGINX Debian repository.
wget http://nginx.org/keys/nginx_signing.key
apt-key add nginx_signing.key
echo 'deb http://nginx.org/packages/debian/ jessie nginx' >> /etc/apt/sources.list
echo 'deb-src http://nginx.org/packages/debian/ jessie nginx' >> /etc/apt/sources.list
apt-get update && apt-get install nginx
Now we need to tweak the NGINX configuration some. Navigate to the configuration directory.
cd /etc/nginx
Use the arrow keys to navigate the text document. To begin making edits, press the “insert” button on your keyboard. If your keyboard doesn’t have an insert button, then press the “i” key. Towards the bottom of vim you’ll notice it now says “INSERT”. Insert mode will let you delete via backspace or insert new characters by typing them.
Let’s open up our nginx.conf
and poke around:
vi nginx.conf
Let’s change the default user, check the number of worker processes, and turn off the access log.
The directives “user” and “worker_processes” are near the top. Try the values below:
Note that you’ll want to set “worker_processes” to the number of CPU cores available on your server. In this example, we have 1, which is the NGINX default.
user www-data;
worker_processes 1;
We’ll also want to disable the access log, for sake of improving I/O performance. Navigate downwards with the arrow keys until you find “access_log”. Modify it to the following:
access_log off;
And lastly, we’ll set the “client_max_body_size” to correspond with some changes made to PHP later on. Let’s save the trouble and do it now. Add just below “access_log”:
client_max_body_size 12m;
When you’ve finished up editing, press “Esc” on your keyboard. Vim will no longer say “INSERT” towards the bottom of the file.
To save our changes and quit vim, press the following key sequence:
SHIFT :(colon)
wq
Press "Enter"
The above vim kung fu will write your changes to disk and exit vim, dropping you back into the bash shell.
Now, we need to make a site-specific configuration for our example! We’ll also delete the other example configurations. Try the following:
cd conf.d
rm example_ssl.conf default.conf
vi my_site.conf
We’ll make a short and simple www.conf
based loosely on the default NGINX configuration, but with a few tweaks. Press insert and you can copy/paste the below example.
Don’t forget to edit the “root” directive to point to the root directory of your website, and “server_name” to correspond to your domain.
server {
listen 80;
root /path/to/your/website;
index index.php index.html index.htm;
server_name mydomainname.com www.mydomainname.com;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
}
Now we’re done with the NGINX configuration section of this tutorial. We’ll restart NGINX in a little bit, right after we install PHP.
PHP-FPM is the PHP Fast Process Manager. It’s required when using NGINX, because unlike Apache, NGINX doesn’t run PHP as a module. This was done to reduce NGINX’s memory footprint. Remember that part about NGINX being a reverse proxy first and foremost? Here’s where that comes into play; PHP requests sent to NGINX are fed to PHP-FPM to do the heavy lifting.
Let’s install PHP-FPM.
apt-get install php5-fpm php5-mysqlnd
Note that depending on what your PHP scripts require, you may have to install other PHP modules not included by default. Popular ones are
php5-gd
andphp5-mcrypt
. You can install these with the following command.
apt-get install php5-module_name_here
Now that we’ve got PHP-FPM installed, we’ll want to make a few quick edits to enhance security and functionality.
cd /etc/php5/fpm
vi php.ini
Time for another quick vim lesson! The php.ini
file is absolutely huge. Looking for a few key values will take all day. So since we know what we’re looking for, we’ll search. Type the following:
/upload_max_filesize
This, by default, is set to 2 megabytes. If you want to allow users to upload files to your PHP applications greater than 2 megabytes, you will need to change this. 10M is probably a safe bet for now, but higher values are also acceptable. This setting will vary among configurations. For sake of tutorial:
upload_max_filesize = 10M
One more glaring security flaw. Scroll down a little further or search. We need to turn “allow_url_fopen” to “Off”. This will prevent PHP from running PHP files hosted REMOTELY, otherwise known as RFI (Remote File Inclusion). Many servers are hacked this way.
allow_url_fopen = Off
And because we changed “upload_max_filesize”, we now have to change “post_max_size”. This value should be a little bigger than “upload_max_filesize”, because we have to take into account the overhead associated with our requests processed by PHP.
Let’s search one more time with “/post_max_size”.
post_max_size = 12M
Note that you’ll have to go back to your NGINX configuration and edit “client_max_body_size” if you decide to go with larger values than these examples for your PHP file sizes.
That’s about it for now. Make sure you aren’t in edit mode by pressing “Esc”. Save and exit vim.
SHIFT :(colon)
wq
Press 'Enter'
PHP-FPM setup is complete.
Even in a world continuously moving towards NoSQL or MongoDB, some of us still find it easier to just stick with MySQL. This is especially true for many web applications. Fortunately, there now exist a number of “drop-in” replacements for Oracle MySQL. Debian 8 now includes the ever popular MariaDB. MariaDB is a fork of Oracle MySQL based on version 5.5. MariaDB, for all intents and purposes, calls this MariaDB 10. It is considered a FULL replacement for Oracle MySQL. Think of it as MySQL at heart, sans the Oracle branding, and some new features.
apt-get install mariadb-server
IMPORTANT: You absolutely, positively, need to pick a strong root password for MariaDB. Save it somewhere secure. You’ll need to enter it twice during the MariaDB installation.
Let’s tweak the MariaDB configuration slightly. We’re going to disable MariaDB listening via the network interface. Instead, as with PHP-FPM earlier, we’ll stick only to a UNIX socket. Most PHP applications should support connecting to the database server via a UNIX socket instead of the local loopback interface.
cd /etc/mysql
vi my.cnf
Look for “bind-address = 127.0.0.1”. Comment that line out. Above or below it add “skip-networking”.
#bind-address = 127.0.0.1
skip-networking
We’re done with MariaDB! Eventually, you may want to tweak your MariaDB configuration depending on if you’ll be using primarily the MyISAM or InnoDB storage engines, but also for the number of CPU cores and RAM available to your server. The defaults will get us up and running in the mean time.
Let’s restart each of the services for which configuration files were modified in this tutorial.
systemctl restart nginx.service
systemctl restart php5-fpm.service
systemctl restart mysql.service
That’s it – we’re all done. At this point, you have a fully functional LNMP ( LEMP ) server online!
This guide was to serve as a general rule of thumb for getting started with with the above services with minimal tweaking. For further information, read the documentation for the above packages. While this example setup should work well right “out of the box”, adjustments can, and most likely will need to be made to better suit your needs.
Recommended areas to research:
Virtual hosts allow the administrator to use one server to host many domains using a single IP. This is useful for anyone who wants to host more than one website on the same VPS, never indicating that the same server is also hosting other sites. This process can be repeated without limit, depending on the load that your server can handle.
In order to work through these steps, you will need to have:
My configuration will make virtual hosts for test1.com
and test2.com
. You should substitute these with your own domains.
The document root will be set to individual directories under the /var/www
folder. Create a directory here for both of the virtual hosts, like this:
sudo mkdir /var/www/test1
sudo mkdir /var/www/test2
The directories that you have created are owned by the root user. You have to change the ownership for the regular user to be able to modify files. $USER
is the user in which you are currently logged in.
sudo chown -R $USER:$USER /var/www/test1
sudo chown -R $USER:$USER /var/www/test2
You should also modify permissions to the general web directory and all of the files and folders within it.
sudo chmod -R 755 /var/www
Make an index.html
page for each site.
nano /var/www/test1/index.html
In this HTML file, you can place simple content just to indicate that your your configuration works. For example, my file looks like this.
<html>
<head>
<title>test1</title>
</head>
<body>
<h1>test1.com virtual host !</h1>
</body>
</html>
Save and close the file when you are finished.
Now copy this file to the second site.
cp /var/www/test1/index.html /var/www/test2/index.html
You can then open and modify it.
nano /var/www/test2/index.html
<html>
<head>
<title>test2</title>
</head>
<body>
<h1>test2.com virtual host !</h1>
</body>
</html>
Save and close this file when you are finished.
Virtual host files specify the configuration of our virtual hosts and dictate how the Apache web server will respond to different domain requests.
Apache comes with a default virtual host file, 000-default.conf
. Copy this file and modify it for the first domain.
sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/test1.conf
sudo nano /etc/apache2/sites-available/test1.conf
The file will look like this (without comments):
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
</VirtualHost>
Change the ServerAdmin
directive to the email that the site administrator can receive emails through. Then, you need to add three directives:
The virtual host file should resemble the following.
<VirtualHost *:80>
ServerAdmin admin@test1.com
ServerName test1.com
ServerAlias www.test1.com
DocumentRoot /var/www/test1
</VirtualHost>
Save and close the file.
You can do the same with the second domain.
sudo cp /etc/apache2/sites-available/test1.conf /etc/apache2/sites-available/test2.conf
sudo nano /etc/apache2/sites-available/test2.conf
You now need to modify it to reference your second domain.
<VirtualHost *:80>
ServerAdmin admin@test2.com
ServerName test2.com
ServerAlias www.test2.com
DocumentRoot /var/www/test2
</VirtualHost>
Save and close the file when you are finished.
The a2ensite
tool can be used to enable each of our sites like this:
sudo a2ensite test1.conf
sudo a2ensite test2.conf
When you are finished, you need to restart Apache to make these changes take effect:
sudo service apache2 restart
If you receive this message:
*Restarting web server apache2
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1. Set >the 'ServerName' directive globally to suppress this message
… don’t worry, that does not affect our sites.
Now that you have your virtual hosts configured, you can test them by going to the domains that you configured in your web browser:
If both of these sites work, you’ve successfully configured two virtual hosts on the same server.
]]>Here, I will explain how to install Lighttpd with PHP 5 (PHP5-FPM) and MySQL on Ubuntu 14.04.
Install Lighttpd with the following commands.
sudo apt-get update
sudo apt-get install lighttpd
This will start Lighttpd once the install finishes. You can test the status of the server by accessing the IP address of your VPS in a web browser. Upon success, you will see the Lighttp welcome page.
If the page does not load, you can force-restart the service.
sudo service lighttpd start
Install PHP5 with the following command.
sudo apt-get install php5-cgi php5-mysql
Note that the “php5-mysql” package is needed to use MySQL server with PHP.
Enable PHP5 CGI modules in Lighttpd with the following commands.
sudo lighty-enable-mod fastcgi
sudo lighty-enable-mod fastcgi-php
After enabling the modules, you need to restart the Lighttpd service.
sudo service lighttpd force-reload
Test the PHP integration with Lighttpd. To do this, create a test file inside the /var/www/
folder.
nano /var/www/info.php
Paste the following content into this file.
<?php phpinfo(); ?>
Now, access http://[SERVER_IP]/info.php
in your web browser. If the configuration was setup properly, you will see the PHP info page.
Run the following command to install MySQL server. During the installation, you need to give the administrator password for MySQL root.
sudo apt-get install mysql-server
Once the install finishes, install a MySQL database.
mysql_install_db
Additionally, you can use the secure MySQL installation by running the following command.
mysql_secure_installation
]]>These steps were tested on Ubuntu server.
Update the server to the latest packages/updates.
apt-get update
Install lighttpd and PHP.
sudo apt-get install lighttpd php5-cgi
Enable the fastcgi module and fastcgi PHP support.
sudo lighty-enable-mod fastcgi
sudo lighty-enable-mod fastcgi-php
Restart your lighttpd service to apply the fastcgi changes.
sudo service lighttpd force-reload
On your server, edit the /etc/lighttpd/lighttpd.conf
file. Some admins prefer uploading a configuration file over FTP instead of SSH editing.
vi /etc/lighttpd/lighttpd.conf
By default, the document root is /var/www
. You may prefer to host your sites out of a different folder, such as /var/websites
.
#change
server.document-root = "/var/www"
#to
server.document-root = "/var/websites/root"
Note that lighttpd disables the directory listing by default.
Add the following to lighttpd.conf
to host a domain or subdomain.
$HTTP["host"] =~ "^mydomain\.com$" {
server.document-root = "/var/websites/domain"
}
#or
$HTTP["host"] =~ "^sub\.mydomain\.com$" {
server.document-root = "/var/websites/domain/sub"
}
Bare in mind that the $HTTP line contains a regular expression between quotation marks.
If you would like to disable directory listings for virtual hosts, use the following example.
$HTTP["host"] =~ "^sub\.mydomain\.com$" {
server.document-root = "/var/websites/domain/sub"
dir-listing.activate = "disable"
}
Once you have finished adding virtual hosts, save the lighttpd.conf
file and restart the lighttpd service.
service lighttpd restart
At this point, lighttpd is serving your PHP pages. Enjoy!
]]>