A comprehensive "WordPress + WP Super Cache" caddyfile example

This “caddyfile” should work fine for general WordPress website setup.

Remember to turn on “WP Super Cache → Expert” to maximize the performance (The rewrite is ready to serve static cached files. You can ignore the “no apache .htaccess rewrite” warnings)

If you use another caching plugin instead of “WP Super Cache”, change the below path “/wp-content/cache/supercache/{host}{uri}” to the path your plugin uses.

Big thanks to the team work in Help set up a WordPress bypass with a static cache - #16 by nicolinux , a big part of this example are from their discussion result.

# Globals options:
{
	experimental_http3
	email your-email@for-tls.com
	admin off
}

#===========================================#

# Wordpress snippet starts here

(wordpress) {

	# Redirect to remove "www." since wordpress doesn't
	# like multi-domain visits.
	@strip_www {
		header_regexp www Host ^www\.(.*)$
	}
	redir @strip_www https://{http.regexp.www.1}{uri}

	# Some static files Cache-Control.
	@static {
		path *.ico *.css *.js *.gif *.jpg *.jpeg *.png *.svg *.woff *.json
	}
	header @static Cache-Control max-age=2592000
	
	# Cache rewrite to meet WP Super Cache "expert mode" requrements.
	@cache {
		not header_regexp Cookie "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_logged_in"
		not path_regexp "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(index)?.xml|[a-z0-9-]+-sitemap([0-9]+)?.xml)"
		not method POST
		not expression {query} != ''
	}
	route @cache {
		try_files /wp-content/cache/supercache/{host}{uri}/index-https.html /wp-content/cache/supercache/{host}{uri}/index.html {path} {path}/index.php?{query}
	}

	# Use this header if you use something like WPML
	# If you are running a single domain simple site you can remove this.
	header Access-Control-Allow-Origin *

	# Standard services here.
	# Remember to modify php_fastcgi point to your fastcgi address or unix socket
	file_server
	encode zstd gzip
	php_fastcgi localhost:9000
}

#===========================================#

# Here are your 3 wordpress sites.
# You can run many wordpress sites easily by
# importing the "wordpress" snippet above:

wordpress-site-01.com, www.wordpress-site-01.com {
	root * /home/user/public_html/site01
	import wordpress
}

wordpress-site-02.com, www.wordpress-site-02.com {
	root * /home/user/public_html/site02
	import wordpress
}

wordpress-site-03.com, www.wordpress-site-03.com {
	root * /home/user/public_html/site03
	import wordpress
}
4 Likes

Well, I was just going to write a Wiki post with just the configuration to bypass WordPress, it seems you beat me to it. :slight_smile:

I still think a simpler example would be useful, but I’m not sure it needs a different Wiki entry. A thought @matt ?

1 Like

How fast are you :grinning:? I have just posted this 3 minutes ago and your reply is here.
And thank you so much you have no idea how much your config file in another post helped me set up my own sites. And yea you are more qualified to create this post.

Don’t worry, most users are very good at stripping/modifying the code that they don’t like (and usually are very terrible at adding new ones :grin: like me)

I am thinking of collecting all the popular “cache plugins” cached statics paths, and add all of them into the “try_files”, to make this caddyfile a “universal” wordpress config file.

Discourse has great notifications, in fact. :slight_smile:

I was just writing a wiki page with a stripped WordPress setting for each popular cache plugin. I think I will publish it and we can all edit/expand it.

Your idea to create one big configuration is interesting, but I’d rather have one specific config file just for my system. We could easily do both though…

So, here it is : Example: configure WordPress with a static cache

I have used your confirmed version, added it to mine, and guessed what it should be for two other plugins. We can add more later.

Let me know what you think.

Yeah I think I like the format of the other one better. If you guys don’t mind, I’ll move this thread out of the wiki category :+1:

1 Like

Nahh, I don’t mind you move this out of wiki :joy:.

This “all in 1 snippet” format just meet my own need (running 25 small websites on 1 caddy server) that I want to keep each “site block” as slim as possible.

Go move it to somewhere else that it seems fit. Maybe some server manage person will find this helpful.

1 Like

I’m not so sure about this. I mean, I believe you do 100%, but I had a bit of a back-and-forth with some users in another WordPress-related thread regarding some apocryphal rewriting requirements that I believe weren’t fully understood by the other parties, yet they were quite attached to them. Generally with the Caddyfile as well, the simpler the better. Not only for actual function (a significant fraction of help I dole out for people here essentially boils down to helping people remove over-complexity that’s causing issues), but for discoverability and learning from it, too.

4 Likes

Hey @Whitestrake
First of all, I fully agree with what you have just said.

But I think we are talking about like a different layer of things. What I mean is something like eg.

{
	experimental_http3	
}

Many new users don’t even know this switch exist. But NOW they know, they can easily choose to leave it, or remove it;

Also some thing like :

header @static Cache-Control max-age=2592000

Please don’t laugh at me :joy: I didn’t even know cache-control can be easily done using a named matcher like this until I saw @nicolinux 's example. Now I can choose to use it, or delete it.

Without a big and full example, many “functions” and “methoeds” will never be found out by users (very few users will go through all the docs and think out of all kinds of new solutions)

It is because we are too good at it, we often failed to look at the things from a new users’ perspective.

2 Likes

You’re not wrong. But my fear, specifically, is that people will (irrationally) link the varied parts and snippets you’ve combined for your site, conceptually, as being required for their use case.

To you and I, it’s obvious that you don’t need to set Cache-Control to max-age=2592000 in order to run WordPress with Super Cache. You could set it to some other number, or even exclude it entirely, it’s not functionally required at all.

But someone who doesn’t know much about Cache-Control, why it’s there, or what it does, will very quickly assume it’s just one part of the config necessary for the site to run. They’ll never touch it, and if and when they share their configs onwards, they will include it.

Likewise for experimental_http3. I mean, I don’t even understand HTTP3 all that well, to be honest. But a newbie might just think, “oh it’s just more config needed to run a WordPress site”.

I’d rather have a Wiki entry that explains what Cache-Control is, why you’d want it, and some examples of how to configure it. That wiki would purely talk about Cache-Control, and wouldn’t include arbitrary other config snippets (except maybe when highlighted as part of another full configuration - in which case maybe the other arbitrary Caddyfile patterns present could have links to their own wiki parts).

All above being my personal opinion, of course.

4 Likes

Yea, but a really good one.

I think it’s important to keep demonstrations and examples as minimal and unopinionated as possible. Good tutorials don’t throw in extra stuff just because. We’d like to avoid the problems that decades of unscoped, unexplained apache + nginx tutorials have caused.

@Kyle_Chen Not to come off as unappreciative. I think we should help users understand Cache-Control and experimental_http3, but in their own tutorials, etc.

1 Like

I’m a fan of the term minimal and unopinionated.

I’m also a fan of the term discoverable, which I think is the thrust of what @Kyle_Chen is trying to emphasize. The more I think about it, the more I think it’s important for wiki entries to cross link. Specifically, a hypothetical wiki page dedicated to a common Caddyfile pattern like setting Cache-Control should ideally include, at the end, a site config that includes Cache-Control within, say, a working WordPress config and then link to the WordPress config wiki.

A good wiki entry would also discuss, in its body, other config patterns you might find in conjunction with its own topic and link to them, too.

Wiki walking is a great tool for learning and discoverability. Our wiki category is still in its baby stages, I hope to see it grow effectively and become a great tool for discovery along the lines Kyle is trying to create. I just think presenting arbitrary, strictly unnecessary config in a use-case based wiki entry (especially without actually giving them the elaboration they deserve - in the original post, those extras are basically just there without explanation) is not the right way to do it.

1 Like

True!

Very true!

Later on, I also feel this example fits in “Production use” better than the wiki. No issue here. :sweat_smile:

3 Likes

We can also do a better job of cross-linking relevant features in the docs, we did a bit of that this weekend by adding php_fastcgi <-> root <-> file_server links.

If you can think of any specific places where that can be improved, we’re all ears :smile:

1 Like

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