Caddy Frequently Asked Questions (FAQ)

2021 update: This thread is a popular search result, but 5 years later, is now obsoleted because it was about Caddy v1. Please refer to our official documentation and latest wiki articles instead.

Please do not ask for help in this thread. Limit discussion to this FAQ only. Thanks!

How can I install Caddy from the command line?

The easiest way is to use curl or wget to install Caddy. Simply follow the instructions at (Note that custom builds may take several seconds or minutes before the download begins.) A plain install is as easy as:

$ curl | bash

If the build server is down entirely, you can download static releases from GitHub.

Do I have to run Caddy as root to serve on port 80 or 443?

No. On Linux, you can use setcap to give Caddy permission to bind to low ports. Something like setcap cap_net_bind_service=+ep caddy should work. Consult the man pages of your OS to be certain. You could also use iptables to forward to higher ports, or use systemd for similar benefits.

It’s possible that a future version of Caddy will implement privilege de-escalation, but it will likely require spawning a new process.

Why does Caddy need ports 80 and 443?

These ports are required by the ACME specification to solve challenges for your TLS certificates. Even though your site is served over HTTPS on port 443, it needs port 80 to redirect HTTP traffic to HTTPS.

How do I run Caddy in the background?

Caddy is just like any other process or command.

You can run it in the background with nohup caddy &. To keep Caddy running after system restarts, you might want to add a cron job like @reboot nohup caddy &. However, individual needs and systems vary widely, so we (the project maintainers) expect you to know how to administer your system. You are of course welcome to discuss it on these forums.

How can I make a virtual host that serves files only under a specific path?

With Caddy 0.9+, site addresses can be scoped to a base path: {

Can you translate my .htaccess or nginx.conf to Caddyfile?

First, consult the Caddy documentation for the directives you can use that might do what you need. If you still need help, feel free to ask on these forums. Make sure you show what you’ve already tried, and explain specifically what you’re stuck on!

Note that not all concepts of .htaccess or nginx.conf translate to a Caddyfile. Keep in mind that some settings are implicit with Caddy, and other features are not available at all (for better or for worse).

Why does Caddy take all my sites down if just 1 domain fails to resolve?

This is a common misunderstanding; Caddy doesn’t take your sites offline. When you are starting Caddy and there is an error with your configuration (for example, one of your domains is invalid), Caddy refuses to start, but that does not take your sites down; there are no sites to take down, since Caddy was not previously running. When you reload a new configuration by signaling USR1, Caddy rolls back to the previous working configuration if the new one is invalid, which keeps your existing sites online with zero downtime. Read more in this thread.

What is the best way to run a Python site with Caddy?

For now, use the proxy directive to reverse-proxy to a WSGI web server such as uWSGI or Gunicorn. There has been plenty of interest building WSGI support into Caddy, so if anyone implements this in pure Go, you may not have to proxy like this forever.

How do I take advantage of multiple CPU cores with Caddy?

Whether your site is busy and big or slow and small, Caddy will take care of this – you don’t have to worry about it, and there’s nothing for you to configure. Go’s scheduler is very good and will use all cores to the maximum efficiency as needed. (You can use the -cpu flag to limit the number of cores Caddy uses, but this would only be useful if your site is very busy and you’re sharing CPU resources with other active processes.)

How do I test the validity of the Caddyfile before using it?

Run Caddy with the -validate flag, and Caddy will report Caddyfile errors without executing it.

How do I update the Caddyfile while Caddy is running?

Caddy loads the Caddyfile once when it starts, and it won’t see changes to the Caddyfile unless you reload it. You can do that either by stopping and restarting the process, or on Unix systems, you can signal it with USR1 (kill -SIGUSR1) for a graceful, zero-downtime reload.

How do I build Caddy with plugins on my own?

All you have to do is edit run.go and add an import to the plugin’s package:

import _ "your/plugin/package/path/here"

Then re-compile Caddy with ./build.bash for proper version information to be embedded, or go build as usual.

How do I serve PHP files with Caddy?

All you have to do is set up php-fpm like you normally do as with, say, nginx, then add something like to your Caddyfile:

fastcgi / php

This tells Caddy to proxy all requests (i.e. requests starting with /) to via FastCGI, and using the php preset configuration. Consult this wiki page if you have trouble.

Got other questions? Search the forum. If it hasn’t been asked before, create a new topic to ask your question!


Hey all,
I already mentioned this on gitter. I collected some FAQ over the last months, and just that these won’t get lost, here’s the list:

  • How do I update caddy automatically?
  • I want caddy to proxy to wildcard domain?
  • Can you translate my .htaccess or nginx?
  • Is it possible to have a vhost that serves files only under a path?
  • Can I get caddy to act as a reverse proxy?
  • xyz doesn’t work
  • Is there an existing docker-container?
  • How to configure Caddy with [xyz-php-framework]
  • Setup caddy with nginx reverse proxy and letsencrypt
  • What is the best way to run a python site with caddy?
  • Where can I find caddy doing this nginx-option, apache-feature-xyz or that jenkins-setting?
  • Huh, what’s wrong? I get:
    Activating privacy features... and failed to get certificate: acme: Error 0

Unfortunately because I’m not really a native caddyzen, I’m not able to answer these adequate and profound.
Overall I hope this will get the place to-look-first and relieve in answering same questions again and again.

thx for installing this forum. This way’s so much, much more comfortable than searching gitters history. Great.
Caddy’s growing up :wink:

1 Like


If I am running a static site using hand-crafted HTML/CSS/JS (my content does not lend itself well to Markup currently) and I maybe have something like bleve (need to look into this further) for search facilities, will I in any way benefit by having multiple cores using caddyserver?

I know that golang is purposely pointed at using multiple cores, but I have zero clue of how this all works with a small caddyserver install.

1 Like

Thanks @vedam and @z00000mer - I’ve updated the FAQ with a few more questions based on your suggestions!

1 Like

@vedam, I have started writing up a basic translation guide from .htaccess to Caddyfile up on my own blog here :

The first post may interest you. Please let me know what all you think is missing(there’d be tons, I know) either here at the forums or through the comments section of my blog :slight_smile:

I think the FAQ should be on a separate page like I guess to the forum and more importantly each question should be able to be hyperlinked.


@hendry I like the idea of linking to the FAQ from the site/docs, and I think I’ll move things around a little bit when Caddy gets a new website. I also think linking to headers in forum posts is something that the Discourse folks are working on. It will be possible soon, hopefully!

Is there a discussion on that? Should I open one?
Anyways, I don’t know where to place this else, but I think this is a really nice example/inspiration for a site-design: otto

In my opinion an identity/brand is much more than a logo and that site demonstrates that impressingly.
As I told elsewhere I’m willing to help on the designpart, being it Corporate Design, UI or site.

And yes. I know design is the last thing @matt should waste thoughts at the moment, 0.9’s on the way :slight_smile:

Is there a method to test the configuration file before starting / attempting a reload?

Added to the FAQ.

Disclaimer: I’ve just started experimenting with caddy.

Shouldn’t the FAQ say that caddy must be restarted in order to make a change in Caddyfile effective? If my understanding is correct… I’ve added the errors directive while caddy was running and the error log file was not created; only after I restarted caddy.service it appeared.
I could not find anything on this subject in the docs.

Good idea, I’ll add that to the FAQ.

1 Like

@matt Plugins (I mean, other than default) are an essential part of Caddy. I’d add an entry about it.

I wonder also what’s the best way to handle them. Let’s say I want to remember which plugins I need to install for my server, so I can install them again when I need a new build.
AFAIK, I can install further plugins only via the website. The curl | bash does not offer any option.

In this thread (now closed), you suggest to use an import. Does it mean that I need to “fork”/branch the caddy repo and change the run.go to get an easy repeatable installation?

I hope there could be an easier way. I’m missing something?

@matt Let me suggest another entry: how to serve PHP files (using php-fpm).

Probably a brief explanation and a link to the wiki page would be enough.

With regard to the wiki page, I think it would be worth pointing out that if listen.acl_users is not commented (which is the case, at least on my system), listen.owner and will be ignored. So better add the user to listen.acl_users instead.

Here’s the default on my /etc/php-fpm.d/www.conf (Fedora 26):

; When POSIX Access Control Lists are supported you can set them using
; these options, value is a comma separated list of user/group names.
; When set, listen.owner and are ignored
listen.acl_users = apache,nginx

Dealing with plugins is definitely a good question, I’ll try to add that today if I have the chance, and address your questions, because I’ve seen them before too.

I’ll see what we can do to fit php-fpm stuff into the Caddy FAQ too.

@matt Thanks

I realize only now that I didn’t pay attention to the bottom part of the download page. If I want to update a binary including the plugins I need, I can use the -s option, e.g.:

curl | bash -s http.filemanager,http.hugo