Bedrock with Multisite Setup, using Sub-Directories -- Can't get .htaccess working

Hello there!

This is my first post, so I want to start with a big thank-you to @ben and team for the wonderful work with Trellis and Bedrock. In the past 2 weeks that I have spent hacking with both Trellis and Bedrock, I have learnt so much new stuff about Wordpress and Ansible. Awesome work guys!

Now for my issue. I seem to have hit against a wall with something I’m trying to do, and have already spent last couple of days troubleshooting and reading through this forum and elsewhere.

I’m trying to install Bedrock (I’ve synced with latest Git) with Multisite using sub-directories. I’m using Apache because my host would not support Nginx. Here’s my URL configuration:

www.mydomain.com - Root site
www.mydomain.com/us - Sub-site #1
www.mydomain.com/ca - Sub-site #2

I have not been able to get my .htaccess configuration to work properly, despite much trying. I’m close to giving up on Bedrock, even though I love it so much already.

The problem is with the fact that Wordpress is installed in a sub-directory with Bedrock (i.e. web/wp), and that doesn’t seem to go well with Multisite setup that uses subdirectories. Here’s my current .htaccess file:

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]

# uploaded files
RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^[_0-9a-zA-Z-]+/(wp-(content|admin|includes).*) /current/web/wp/$1 [L]
RewriteRule ^[_0-9a-zA-Z-]+/(.*\.php)$ /current/web/wp/$1 [L]
RewriteRule ^(/)?$ current/web/index.php [L]
RewriteRule . index.php [L]
</IfModule>
# END WordPress

My wordpress_sites.yml configuration follows all the docs closely. Here’s a portion of the configuration:

    multisite:
      enabled: true
      subdomains: false
    ssl:
      enabled: false
      provider: letsencrypt
    cache:
      enabled: false
    env:
      domain_current_site: www.mydomain.com
      wp_home: http://www.mydomain.com
      wp_siteurl: http://www.mydomain.com/wp

(I have of-course replaced my real domain with www.mydomain.com since I don’t want my domain to be known publicly and discovered by search engines.)

Thanks in advance.

Best,
Sac

@asksac, did you resolve this issue?

I’m in (almost) the same situation, ie:

  1. Running development Subdirectory Multisite WordPress locally under Trellis using Nginx.
  2. Deploying using Capistrano to shared hosting under Apache.

I’ve deployed my code successfully to my shared host using Capistrano. I’ve also migrated my local database to my shared host using wp-cli export & scp & wp-cli import & wp-cli search-replace, but am not sure how to modify my shared host’s .htaccess file to cope with Bedrock’s directory structure…?

My shared host .htaccess file:

# BEGIN WordPress
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
RewriteRule . index.php [L]
# END WordPress
AddType x-httpd-php7 .php

Thanks,
H

Yes I did resolve it eventually. I had to use two .htaccess files. One in my hosting’s web root, and another within the WP directory. I also managed to figure out most of the Bedrock deployment automation for shared hosting (using Ansible and WP CLI for the most part). I am on the road traveling right now but I can share source code and other details with you once I’m back to my desk by end of next week. Let me know if you’re interested in that.

That’s impressive @asksac - Ansible on shared hosting!

Yes, definitely interested in all of the details, as I’m a bit stuck and I think it would help a lot of other people too. Thanks!

Hey @asksac did you get a chance to dig out your .htaccess solution? :slight_smile:

@henscu, I am so sorry about my delay. I have not been checking this account and have been off development for the past two or so months. Anyways, I hope this will help you in some way, despite all the delay.

I tried several things with my .htaccess file, but none worked other than this workaround (as I had stated in my original post, I wanted a WP network install using sub-directories). So I had to create two .htaccess file. First one was saved on the www root folder (of my shared hosting account – Dreamhost in my case), and the second .htaccess file in the ./current/web folder. Here are the two files:

#www_root.htaccess

RewriteEngine on
RewriteBase /

RewriteCond %{REQUEST_URI} !^/current/web/

# Rewrites all URLS [Replace "domain" with the actual domain, without the TLD (.com, .net, .biz, etc)]
# RewriteCond %{HTTP_HOST} ^(www\.)?stage\.wi-mon\.
# RewriteCond %{HTTP_HOST} ^(www\.)?{{ site | regex_escape() }}

# Rewrite all those to insert /folder
RewriteRule ^(.*)$ /current/web/$1 [L]

#current_web.htaccess

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]

# uploaded files
RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]

# add a trailing slash to /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]

RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(wp-(content|admin|includes).*)$ /wp/$1 [L]
RewriteRule ^[_0-9a-zA-Z-]+/(wp-(content|admin|includes).*) /wp/$1 [L]
RewriteRule ^[_0-9a-zA-Z-]+/(.*\.php)$ /wp/$1 [L]
RewriteRule ^(/)?$ index.php [L]
RewriteRule . index.php [L]
</IfModule>
# END WordPress

I also created a new role in Ansible (I called it dreamhost-deploy) and entered the following in the ./tasks/main.yml file:

# This file contains DreamHost specific tasks
---

- name: Copy www_root.htaccess to DreamHost
  template:
    src: www_root.htaccess
    dest: "{{ project_root }}/.htaccess"
    backup: yes
    mode: 0644

- name: Copy current_web.htaccess to DreamHost
  template:
    src: current_web.htaccess
    dest: "{{ project_root }}/current/web/.htaccess"
    backup: yes
    mode: 0644

The role (dreamhost-deploy) was then added to the deploy.yml, as follows:


  roles:
    - deploy
    - dreamhost-deploy

(notice the new role has been added right after -deploy)

The file structure of my dreamhost-deploy role looks like this:

Let me know if this helps, or if you have any questions related to above. I will check my account again this week, so I should catch your response if you do.

2 Likes

@asksac, no worries, thanks for the information!

I’m getting up to speed on .htaccess at the moment. There are many tutorials but not many good ones…

I will get back to you when I’ve digested your setup. Thanks again.