WordPress Nginx and APC Configuration

Nginx Logo

I’ve been working with Nginx web server for a while now. I have to say it’s an impressive web server that performs really well on high traffic websites. I’m in the process of migrating all my sites from Apache to Nginx. I am about 80% there after migrating WordPress and Joomla sites to Nginx without any major issues. I want to add a couple of WordPress Nginx config snippets here for my future reference.

WordPress Nginx Configuration

Normally Nginx config files will be stored in /etc/nginx directory and all related config files, such virtual hosts will be pulled in automatically from /etc/nginx/conf.d. The following would be a typical Nginx configuration file with gzip compression turned on:

user  nginx;
worker_processes  2;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    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;
    server_tokens   off;

    keepalive_timeout  65;

        gzip on;
        gzip_http_version 1.1;
        gzip_comp_level 6;
        gzip_min_length 1100;
        gzip_buffers 4 8k;
        gzip_types text/plain application/xhtml+xml text/css application/xml application/xml+rss text/javascript application/javascript application/x-javascr$
        gzip_proxied     any;
        gzip_disable     "MSIE [1-6]\.";

    upstream php {
        server 127.0.0.1:9000;
    }
    include /etc/nginx/conf.d/*.conf;
}

As you can see we include .conf files frm conf.d directory. Let’s say we wanted to create a virtual host for www.mysite.com domain that runs on WordPress platform. I would then add mysite.conf in conf.d with the following Nginx WordPress configuration:

server {
        server_name mysite.com;
        rewrite ^ http://www.mysite.com$request_uri permanent;
}

server {        
        server_name www.mysite.com;
        root /var/www/www.mysite.com/htdocs;
        index index.php;

        access_log /var/log/nginx/mysite.com.au_access.log;
        error_log /var/log/nginx/mysite.com.au_error.log;

        client_max_body_size 150m;

        # Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
        location ~ /\. {
                deny all;
                #access_log off;
                #log_not_found off;
        }
        # Deny all attempts to access *.conf
        location ~ \.conf$ {
                deny all;
        }
        
        # caching of files 
        location ~* \.(ico|pdf|flv)$ {
                expires 1y;
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|swf|xml|txt)$ {
                expires 14d;
        }

        # unless the request is for a valid file, send to bootstrap
        if (!-e $request_filename)
        {
                rewrite ^(.+)$ /index.php?q=$1 last;
         }
 
        # catch all
        error_page 404 /index.php;

        # Pass all .php files onto a php-fpm/php-fcgi server.
        location ~ \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass php;
        }

        location = /favicon.ico {
            log_not_found off;
        }
}

You could also move some of these config statements, such as upstream, rewrites and compression, into a global configuration file so they can be shared among other Virtual Hosts. But for the purpose this post, I’ve included everything in a single file.

APC Configuration

One other thing that can boost up your WordPress performance is PHP APC cache. I’ve spent a lot of time fine tuning APC configuration on WordPress and the following APC configuration seems to work quite well for me. Obviously a lot of these setting will depend on your server specs, but the following would be suitable for most common WordPress installations:

apc.enabled=1
apc.shm_segments=1

; I would try 32M per WP install, go from there
apc.shm_size=256M

; Relative to approx cached PHP files,
apc.num_files_hint=512

; Relative to approx WP size W/ APC Object Cache Backend,
apc.user_entries_hint=4096

apc.ttl=7200
apc.use_request_time=1
apc.user_ttl=7200
apc.gc_ttl=3600
apc.cache_by_default=1
apc.filters
apc.mmap_file_mask=/tmp/apc.XXXXXX
apc.file_update_protection=2
apc.enable_cli=0
apc.max_file_size=2M

;This should be used when you are finished with PHP file changes.
;As you must clear the APC cache to recompile already cached files.
;If you are still developing, set this to 1.
apc.stat=0

apc.stat_ctime=0
apc.canonicalize=1
apc.write_lock=1
apc.slam_defense=0
apc.report_autofilter=0
apc.rfc1867=0
apc.rfc1867_prefix =upload_
apc.rfc1867_name=APC_UPLOAD_PROGRESS
apc.rfc1867_freq=0
apc.rfc1867_ttl=3600

;This MUST be 0, WP can have errors otherwise!
apc.include_once_override=0

apc.lazy_classes=0
apc.lazy_functions=0
apc.coredump_unmap=0
apc.file_md5=0
apc.preload_path

Credit for the APC settings goes to Optimize APC Caching post on Stack Overflow.

Marko