July 19, 2012

Advanced

How To Install Wordpress, Nginx, PHP, and Varnish on Ubuntu 12.04

About Varnish


Varnish is an HTTP accelerator and a useful tool for speeding up a server, especially during a times when there is high traffic to a site. It works by redirecting visitors to static pages whenever possible and only drawing on the server itself if there is a need for an active process.

Setup


Before you start to work through this tutorial, there are a couple prerequisites. You will need a user with root privileges, the LEMP stack, and Wordpress already installed on your server.

You can run through a few of the previous tutorials to make sure that your server is up to speed:

  1. To create a user with sudo privileges, go through the third and fourth steps of the Initial Ubuntu Server Setup

  2. To install LEMP (linux, nginx, mysql, and php) stack, follow the steps in the LEMP Installation Tutorial.

  3. To install wordpress on your server, check out the instructions in the Wordpress Installation Tutorial

Step One—Install Varnish


Once you have all of the prerequisites needed to configure varnish with wordpress, you should go ahead and start the process to install Varnish.

The varnish site recommends installing the varnish package through their repository.

You can start that process by grabbing the repository:
sudo curl http://repo.varnish-cache.org/debian/GPG-key.txt | sudo apt-key add -

The next step is to add the repository to the list of apt sources. Go ahead and open up the file.
sudo nano /etc/apt/sources.list

Once inside the file, add the varnish repository to the list of sources.
deb http://repo.varnish-cache.org/ubuntu/ lucid varnish-3.0

Save and exit. Finally, update apt-get and install varnish.
sudo apt-get update
sudo apt-get install varnish libvarnish-dev

Step Two—Configure Varnish


Once you have both nginx and varnish installed, you can start to configure them to ease the load on your virtual private server.

Varnish will serve the content on port 80, while fetching it from nginx which will run on port 8080.

Go ahead and start setting that up by opening the /etc/default/varnish file:
sudo nano /etc/default/varnish

Find the lines under “DAEMON_OPTS”— in the Alternative 2 section, and change the port number by "-a" to 80. The configuration should match the following code:
 DAEMON_OPTS="-a :80 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -S /etc/varnish/secret \
             -s malloc,256m"

That's the only change you need to make there. Save and exit out of that file and open up the default.vcl file:
sudo nano /etc/varnish/default.vcl

This file tells varnish where to look for the webserver content. It should already be configured to have the backend (ie. nginx) listening in on port 8080.
We need to use this file for a secondary purpose. Wordpress is chock full of various cookies that make caching it very difficult. In order to have varnish work as efficiently as possible, we need to tell it to drop all the cookies that don't relate to the admin side of the Wordpress site. Additionally, we need to tell varnish to remove the cookies that make worpdress very difficult to cache. The beginning of the default.vcl file should look like this:
[...]
backend default {
    .host = "127.0.0.1";
    .port = "8080";
}

# Drop any cookies sent to Wordpress.
sub vcl_recv {
        if (!(req.url ~ "wp-(login|admin)")) {
                unset req.http.cookie;
        }
}

# Drop any cookies Wordpress tries to send back to the client.
sub vcl_fetch {
        if (!(req.url ~ "wp-(login|admin)")) {
                unset beresp.http.set-cookie;
        }
}

[...]

Step Three—Configure Nginx


Although we have already configured varnish to expect that nginx ports will be running on 8080, the default settings for nginx are still on port 80. We will correct the discrepancy now.

Open up the virtual host file with the Wordpress information. In the previous Wordpress tutorial we simply called it wordpress:
sudo nano /etc/nginx/sites-available/wordpress

The Virtual Host should also be set to port 8080 and be accessible only from the localhost. The updated line looks like this:
[...]
server {
        listen  127.0.0.1:8080; ## listen for ipv4; this line is default and implied
        [...]

We need to do one last thing prior to starting varnish running on our site, and that is to remove the default enabled virtual host.
sudo rm /etc/nginx/sites-enabled/default

The template will remain in the sites-available directory, should you need it once more.

Step Five—Restart


Once you have made all of the required changes, restart varnish and nginx.
sudo service nginx restart
sudo service varnish restart

Accessing your domain should instantly take you to the varnish cached version, and you can see the details of varnish’s workings on your VPS with this command:
varnishstat




By Etel Sverdlov

Share this Tutorial

Vote on Hacker News

Try this tutorial on an SSD cloud server.

Includes 512MB RAM, 20GB SSD Disk, and 1TB Transfer for $5/mo! Learn more

Create an account or login:

93 Comments

Write Tutorial
  • Gravatar nick about 1 year

    Running into http 101 errors.

  • Gravatar nick about 1 year

    This configuration works for a majority of the time, however I still get a HTTP Error 101 "Connection was reset." Anyone have any luck and know how to fix this?

  • Gravatar Moisey about 1 year

    You may want to check how many free resources you have on your server, if the config works and occasionally has issues looks like it could be an issue with available RAM, etc.

  • Gravatar roozbehk about 1 year

    If you are going to use varnish + nginx solely for serving static sites. it is recommend by varnish dev people that you don't put varnish in front of nginx as nginx is pretty good at handing static sites without the help of varnish. if you however are setting up php fast-cgi. then you can leverage varnish.

  • Gravatar Dzulhelmi Jumat about 1 year

    I got this error: Error 503 Service Unavailable Service Unavailable Guru Meditation: XID: 1927329062 Varnish cache server

  • Gravatar Dzulhelmi Jumat about 1 year

    Its fixed now after i restart Varnish+Nginx :)

  • Gravatar Dzulhelmi Jumat about 1 year

    One question about Varnish, do i have to setup different VCL files for different WP sites or just once?

  • Gravatar Dzulhelmi Jumat about 1 year

    My permalinks still show "index.php" in the URL, how to remove this?

  • Gravatar xxdesmus about 1 year

    Can't seem to get this working with Nginx - keep ending up with Nginx bound to port 80 and 8080..which of course is interfering with Varnish being bound on 80. I can't find anything in Nginx's confs or site-enabled that should be pointing at 80.

  • Gravatar desk about 1 year

    I think using Tuxlite can make us ease as it can automate the whole install process ;)

  • Gravatar Chris Bunting about 1 year

    I personally don't think Varnish is needed unless you are pulling 500K+ visitors daily. But if you are looking for another Vanish install, most of the info provided will work here at DO. Look towards the bottom of the page for the Varnish config. http://www.ewanleith.com/blog/900/10-million-hits-a-day-with-wordpress-using-a-15-server

  • Gravatar micah about 1 year

    Thanks for your tutorial. I've got Varnish set up on port 80 with Apache running on port 8080 on an EC2 instance. Everything seems to work great except when I go to http://mysite.com/wp-admin it redirects to http://mysite.com:8080/wp-admin. I can still log in if I refresh after removing the 8080 part, but it would be great if this didn't happen. Any ideas how to fix this?

  • Gravatar pasbeier about 1 year

    Hey there micah, Just add the following to your sites-available/default (or what you've called that file): That goes into the server {} - part of your domain. port_in_redirect off; Furthermore, ensure that your Blog-URL in the WordPress preferences does not show :8080 at the end. Greetings!

  • Gravatar michael 12 months

    Ok now that I have this up an running, I need to add a second (very small) Wordpress site on the same droplet. Could any one explain how to do that? I've done allot of testing from Nignx.org and Stock Overflow articles, but noting seems to work according to the config I've created by following this tutorial. Thanks!

  • Gravatar Kamal Nasser 11 months

    @michael You can just duplicate the server{} virtualhost block and edit server_name appropriately (use a domain name instead of an IP address).

  • Gravatar Matt 11 months

    Thanks for the excellent write-up - works great!

  • Gravatar tiago.pcodelico 11 months

    hello, I installed following these tutorials, but now my site http://198.199.112.161 with this 503 error. I've restart nginx and varnish, but not solved. What do you advise?

  • Gravatar Guilherme Ribeiro 11 months

    In order to allow post preview you'll have to change the default.vcl to something like this... backend default { .host = "127.0.0.1"; .port = "8080"; } sub vcl_recv { # Allow posts preview if (req.url ~ "preview=true") { return(pass); } # Drop cookies sent to Wordpress if (!(req.url ~ "wp-(login|admin)")) { unset req.http.cookie; } } sub vcl_fetch { # Drop cookies sent to client if (!(req.url ~ "wp-(login|admin)")) { unset beresp.http.set-cookie; } }

  • Gravatar digitalocean 10 months

    I installed mysql, php, nginx, varnish and wordpress on ubuntu 12.04 and being able to view the site with the IP address given by digital ocean. After updating the DNS entries with my domain registrar, I can view the Wordpress site, but have problems getting to the WP Admin page. I get redirected to mydomain.com:8080/wp-admin/ and get an unable to connect message in my web browser. I assume there is a config file or something that needs updated with my domain name on my server setup, but I am unsure what it is.

  • Gravatar Kamal Nasser 10 months

    Please see @pasbeier's comment above.

  • Gravatar Adam Patterson 9 months

    Thanks! Finally a varnish config that works with WordPress! Still cant do a bulk update of plugins thought but I'm willing to take that hit.

  • Gravatar Ersan Genç 9 months

    When clicked on Customize, the theme preview doesn't appear. Instead a message appears saying session is expired and shows login box. Here's an image to show what it looks like: http://i.imgur.com/18QwXvi.jpg

  • Gravatar gary 9 months

    Hi, seemed to get everything working and then took a snapshot. Upon reboot the nginx service won't start and I get an Error 503 Service Unavailable message, Guru Meditation: XID: 1847591584. Not sure how to start nginx. Any help appreciated

  • Gravatar Kamal Nasser 9 months

    @Ersan: Do you have the following config in your Varnish config files? https://p.kk7.me/nijexabeqe.nginx

  • Gravatar Kamal Nasser 9 months

    @gary: What's the output of this command?

    tail /var/log/nginx/error.log

  • Gravatar gary 9 months

    Kamal, thank you for responding. I have restarted Nginx and made some progress but having errors. I have placed it here as a jpg (click to enlarge) http://37.139.14.30/hello-world/ http://37.139.14.30/hello-world/

  • Gravatar Kamal Nasser 9 months

    Try clearing it and browsing to your domain again so we can know which of the errors it is:

    cat /dev/null > /var/log/nginx/error.log

  • Gravatar Ersan Genç 9 months

    @Kamal, yes I do have that in my Varnish config, but I got around the problem by setting the phpmyadmin to work on another port which Varnish doesn't listen to.

  • Gravatar Kamal Nasser 9 months

    Oh. Glad you got it fixed! :]

  • Gravatar layne.heiny 8 months

    In order to get this set, I had to use server { listen [::]80 ipv6only=on; Therefore I cannot get the proxy_pass to work I have tried proxy_pass http://127:0:0:1:8080 as well as :80 Both cause an [emerg] invalid port in upstream ... Any suggestions?

  • Gravatar Kamal Nasser 8 months

    @layne.heiny:

    http://127:0:0:1
    should be
    http://127.0.0.1
    Dots, not colons :]

  • Gravatar Dave G 8 months

    I was playing around with this Nginx WordPres setup the other day. Select the droplet with the docker application and then import the script below from Github. :-) I had it up and running in a container on a port pretty easily, it seemed very fast. https://github.com/eugeneware/docker-wordpress-nginx

  • Gravatar aacharya.vaddey 7 months

    I have successfully executed your procedure. Very informative! Is there any need of wordpress varnish plugin after this? thanks in advance.

  • Gravatar Kamal Nasser 7 months

    @aacharya.vaddey: It should work without installing any Wordpress plugins.

  • Gravatar jaap.de.wit 7 months

    After the setup I was unable to preview posts and pages. Searching for a solution I found the following config for Varnish default.vcl. Instead of above code enter this: [...] backend default { .host = "127.0.0.1"; .port = "8080"; } # Drop any cookies sent to Wordpress except when previewing. sub vcl_recv { if ( !(req.url ~ "(wp-login|wp-admin|preview=true)") ) { unset req.http.cookie; } } # Drop any cookies Wordpress tries to send back to the client except when previewing. sub vcl_fetch { if ( !(req.url ~ "(wp-login|wp-admin|preview=true)") ) { unset beresp.http.set-cookie; } } [...]

  • Gravatar s.arazi770 6 months

    Finally, it works great for me !! How about... THANK YOU VERY MUCH DIGITAL OCEAN Before Varnish : page load 7.3s after : 2.42s Kabouuum Toda rabba

  • Gravatar Kamal Nasser 6 months

    @s.arazi770: Awesome! :]

  • Gravatar joshkarteson 6 months

    Thanks for the excellent article, you can install Nginx, PHP and MySQL with Postfix and phpMyAdmin using EasyEngine (https://github.com/rtCamp/easyengine). I have tried EasyEngine and it help me to get into shell. Regarding Varnish, I read this link recently (http://rtcamp.com/tutorials/why-we-never-use-varnish-with-nginx/), so I think we don't need to install another package to handle our static content.

  • Gravatar Pablo of vDevices.com 6 months

    @joshkarteson, Did you notice that the author of the article you cited states "Disclaimer: I never used Varnish."? Kinda hard to take someone at their word when they've never even tried it.

  • Gravatar Nicholas Ong 6 months

    Strange happenings here. On backend, i can navigate my WordPress dashboard no issues. One I go to the frontend/live-site, refuses to keep me logged-in no matter how many times I try. Any thoughts?

  • Gravatar Nicholas Ong 6 months

    Update: Turned off 'Users must be registered and logged in to comment ' in WordPress > Settings > Discussion and activated JetPack Comments. It's a temporary work-around till I figure out how to keep registered users logged in on the front end.

  • Gravatar Kamal Nasser 6 months

    @Nicholas: Hmm, seems like varnish isn't passing the cookies properly. What's the output of

    cat /etc/default/varnish | curl -F 'sprunge=
    ?

  • Gravatar Pablo of vDevices.com 6 months

    If installing Varnish on Ubuntu 12.04, do we still add the repo deb http://repo.varnish-cache.org/ubuntu/ lucid varnish-3.0? Or should we change the name lucid to precise?

  • Gravatar Kamal Nasser 6 months

    @Pablo: You should set it to your distro's codename:

    lsb_release -sc

  • Gravatar Nicholas Ong 6 months

    @Kamal, not getting any output. Just see this in Putty: '>' @Pablo, I just switched from lucid to precise and did a apt-get upgrade/update. Can't tell for sure but seems to be fine on my end. varnishd (varnish-3.0.4 revision 9f83e8f) <<< this is precise?

  • Gravatar Kamal Nasser 6 months

    @Nicholas: My bad, the command was stripped out. Try this instead:

    cat /etc/default/varnish | curl -F 'sprunge=<-' http://sprunge.us

  • Gravatar PigGy 6 months

    Hi. After [sudo rm /etc/nginx/sites-enabled/default] Should I add new symlink of 'Wordpress' to /etc/nginx/sites-enabled? Cos folder would be empty after delete default. [sudo ln -s /etc/nginx/sites-available/wordpress /etc/nginx/sites-enabled/wordpress]

  • Gravatar Nicholas Ong 6 months

    @Kamal, now that's interesting... here you go, http://sprunge.us/FWYE

  • Gravatar Misho 5 months

    How to set max-age=?

  • Gravatar Kamal Nasser 5 months

    @admin: See http://stackoverflow.com/questions/12864245/varnish-3-how-to-set-maximum-age-in-http-headers

  • Gravatar cleytonbonamigo 5 months

    If you're in trouble with upload large files in wordpress-admin panel (like me), try to do this: tail /var/log/nginx/error.log. Probably there's a line that show this: "client intended to send too large body". So, it's only do this: sudo nano /etc/nginx/nginx.conf Add or modify the following line on http{...} client_max_body_size 20M; That's all folks :D.

  • Gravatar eko bayu 5 months

    hi kamal very nice article, I'm doing some research for my thesis about varnish, I want to know, what is pros and cons from using varnish for web cache server ? and what we can configure in varnish ? thx, sorry for my bad english,

  • Gravatar Kamal Nasser 5 months

    @eko: I've never used Varnish myself, see if http://en.wikipedia.org/wiki/Varnish_(software) helps.

  • Gravatar csfalcao 5 months

    I've like to share my very succesful 5US droplet benchmark: LEMP, APC and varnish. ANALYSIS This rush generated 21,625 successful hits in 57.78 seconds and we transferred 184.75 MB of data in and out of your app. The average hit rate of 374.28/second translates to about 32,338,133 hits/day. The average response time was 31 ms. https://www.blitz.io/report/ad1a82454ca764fce66f361317eb8510#/

  • Gravatar csfalcao 5 months

    HD and CPU usage were below 8%. I´m very happy with the results!

  • Gravatar Bruno Testoni 5 months

    Got Varnish installed, but can't find a way to flush/purge/ban the cache. Tried everything I've found on the internet and notthing i working. The only effective way is to reboot the droplet. Any ideas?

  • Gravatar Kamal Nasser 5 months

    @Bruno: Try restarting Varnish -- I believe that should clear the cache.

  • Gravatar sgrenger 5 months

    I'm used to have W3Total Cache and DB Cache realoaded fix plugins installed in my Wordpress site, at a shared hosting server. After installing all os these and also Varnish, do you think i can still have those plugins?? Or will they be irrelevant due to Varnish?? Or even a conflict of caches?? (i'm a newbie is this part so it's probally that i dont know much what i'm talking about xD)

  • Gravatar Kamal Nasser 5 months

    @sgrenger: See https://www.digitalocean.com/community/questions/wordpress-w3-total-cache-plugin-configuration-with-varnish-installed

  • Gravatar paolo.beltrami 4 months

    Hi. Everything seems to work good on web, but I run into an error while trying to run varnishstat. varnishstat: error while loading shared libraries: libvarnishapi.so.1: cannot open shared object file: No such file or directory Can anyone please help me and fix it? thanks in advance.

  • Gravatar Kamal Nasser 4 months

    @paolo.beltrami: Running

    sudo ldconfig
    should fix it.

  • Gravatar Hemant Aggarwal 4 months

    @Kamal Nasser: Your answer didn't solve the problem. The error is still there varnishstat: error while loading shared libraries: libvarnishapi.so.1: cannot open shared object file: No such file or directory

  • Gravatar Kamal Nasser 4 months

    @Hemant: Hmm. Try running

    sudo apt-get install libvarnish-dev
    Does that fix it?

  • Gravatar golestani 4 months

    @ kamal nasser, had the same problem as @henmant, and "sudo apt-get install libvarnish-dev" fixed the problem. tnx

  • Gravatar Kamal Nasser 4 months

    @golestani: Glad it's working now. Thanks :]

  • Gravatar buzucan 3 months

    i think i have a problem with varnish and wp. all my external links, specially in comments(admin panel) show me 127.0.0.1, not the real ip as usual. i think i missed something...

  • Gravatar Kamal Nasser 3 months

    @buzucan: Log into your WordPress Admin Panel and browse to Settings - General. What are WordPress Address (URL) and Site Address (URL) set to?

  • Gravatar anand.srikantaiah 3 months

    I have completed my installation and can access my site at ip-address/wp-login but when I visit my ip-address directly , I see this page "Welcome to nginx!"

  • Gravatar anand.srikantaiah 3 months

    Ok, strangely its working now, but when I try to login I get this "ERROR: Cookies are blocked or not supported by your browser. You must enable cookies to use WordPress."

  • Gravatar Kamal Nasser 3 months

    @anand.srikantaiah: That's expected. It's better to leave it that way. What page do you get that error on?

  • Gravatar anand.srikantaiah 3 months

    when I enter login details at Domain-IP/wp-login.php

  • Gravatar anand.srikantaiah 3 months

    Solved, it works now, My bad had missed a code when following the steps

  • Gravatar aalireza439 3 months

    how can use this configuration for Drupal ?

  • Gravatar Kamal Nasser 3 months

    @aalireza439: Check out https://drupal.org/project/varnish.

  • Gravatar Tural Abiyev 3 months

    varnishstat command not working. debian 7 (nginx) please help me. Error message: varnishstat: relocation error: varnishstat: symbol VSC_Setup, version LIBVARNISHAPI_1.0 not defined in file libvarnishapi.so.1 with link time reference

  • Gravatar Kamal Nasser 3 months

    @Tural: See my comment above (December 14th, 2013 13:30).

  • Gravatar collin.m.barrett 2 months

    I have followed these instructions exactly, but for some reason varnish is still not working at all. The varnish header is not coming through when I load the page? My fresh WordPress install that should be coming through varnish is at this domain: www.collin-barrett.com Thanks for any help you can provide!

  • Gravatar abdul.khois 2 months

    How to setup Nginx + Varnish + PHP + Wordpress support Virtual hosts, I have 2 domain added in 1 droplet

  • Gravatar Thomas McMahon 2 months

    This works well, but the killing of the cookies also kills the theme customization screen in WordPress. Anyone know how to get that fixed?

  • Gravatar Thomas McMahon 2 months

    This site has updated cookie code that basically says that if you're logged in, skip Varnish. That way you don't lose theme customization, the admin bar, or anything else. http://timwhitlock.info/blog/2010/08/varnish-with-php-and-wordpress/

  • Gravatar jgiroux about 1 month

    Hey, I tried setting this up and I got a message that one aspect failed. Here's the message I get: Message from VCC-compiler: 'beresp.http.set-cookie': cannot be unset in method 'vcl_recv'. At: ('input' Line 22 Pos 23) unset beresp.http.set-cookie; ----------------------######################- Any ideas what might be causing this issue? I can try removing that line and see what happens.

  • Gravatar jgiroux about 1 month

    So, I resolved the issue above by deleting the system and starting from scratch. it's now working the way I expect it. BUT, I went ahead and added 4 more WP installations to the server. Everything seemed to be working fine until I went to the first install. It's redirecting to one of the other WP installations and I can't figure out where to look to try and fix the problem. I haven't added the new sites to varnish's default.vcl and when I look in the nginx/sites-available/ config files, everything looks to be right so I don't know where else I need to look to figure this all out. Any ideas?

  • Gravatar Thomas McMahon about 1 month

    That port_in_redirect off; line should REALLY be in the setup as it can cause lots of issues that you may not notice. For example, for the past month IFTTT.com was unable to connect to my site and do it's thing. Once I put that redirect off line in, things were fine.

  • Gravatar connormckelvey about 1 month

    When I change the theme to my blog, the change doesn't appear right away. How can i purge the varnish cache without a plugin?

  • Gravatar daniellekwint 29 days

    @connormckelvey delete your browser cache and use a cache plugin like w3 Total Cache which one can handle with Varnish as well

  • Gravatar i51nbf 22 days

    I want to install phpMyAdmin on this basis, who told me I should install?

  • Gravatar Kamal Nasser 22 days

    @i51nbf: I recommend using a local MySQL client with an SSH Tunnel. See https://www.digitalocean.com/community/articles/how-to-set-up-ssh-tunneling-on-a-vps. Create a tunnel for port 3306 and configure your MySQL Client (HeidiSQL, MySQL Workbench, Navicat, etc.) to connect to a local MySQL server on port 3306.

  • Gravatar jessemortensen 12 days

    I just followed the tutorials and everything seems to work, except I can't get any of the Wordpress/Varnish plugins to clear the cache. I'm assuming I am missing something in one of the config files, but I can figure it out. Any ideas?

  • Gravatar jessemortensen 12 days

    "can't figure it out"

  • Gravatar jessemortensen 12 days

    Found the solution: http://blog.doh.ms/2012/10/15/slapping-some-varnish-on-wordpress/

  • Gravatar baki60 11 days

    Step Three—Configure Nginx This part of the tutorial is NOT FAIR! Give us a link or something, what do we have to do in this part, it's too unclear...

  • Gravatar Kamal Nasser 10 days

    @baki60: Run

    sudo nano /etc/nginx/sites-available/wordpress
    edit the line that begins with listen and replace 80 with 8080.

  • Gravatar alanhoskins 8 days

    If you are using Varnish 4.0 you must use: sub vcl_backend_response { if (!(bereq.url ~ "wp-(login|admin)")) { unset beresp.http.set-cookie; } } instead of sub vcl_fetch { if (!(req.url ~ "wp-(login|admin)")) { unset beresp.http.set-cookie; } }

Leave a Comment

Create an account or login:
Ajax-loader