7

I am going to build a website with docker-compose.

When user enter the root directory, it goes to the web app. When the user enter the http://example.com/blog, it should redirect to the wordpress.

In order to do so, i have config the docker-compose like this

version: "3"

services:

  nginx:
    image: nginx:latest
    depends_on:
      - web-app
      - wordpress
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 80:80

  mysql:
    image: mysql:5.7.29
    container_name: mysql
    restart: always
    volumes:
      - ./data/mysql/data:/var/lib/mysql

  wordpress:
    depends_on:
      - mysql
    image: wordpress:latest
    ports:
      - 8000:80
    restart: always
    volumes:
     - ./data/blog:/var/www/html/wp-content
     - ./blog/wp-config.php:/var/www/html/wp-config.php

  web-app:
    build: ./app
    depends_on:
      - mysql
    restart: always
    command: npm start
    environment:
      - TZ=UTC
      - NODE_ENV=production

networks:
  default:
    external:
      name: common

And this is my nginx config

worker_processes auto;
events {
    worker_connections 1024;
}
http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    log_format main '[$time_local] $remote_addr - $request request_time: $request_time';
    access_log /var/log/nginx/access.log main;

    gzip on;
    gzip_http_version 1.1;
    gzip_vary on;
    gzip_comp_level 6;
    gzip_proxied any;
    gzip_types text/plain text/html text/css application/json application/javascript application/x$
    #                        make sure gzip does not lose large gzipped js or css files
    #                        see http://blog.leetsoft.com/2007/07/25/nginx-gzip-ssl.html
    gzip_buffers 16 8k;

    server {
        listen 80;
        charset utf-8;

        location /blog/ {
            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_pass http://wordpress;
        }

        location / {
            proxy_http_version 1.1;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $http_host;
            proxy_set_header X-NginX-Proxy true;
            proxy_redirect off;
            proxy_pass http://web-app:3000;
        }

    }
} 

And I have updated the wp-config.php and set the website url.

define('WP_SITE_URL', 'https://example.com/blog');
define('WP_SITEURL', 'https://example.com/blog');
define('WP_HOME', 'https://example.com/blog');

However, when I enter to https://example.com/blog, it return the ERR_TOO_MANY_REDIRECTS response.

I have searched a lot articles and some of that say it is because I am using cloudflare. How can I solve the above problem?

1
  • This isn't a good solution, but it can help for a while until you find the cause: remove_action( 'template_redirect', 'redirect_canonical' ); Add this line to the functions.php file. Commented Jun 5, 2021 at 14:03

4 Answers 4

10

To initialize Wordpress in a subdirectory like /blog, you can use the working_dir attribute.

The default Wordpress image uses /var/www/html as root, and you can move to /var/www/html/blog to initialize at this point.

# ...
  wordpress:
    image: wordpress:apache
    working_dir: /var/www/html/blog
    volumes:
      - ./data/blog:/var/www/html/blog/wp-content
      - ./blog/wp-config.php:/var/www/html/blog/wp-config.php
# ...

Now, you can navigate to http://localhost/blog.

Full example

Following is a full docker-compose.yml example:

version: '3.1'

x-wordpress: &wordpress
  depends_on:
    - db
  environment:
    WORDPRESS_DB_HOST: db:3306
    WORDPRESS_DB_NAME: wordpress
    WORDPRESS_DB_USER: wordpress
    WORDPRESS_DB_PASSWORD: wordpress
  working_dir: /var/www/html/blog
  volumes:
    - wp_root:/var/www/html/blog
    - ./wp-content/plugins:/var/www/html/blog/wp-content/plugins
    - ./wp-content/themes:/var/www/html/blog/wp-content/themes
    - ./wp-content/uploads:/var/www/html/blog/wp-content/uploads
    - ./wp-content/languages:/var/www/html/blog/wp-content/languages

services:
  # Database
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
      - ./backup/blog.sql:/docker-entrypoint-initdb.d/dump.sql:ro
    ports:
      - 3306:3306
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wordpress
      MYSQL_PASSWORD: wordpress

  # phpmyadmin
  phpmyadmin:
    depends_on:
      - db
    image: phpmyadmin/phpmyadmin
    ports:
      - 8080:80
    environment:
      PMA_HOST: db
      MYSQL_ROOT_PASSWORD: password

  # Wordpress
  wordpress:
    <<: *wordpress
    image: wordpress:apache
    ports:
      - 80:80

  wpcli:
    <<: *wordpress
    image: wordpress:cli

volumes:
  wp_root:
    driver_opts:
      type: tmpfs
      device: tmpfs
  db_data:

Notes about syntax:

Finally, the code like following:

x-wordpress: &wordpress
  depends_on:
    - db
  environment:
    WORDPRESS_DB_HOST: db:3306
  volumes:
    - wp_root:/var/www/html/blog

services:
  wordpress:
    <<: *wordpress
    image: wordpress:apache
    ports:
      - 80:80

Will be processed as following:

services:
  Wordpress:
    depends_on:
      - db
    environment:
      WORDPRESS_DB_HOST: db:3306
    volumes:
      - wp_root:/var/www/html/blog
    image: wordpress:apache
    ports:
      - 80:80
Sign up to request clarification or add additional context in comments.

2 Comments

can you pls explain the &wordpress and <<: *wordpress - that do they do?
I have spent WEEKS trying to work this out, on and off. This answer works perfectly! This has allowed me to simply install wordpress in a subdirectory / subfolder of my website without rewrites. working_dir was the key - this should be on the wordpress docker documentation. The only difference I have is how I map wp-content which is all at once - /var/www/dirname/blog/wp-content/:/var/www/html/blog/wp-content/
4

In your config.php you do this :

// Define the website URL
define('WP_SITEURL', getenv_docker('WORDPRESS_SITEURL', 'https://example.com/blog'));

// Define the website Home page
define('WP_HOME',    getenv_docker('WORDPRESS_HOME', 'https://example.com/blog'));

// Rewrite your access URL to the admin page
$_SERVER['REQUEST_URI'] = str_replace("/wp-admin/", "/blog/wp-admin/",  $_SERVER['REQUEST_URI']);

If you don't version your wordpress resources, use directly the docker compose variables like this, instead of using the config.php file :

WORDPRESS_CONFIG_EXTRA: |
   define('WP_HOME','https://example.com/blog');
   define('WP_SITEURL','https://example.com/blog');
   $$_SERVER['REQUEST_URI'] = str_replace("/wp-admin/", "/blog/wp-admin/",  $$_SERVER['REQUEST_URI']);

And in the file docker-compose.yml you put the following environment variables :

environment:
  ...
  - WORDPRESS_SITEURL="https://example.com/blog"
  - WORDPRESS_HOME="https://example.com/blog"

1 Comment

I'm getting infinite redirect loop.
3

What actually worked for me is this combo :

nginx :

upstream test {
    least_conn;
    server test_wordpress_1;
}
server {
    listen 443 ssl;
    server_name slapps.fr;
    #...
    #SSL CONFIG
    #...
    location /test/ {
        #rewrite ^/test/(.*)$ /$1 break; #This didn't work for me 
        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-Proto  $scheme;
        proxy_pass http://test/;

    }
 }

wp-config.php :

define('WP_HOME','https://slapps.fr/test');
define('WP_SITEURL','https://slapps.fr/test');
$_SERVER['REQUEST_URI'] = str_replace("/wp-admin/", "/test/wp-admin/",  $_SERVER['REQUEST_URI']);

Somehow the following config in docker-compose.yml didn't work for me, the $_SERVER wouldn't go through, but the first defines did

WORDPRESS_CONFIG_EXTRA: |
            define( 'WP_HOME', 'https://slapps.fr/test' );
            define( 'WP_SITEURL', 'https://slapps.fr/test' );
            $$_SERVER['REQUEST_URI'] = str_replace("/wp-admin/", "/test/wp-admin/",  $$_SERVER['REQUEST_URI']);

1 Comment

Thank you! I was missing proxy_set_header X-Forwarded-Proto $scheme; in my configuration, but as soon as I added it, the assets were served correctly. Before I was seeing an error about mixed resources (HTTPS vs HTTP for the assets).
0

In addition to the excellent answer from @Eduardo Cuomo above outlining the key point of setting "working_dir", here's a couple of extra tips that worked for me when I couldn't navigate to blog posts.

The main tip is to go into Wordpress Admin -> Settings -> Permalinks and hit "save changes". That regenerates the permalink structure and appeared to fix my problem.

My next step would have been another tip I found, which was to update the apache .htaccess file for Wordpress as follows. The "RewriteBase" is the key line that I think may have helped, but I haven't tried this part myself. You'd have to

RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.php [L]

To change that I would put something like this in my docker-compose file

- /host/machine/.htaccess:/var/www/html/blog/.htaccess

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.