How can I force www subdomain usage?

Hello there,

I am kinda new to Trellis and I have successfully deployed it on a droplet. Everything is fine except that I would like to force the www subdomain but can’t make it work.

I know this topic has already been brought here before but it is outdated now.

I tried multiple configuration in my wordpress_sites.yml, notably by setting the canonical url to www.mydomain.com without success.

How could I force the www subdomain ?

Show us what you tried. Did you re-provision the server afterwards?

Here is what I ended up with, which makes infinite redirections :

wordpress_sites:
  www.mydomain.com:
    site_hosts:
      - canonical: www.mydomain.com
      redirects:
          - mydomain.com
    local_path: ../site
    repo: myrepo.git
    repo_subtree_path: site
    branch: master
    multisite:
      enabled: false
    ssl:
      enabled: true
      provider: letsencrypt
    cache:
      enabled: true
    env:
      wp_home: https://www.mydomain.com

After every test change to the configuration file I re-provisioned the server by running :

ansible-playbook server.yml -e env=production

This probably isn’t the answer, but Chrome aggressively caches redirections. Have you tried this solution in a different browser, or from your phone? It could be that Chrome and the site are arguing over which URL is canonical.

I’m usually on Safari and disabled the cache, but I tried on FF and Chrome too without success.
I also tried HTTP code checker like https://httpstatus.io to see what happens, but I get too many redirections.

@Asch Could you also try a deploy (deploy.yml) after your provision (server.yml)?

During deploys, the WP_HOME and WP_SITEURL constants are updated via env vars based on the first canonical url in your site_hosts.

Without a deploy to update the WP constants, the Nginx would be redirecting domain.com to www.domain.com but I think WP itself may then be redirecting the www.domain.com back to domain.com (can’t remember if that’s how it works), and a loop ensues.

1 Like

I just tried to deploy after provisioning but it still doesn’t work. Still getting a 301 from “www.mydomain.com” to “mydomain.com”, then a 301 from “mydomain.com” to “www.mydomain.com” and looping again and again.

Is my wordpress_sites.yml correctly configured or am I missing something ?

Hmm, ok. I mentioned the deploy idea because I was able to reproduce the issue by provisioning only, then fix it by deploying (on a bedrock-based test site with no extra plugins or WP settings).

I don’t see errors that would block, but I suggest some adjustments:

 wordpress_sites:
   www.mydomain.com:
     site_hosts:
       - canonical: www.mydomain.com
-      redirects:
+        redirects:
           - mydomain.com
     local_path: ../site
     repo: myrepo.git
     repo_subtree_path: site
     branch: master
     multisite:
       enabled: false
     ssl:
       enabled: true
       provider: letsencrypt
     cache:
       enabled: true
-    env:
-      wp_home: https://www.mydomain.com

I suggest also:

  • run server.yml again
  • run deploy.yml again
  • ssh root@mydomain.com and service nginx -t && service nginx reload
    OR if if root is not permitted use admin and the sudo password here
    ssh admin@mydomain.com and sudo service nginx -t && sudo service nginx reload
  • test in browser again

If it still doesn’t work, think through any plugins or WP settings you may have that involve URLs and redirects. Also consider whether you have any DNS adjustments that might be causing an issue (I can’t think of any examples of the top of my head though).

You could consider SSHing to your server copying the contents of /etc/nginx/sites-enabled/mydomain.com.conf and posting for review here.

I made the change in the conf file, provisioned, deployed and reloaded nginx but sadly it doesn’t work.

I don’t know if it’s OK but it seems I have two sites-enabled config files on my server : a mydomain[dot]com.conf and a www.mydomain[dot]com.conf which may be the source of the conflict ? I copy/pasted the contents below.

By the way this a complete fresh install, I didn’t install any plugin neither change any settings of WordPress.

Server-side I’m using the basic droplet plan on DigitalOcean which has a few DNS records :

  • A -> mydomain[dot]com -> directs to my.server.ip
  • NS -> mydomain[dot]com -> directs to ns1.digitalocean[dot]com.
  • NS -> mydomain[dot]com -> directs to ns2.digitalocean[dot]com.
  • NS -> mydomain[dot]com -> directs to ns3.digitalocean[dot]com.
  • CNAME -> *.cactuseo[dot]com -> is an alias of cactuseo[dot]com

I am not used to manage DNS records so I might have done some misconfiguration here too.

Contents of mydomain[dot]com.conf :

Contents of www.mydomain[dot]com.conf :

P.S : sorry for the [dot] notation I can’t post more than 4 links as a new user

Good find! I think the two Nginx conf files could likely be the cause.

DNS looks fine, but try removing one Nginx conf:

  • SSH in
  • remove the non-www conf
    (remove /etc/nginx/sites-enabled/mydomain.com.conf)
  • reload nginx
  • try loading your site in the browser.

Below is a bunch of speculation about what could be going on due to the presence of the two confs.

Site key determines name for www_root, Nginx conf, and DB

I’m guessing you originally had this:

wordpress_sites:
  mydomain.com:
  ...

The above creates the mydomain.com.conf and a DB named mydomain_com_production.

Then you probably made this change to the “site key”:

 wordpress_sites:
-  mydomain.com:
+  www.mydomain.com:
   ...

The above site key change creates the www.mydomain.com.conf.

In addition, now you have two site directories in your www_root:

/srv/www
  ├── mydomain.com
  └── www.mydomain.conf

You would also have two databases due to the different site keys.

Nginx matches only one server block per server_name www.mydomain.com

Line 7 in both your nginx confs: server_name www.mydomain.com; Nginx will only match one or the other server blocks with identical server_name directives. Nginx probably matches the server block in the conf file whose name comes first lexicographically.

The mydomain.com.conf comes before www.mydomain.com.conf alphabetically, so its OLD server block is probably matched. This block has line 12 root /srv/www/mydomain.com/current/web; so traffic is sent to your OLD deploy’s files where maybe the canonical host and env var was mydomain.com and WP was perhaps redirecting www.mydomain.com to mydomain.com.

If that is the case, any new provision/deploy affects only the NEW site files in /srv/www/www.mydomain.com but Nginx never sends traffic there.

2 Likes

Absolutely right. By deleting the old conf file and reloading nginx it works perfectly !

By the way, are the canonical URL and the site key linked ? Is a requirement or a best practice or just a personal preference for both to be the same ? Because my first (kinda dumb) move was to change every “mydomain.com” to “www.mydomain.com” included the site key, not knowing how it will affect the server.

Thanks again for your detailed answer @fullyint :smiley:

The site key and the canonical host are independent.

You could have the site key be whatever and the site files would be at /srv/www/whatever, the Nginx conf at /etc/nginx/sites-enabled/whatever.conf, and the DB named whatever_production.

I suspect most people just leave the site key domain.com even if their canonical host is www.domain.com. It’s up to you.

In any case, it looks like you’ll probably want to pick a site key and not change it, as we learned the hard way above. :slightly_smiling_face:

1 Like