Wordpress: How to run wordpress behind HOST nginx?

Created on 19 Nov 2017  路  10Comments  路  Source: docker-library/wordpress

Hello there,

how do I have to configure nginx to be able to run a dockerized wordpress setup? No, I do not intend to run a dockerized nginx and need/want it to be managed by my host.

I tried the following but I cannot get past the language setup

server {
    listen 80;
    server_name 10.211.55.14;

    rewrite ^(.*) https://$server_name$1 permanent;
}

server {
    listen 443 ssl;
    server_name 10.211.55.14;

    access_log /var/log/nginx/wordpress-access.log;
    error_log /var/log/nginx/wordpress-error.log;

    include /etc/nginx/snippets/ssl-wordpress.conf;
    include /etc/nginx/snippets/ssl-params.conf;

    location / {
        proxy_pass       http://localhost:7979;
        proxy_redirect   off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $server_name;
        proxy_set_header X-Forwarded-Proto https;
    }
}

For /wp-admin I receive "ERR_TOO_MANY_REDIRECTS" and for the front page css won't get loaded properly

I already added the following to wp-config.php

define('WP_HOME','http://10.211.55.14');
define('WP_SITEURL','http://10.211.55.14');

Most helpful comment

Not sure whether the nginx setup is properly done so it would be great if someone could look into it (remember, nginx is running on host, mysql/wordpress is dockerized with the given .yml)

I added the following ONTOP of the wp-config.php file and got it working now. As it seems it MUST be placed as high as possible (which is a bad behavior anyways) or it won't work at all!

/**
 * For WordPress, force the protocol scheme to be HTTPS
 * when is_ssl() doesn't work, e.g. on a reverse proxied server
 * where _SERVER['HTTPS'] and _SERVER['SERVER_PORT'] don't
 * indicate that SSL is being used.
 */
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
    $_SERVER['HTTPS'] = '1';

if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}

Source

All 10 comments

Not sure whether the nginx setup is properly done so it would be great if someone could look into it (remember, nginx is running on host, mysql/wordpress is dockerized with the given .yml)

I added the following ONTOP of the wp-config.php file and got it working now. As it seems it MUST be placed as high as possible (which is a bad behavior anyways) or it won't work at all!

/**
 * For WordPress, force the protocol scheme to be HTTPS
 * when is_ssl() doesn't work, e.g. on a reverse proxied server
 * where _SERVER['HTTPS'] and _SERVER['SERVER_PORT'] don't
 * indicate that SSL is being used.
 */
if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
    $_SERVER['HTTPS'] = '1';

if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}

Source

This block of code:

define('WP_HOME','http://10.211.55.14');
define('WP_SITEURL','http://10.211.55.14');

Should really be:

define('WP_HOME','https://10.211.55.14');
define('WP_SITEURL','https://10.211.55.14');

(Note the https:// there.)

See also https://codex.wordpress.org/Moving_WordPress.

As to the block you added to wp-config.php, this repository will already add roughly that exact block for new installs:

https://github.com/docker-library/wordpress/blob/583768e49b56d478cc039671f25d3f73a949f2c6/docker-entrypoint.sh#L130-L140

(As documented in http://codex.wordpress.org/Administration_Over_SSL#Using_a_Reverse_Proxy.)

I don't follow what the solution was here. I too am using a nginx running undockerized and I want it to proxy requests to the wordpress image. I was able to get through the installation wizard but there are no css assets loaded. I feel like this is a more basic question than nginx+ssl (which I'll get to next).

my nginx.conf

events {
    worker_connections 768;
    # multi_accept on;
}
http {
    server {
        server_name foo.com www.foo.com;

        location / {
            proxy_pass http://localhost:4000;
        }
    }
}

devtools network tab after reload on the wordpress site root (foo.com)
screen shot 2018-09-01 at 11 51 08 pm

update: I fixed one error net::ERR_INSECURE_RESPONSE by adding ssl to the site with letsencrypt, nginx and certbot. The error then becomes the assets refer to localhost:<port>.
screen shot 2018-09-02 at 11 24 37 am

I'm doing

sudo docker run -e WORDPRESS_DB_PASSWORD=foo -e WORDPRESS_ADDITIONAL_CONFIG="define('WP_HOME','https://foo.com'); define('WP_SITEURL','https://foo.com');" --name wordpress --link wordpressdb:mysql -p 4000:80 -d wordpress

but I'm not seeing the extra config addd to wp-config.php

The proper environment variable is WORDPRESS_CONFIG_EXTRA.

sudo docker run -e WORDPRESS_DB_PASSWORD=foo -e WORDPRESS_CONFIG_EXTRA="define('WP_HOME','https://foo.com'); define('WP_SITEURL','https://foo.com');" --name wordpress --link wordpressdb:mysql -p 4000:80 -d wordpress

works and you should see a styled installation.

final nginx.conf. But you should let certbot add the ssl related lines.

events {
    worker_connections 768;
    # multi_accept on;
}

http {
    server {
        server_name foo.com www.foo.com;

        location / {
            proxy_pass http://localhost:4000;
        }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/foo.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/foo.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

    server {
    if ($host = www.foo.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = foo.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


        server_name foo.com www.foo.com;
    listen 80;
    return 404; # managed by Certbot
}
}

It's still not fully solved, the site redirects to localhost after I complete the installation wizard. Thoughts?

@morenoh149 the important bit your NGINX configuration is missing is the X-Forwarded-Proto header, which is the standard way for a reverse proxy like NGINX to inform the application it's proxying for that it is handling the request via TLS even though the application itself is receiving the request over plain HTTP

@tianon Thank you very much for that hint! I was struggling for days and had tried multiple approaches! You saved my day!!!

@sdaban you may find https://github.com/docker-library/wordpress/issues/331 , and it's solution, useful

@morenoh149, truly you are a life saver!

Editing wp-config.php would work, but if your wp-config.php file is under Docker, then you can use docker cp command to copy/copy back file.

#Copy from docker container
docker cp project_wordpress_1:/var/www/html/wp-config.php .

#Edit it

#Copy back to docker container
docker cp wp-config.php project_wordpress_1:/var/www/html/wp-config.php

Modified with https://www.nginx.com/resources/wiki/start/topics/recipes/wordpress/
This is for fpm images.

````nginx

Upstream to abstract backend connection(s) for php

upstream php {
server wordpress:9000;
}

server {
set_real_ip_from 10.0.0.0/8;
set_real_ip_from 172.16.0.0/20;
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 127.0.0.1;

    proxy_set_header Forwarded $proxy_protocol_addr;
    proxy_set_header X-Forwarded-For $proxy_protocol_addr;
    proxy_set_header X-Forwarded-Proto $scheme;

    server_name localhost;
    ## Your only path reference, mount wordpress files here
    root /var/www/html;
    ## This should be in your http block and if it is, it's not needed here.
    index index.php;
    # upload size
    client_max_body_size 100M;

    location = /.user.ini {
            return 404;
    }

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

    location = /robots.txt {
            allow all;
            log_not_found off;
            access_log off;
    }

    location / {
            # This is cool because no php is touched for static content.
            # include the "?$args" part so non-default permalinks doesn't break when using query string
            try_files $uri /index.php?q=$uri&$args;
    }

    location ~ \.php$ {
            #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
            include fastcgi.conf;
            fastcgi_intercept_errors on;
            fastcgi_pass php;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
            expires max;
            log_not_found off;
    }

}
````

Was this page helpful?
0 / 5 - 0 ratings