Development: HTTPS for WordPress using Caddy

1. Caddy version (caddy version):

n/a

2. How I run Caddy:

a. System environment:

n/a

b. Command:

n/a

c. Service/unit/compose file:

n/a

d. My complete Caddyfile or JSON config:

n/a

3. The problem I’m having:

I’m looking at getting some Caddy code added to this WordPress support doc HTTPS for WordPress. I’ve chosen this page as it’s quite strategic and should leave a lasting impression on the simplicity of Caddy. I figure it’s a great place for a compare and contrast of the Apache code that’s in the article and the equivalent Caddyfile code to be supplied.

More info in the post to follow.

4. Error messages and/or full log output:

n/a

5. What I already tried:

n/a

6. Links to relevant resources:

  1. HTTPS for WordPress
1 Like

This is the section of the article I’m referring to:

Best Practices for HTTPS for WordPress #

It is recommended for all production WordPress sites to use HTTPS.

  • Use a reputable web host, most provide HTTPS service as a standard.
  • Use a SSL Certificate from Let’s Encrypt, they are free and easy to use.
  • Serve Static Content from an SSL enabled CDN

You may need to redirect your HTTP traffic to your HTTPS site. For Apache, you can do so by creating two VirtualHost entries for example:

<VirtualHost *:80>
    ServerName mkaz.blog
    Redirect / https://mkaz.blog/
</VirtualHost>

<VirtualHost *:443>
    ServerName mkaz.blog
    DocumentRoot /home/mkaz/sites/mkaz.blog
    <Directory /home/mkaz/sites/mkaz.blog>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    SSLEngine on
    SSLCertificateFile    /etc/letsencrypt/live/mkaz.blog/cert.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/mkaz.blog/privkey.pem
    SSLCertificateChainFile /etc/letsencrypt/live/mkaz.blog/fullchain.pem
    IncludeOptional /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>

Caddy considerations in the next post.

I’m not familiar with Apache, but as Caddy handles automatic HTTPS, I’m guessing the bottom block of the Apache code disappears.

I wasn’t able to do a 1:1 transformation, but would this be the equivalent Caddyfile? If so, I have a few follow-up questions.

mkaz.blog { 
    root /home/mkaz/sites/mkaz.blog
    php_fastcgi 127.0.0.1:9000
    file_server
}

Close, you need a * for root since otherwise, the first parameter would be parsed as a path matcher:

root * /home/mkaz/sites/mkaz.blog

Also worth noting that Apache + PHP usually involves using mod_php, whereas Caddy uses php-fpm (although Apache can use php-fpm as well, but that’s less commonly used) which has involves different setup steps.

That example looks a bit goofy though, it reads like some user called mkaz left in their domain and paths in the config.

I would update that to example.com and maybe /var/www/html or /var/www/example.com or something to that effect. Putting sites in /home is usually not ideal, for user permissions etc.

1 Like

My bad, I left out the *. My follow-up questions, which I think you’ve partly answered are:

  1. Unlike the Apache code, why didn’t I have to redirect HTTP to HTTPS in Caddy? That seems to be intrinsically done somewhere.
  2. What’s the part of the Apache code that serves PHP files? Is it the ‘module’ the code is run in?
  3. Is the wrapper around the middle block of the Apache code the equivalent of Caddy file_server or is it the again the module the code runs in that does the file serving?
example.com { 
    root * /var/www/html
    php_fastcgi 127.0.0.1:9000
    file_server
}

In addition, do you have a preference here - the use of 127.0.0.1 or localhost?

    php_fastcgi localhost:9000

That’s part of Automatic HTTPS. It automatically enables HTTP->HTTPS redirects.

The PHP module is probably enabled globally for Apache automatically when PHP was installed alongside Apache using your package manager. Apache config is not really comparable to Caddy, they’re quite different.

If you mean <Directory, that essentially defines some ACL rules for certain paths, i.e. “grant access to this directory in the context of the server on port 443”. Apache’s default is to enable a file server AFAIK.

:man_shrugging: it’s basically the same. localhost reads nicer I guess but some system do really dumb things and change localhost to resolve to something else. It’s bit some users of Caddy in the past where the default admin endpoint of localhost:2019 would bind to something random. But that’s an edgecase and isn’t so relevant. I’d just match whatever’s in the php-fpm config, and I think that’s typically 127.0.0.1:9000.

1 Like

So, this is what I’m thinking gets added after the Apache code:

The Caddy web server activates HTTPS by default for qualifying domain names and automatically enables HTTP → HTTPS redirects. By default, it obtains certificates from Let’s Encrypt and renews them automatically.

example.com { 
    # Set this path to your site's directory:
    root * /var/www/html

    # Enable the static file server:
    file_server

    # Serve WordPress PHP files through php-fpm:
    php_fastcgi 127.0.0.1:9000
}

Suggestions for improving this are welcome and in-principle endorsement from the Caddy team required before I submit a WP doc update request.

I’d put php_fastcgi before file_server because that’s the order in which Caddy will actually sort them according to the directive order.

BTW, we actually do have an example for WordPress in the docs, although it can be easily missed:

1 Like

Oh also, I’d say it’s probably beneficial to add encode gzip as well, it’s free performance win. (I’d order it after root)

1 Like

Next iteration…

The Caddy web server activates HTTPS by default for qualifying domain names and automatically enables HTTP → HTTPS redirects. By default, it obtains certificates from Let’s Encrypt and renews them automatically.

example.com { 
    # Set this path to your site's directory:
    root * /var/www/html

    # Enable Gzip compression:
    encode gzip

    # Serve WordPress PHP files through php-fpm:
    php_fastcgi 127.0.0.1:9000

    # Enable the static file server:
    file_server
}

For a Caddy WordPress example that listens via a Unix socket when using php-fpm, refer to The Caddyfile.

Not really that thrilled with the last sentence. I think it can be improved. Suggestions welcome.

Maybe…

For a WordPress example that listens via a Unix socket when using php-fpm, refer to The Caddyfile in the Caddy documentation.

I think I’d avoid linking to that page in the docs, it would be confusing rather than useful. Just explain what a unix socket address would look like (i.e. unix//var/run/php-fpm.sock or something to that effect).

Otherwise, LGTM

1 Like

A WordPress doc update request has been submitted here HTTPS for WordPress using Caddy

This topic was automatically closed after 30 days. New replies are no longer allowed.