I am running Debian Squeeze on a dedicated server, using it as a web- and db-server (nginx, apache & mysql).

I followed a few tutorials on how to setup nginx as a reverse proxy for apache - and most works just fine and I have to say - wow, nginx is very fast.

But, their are also some problems I encountered during "testing". And here we are, at the point I hope someone from serverfault's able to help me. :)

So let me first show you me complete configuration and explain the scenario.


To manage clients on the server I am using the ISPConfig Control Panel, configured to handle apache (you can choose between nginx or apache).

Since I don't want that the clients do have to configurate special rewrite rules etc. I am trying to tweak nginx very transparent, meaning it really does only serve static files and all other requests are passed to apache, so rewrite rules etc. still work.


What I currently have is:

  • a normal apache installation, listening on port 82
  • mod_rpaf enabled to forward the real IP to apache

  • nginx installed with the following configuration(s):


user www-data;
worker_processes 4;

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

events {
    worker_connections 2048;

http {
    include     /etc/nginx/mime.types;
    access_log  /var/log/nginx/access.log;

    sendfile on;
    tcp_nopush on;

    keepalive_timeout 4;
    tcp_nodelay on;

    # Hide version information
    server_tokens off;

    # Include configurations
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;


gzip on;

# Compression level
gzip_comp_level 6;

# HTTP version
gzip_http_version 1.0;

# File min lenght to compress
gzip_min_length 0;

# Compress all proxied files
gzip_proxied any;

# Mimes to compress
gzip_types text/plain text/css application/x-javascript text/xml \
        application/xml application/xml+rss text/javascript;

# Disable for IE 6 and below
gzip_disable "MSIE [1-6]\.";

gzip_vary on;


# Set locations and sizes
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=nginx_cache:10m max_size=500m;
proxy_temp_path /tmp/nginx;

# Putting the host name in the cache key allows different virtual hosts to share the same cache zone
proxy_cache_key "$scheme://$host$request_uri";

# Cache different return codes for different lengths of time
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;


proxy_redirect off;

# Set proxy headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

# Client configuration
client_max_body_size 10m;
client_body_buffer_size 128k;
client_header_buffer_size 64k;

# Connection and buffer
proxy_connect_timeout 60;
proxy_send_timeout 60;
proxy_read_timeout 60;
proxy_buffer_size 16k;
proxy_buffers 32 16k;
proxy_busy_buffers_size 64k;


server {

    # Listen on Port 80
    listen 80 default;

    # Resolve server_name with DNS
    server_name _;
    server_name_in_redirect off;

    # Strip www from host
    if ($host ~* ^www\.(.*)) {
            set $cleanhost $1;
    if ($cleanhost = "") {
            set $cleanhost $host;

    access_log /var/log/ispconfig/httpd/$cleanhost/access.log;

    # Serve static files through nginx
    #location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|e$
    location ~* ^.+.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|ex$
            root /var/www/$cleanhost/web;
            access_log off;
            expires max;
            error_page 404 /;

    # Apache backend for dynamic files
    location / {
            root /var/www/$cleanhost/web;
            index index.html index.htm index.php;
            access_log off;
            proxy_cache nginx_cache;
            proxy_pass http://$cleanhost:82;
            proxy_pass_header Set-Cookie;

What for?

As you can see, I am trying to serve static files through nginx and compress them. All other requests are passed to apache, and the result get's cached from nginx (within tmpfs).

With this default site, I don't have to create a config for every domain on the server.


OK, since you've seen the config, let's move over the the problems I got with these configurations:

  • If a website uses mod_rewrite to rewrite URLS like index.php?page=home to */page/home.html, nginx thinks that this is a static file (because of the .html ending) - and I get an error "not found".

  • On wordpress blogs, you are not able to insert medias into posts. You can upload them, but as soon as you push the "insert into post" button, you'll get an 403 - forbidden error.

  • Every website has it's own error documents folder /var/www/domain.tld/web/errors/[404.html|500.html etc.]. How do I tell nginx/apache to serve these and not the nginx/apache's default error pages?

What would help me?

If someone could walk through the configurations and look for parts, which could cause the named errors/problems.

Also, in general, general hints and tipps related to performance/security etc. are appreciated :)

Thank you very much for your time and help!

Regards, MaddinXx

  • A bit unrelated, but do you really need apache? It would be best to just cut out the middle man and use nginx with php-fpm. The few rewrites shouldn't be a problem using rewrite and also try_files. Cutting out apache would, I'm sure, solve the first two problems. As per your third issue, error_page along with your $cleanhost should work fine. – Sašo Jun 27 '12 at 7:50
  • @Sašo thank you for a very quick answer. To your question if I need apache or not, I would definitly say "YES" as the server is used for shared hosting and I think that a lot of customers just don't want to rewrite their rules etc. Because of this, nginx really should just stay "in the background". But of course, your setup would perform better... – MaddinXx Jun 27 '12 at 7:55

Two things: you should not use the version shiped with debian. Mine was eating cookies, which took me half a day to figure out. Use the latest debian package supplied by the nginx folks. They supply a repo, so its quite convenient.

For the redirect: I see you are using proxy_redirect off;. Try something like

proxy_redirect http://$host/index.php?page=home http://$host/page/home.html;

  • Hi @Isaac. Thank you for looking into it. I followed your first hint, using the official nginx repos. Second one may work, but is exactly what I don't want, as this can change for every site and I want it to have dynamic. Wouldn't there be a method first trying to serve with nginx and if it throughs an error 404 (because it can not be found because of the rewrite) pass it to the apache backend - it may work then. – MaddinXx Jun 27 '12 at 11:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.