This tutorial is out of date and no longer maintained.
Note: This tutorial is out of date and unmaintained. Updated versions are available for Ubuntu 18.04 and Ubuntu 16.04
Both nginx and apache are powerful and effective servers. Apache currently reigns as the #1 server for websites and since its public release in 2006, nginx has taken the world by storm and is now the #2 server for active sites. The reasons for each respective server’s popularity are clear: apache’s power and nginx’s speed are well known. However, both servers do have drawbacks—apache is hard on server memory, while nginx (great at static files) needs the help of php-fpm or similar modules for dynamic content.
However, one can combine the two web servers to great effect, with nginx as static web server front and apache processing the back end.
To perform the steps in this tutorial, you will need to have sudo privileges on your virtual private server.
To create a user with sudo privileges, go through the third and fourth steps of the initial ubuntu server setup tutorial
To start off, we need to install and configure nginx which will serve the front end of our site.
Let’s download it from apt-get:
sudo apt-get install nginx
Once it has downloaded, you can go ahead and configure the virtual host to run on the front end.
There are a few changes we need to make in the configuration.
Open up the nginx configuration.
sudo nano /etc/nginx/sites-available/example
The following configuration will set you up to use nginx as the front end server. It is very similar to the default set up, and the details are under the configuration.
server { listen 80; root /var/www/; index index.php index.html index.htm; server_name example.com; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; proxy_pass http://127.0.0.1:8080; } location ~ /\.ht { deny all; } }
The following changes were implemented in the configuration:
This configuration sets up a system where all extensions with a php ending are rerouted to the apache backend which will run on port 8080.
Activate the virtual host.
sudo ln -s /etc/nginx/sites-available/example /etc/nginx/sites-enabled/example
Additionally, delete the default nginx server block.
sudo rm /etc/nginx/sites-enabled/default
The next step is to install and configure apache.
With nginx taken care of, it’s time to install our backend, apache.
sudo apt-get install apache2
Since nginx is still not turned on, Apache will start running on port 80.
We need to configure apache to take over the backend, which as we told nginx, will be running on port 8080. Open up the apache ports file to start setting apache on the correct port:
sudo nano /etc/apache2/ports.conf
Find and change the following lines to have apache running on port 8080, accessible only from the localhost:
NameVirtualHost 127.0.0.1:8080 Listen 127.0.0.1:8080
Save and Exit.
Subsequently, open up a new virtual host file, copying the layout from the default apache file:
sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/example
sudo nano /etc/apache2/sites-available/example
The main issue that needs to be addressed here is that the virtual host needs to be, once again, running on port 8080 (instead of the default 80 given to nginx).
The line should look like this:
<VirtualHost 127.0.0.1:8080>
Make sure your Document Root is correct. Save and exit the file and activate that virtual host:
sudo a2ensite example
Before we start testing anything out, we need to equip apache with php. Go ahead and install it now:
sudo apt-get install php5
Restart both servers to make the changes effective:
sudo service apache2 restart
sudo service nginx restart
We have set up the VPS with nginx running on the front end of our site and apache processing php on the back end. Loading our domain will take us to our site’s default page.
We can check that information is being routed to apache is working by running a common php script.
Go ahead and create the php.info file:
sudo nano /var/www/info.php
Paste the following lines into that file:
<? phpinfo( ); ?>
Save and exit.
Visiting your domain/info.php should show you php info screen, and you’ll be able to see that this was handled by apache. (screenshot here)
Finally, you can see which ports are open and which application is on each one by typing in this command.
sudo netstat -plunt
Configuring nginx and Apache together can be a great boost to a server, and this was just a brief overview. If you have any specific questions about the configuring the two together, feel free to post your questions in our Q&A Forum and we’ll be happy to answer them.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Very, very good!
setup everything following the steps but only loads default nginx page from /usr/share/nginx/www instead from the /var/www
How does one get this working?
After updating your root path did you give nginx a restart?
It may also be that the default nginx page is showing up. You can disable the default nginx server block by removing it from the sites-enabled folder. I have added this step to the tutorial in “Configure nginx” step.
Hi, in the example nginx.conf, in the PHP section, you have written “127.0.0.1:9000” in one place and “127.0.0.1:8080” in another. Is this intentional?
Hi Jason—thanks for catching that. It was a typo that originated because the configuration was based on the the default configs, and I had not removed that comment. It is gone now!
Thanks!
It’s awesome Etel, I’m trying Nginx+Apache on an Ubuntu 12.04, and found that the setting works right-away for most pages. However, the cgi calls seems to stuck on Nginx. I’ve tried adding the following, location ~ .cgi$ { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Host $host; proxy_pass http://127.0.0.1:8080; } but no luck. Any comments?
jessehaung, I think that question might be outside the scope of this article. (I don’t know the answer off hand just by looking at your syntax).
Hi Jesse,
Given that the request is being redirected back to your Apache server at http://127.0.0.1:8080 you should attempt to make that request directly to the Apache server to see if its processing correctly:
telnet 127.0.0.1 8080
GET /path/to/script.php HTTP/1.1 Host: domain.com
Then you will see if Apache is returning any kind of weird behavior. Since nginx is just serving as a reverse proxy and it isn’t returning its own error it may be breaking down there.
So you would want to test each piece individually to narrow down where you may be running into an issue.
This worked perfectly. Thank You!