A month ago I wrote about an exciting open source project called Caddy. In case you missed it, you can catch it here. The project offers a lightweight, powerful web server aimed at lowering the technical barrier to entry for just about anyone wanting to serve content from a self hosted web server. In this post I want to cover how to setup the Caddy web server to serve PHP pages. I’ll be configuring Caddy to use php-fpm. I encourage you to follow along in your own dev environment.
Requirements:
Ubuntu 14.04
curl
php-fpm
Caddy web server binary (download)
Let’s begin.
Open a terminal on your Ubuntu 14.04 server or desktop and install php, php-fpm, and curl:
sudo apt-get install php5-fpm php5-cli curl
Once you’ve downloaded the Caddy binary, extract it:
sudo mkdir /opt/caddy-server; sudo tar xvzf caddy_linux_amd64_custom.tar.gz -C /opt/caddy-server
Create the docroot we’ll be using for this example, and give yourself perms to write to it:
sudo mkdir /opt/caddywww; sudo chown `whoami` /opt/caddywww
Now let’s make a Caddyfile. A Caddyfile is Caddy’s configuration file. We’ll create this file:
/etc/Caddyfile
With this text:
:80 tls off root /opt/caddywww gzip log /var/log/caddyaccess.log errors /var/log/caddyerror.log fastcgi / /var/run/php5-fpm.sock php
If you’re used to configuring Nginx or Apache, the format of this file will look unfamiliar. Once you’ve configured a few options in a Caddyfile, you’ll get the hang of it pretty fast. The documentation makes it easy to reference the functionality you’re looking for. Let’s sidetrack for a minute, and discuss the Caddyfile and each of the directives, to briefly explain what they mean.
This line tells Caddy to answer on port 80, no matter how it’s called.
:80
If you want to lock it to a virtual host definition you would simply change this to the following, which will tell Caddy to only answer if port 80 was accessed using example.com. Any other request using a different hostname would receive an error from Caddy.
example.com:80
The following tells Caddy to disable serving sites over TLS. I’m putting this here, because Caddy will automatically setup a certificate with Let’s Encrypt if you use a valid and registered domain name for your site. This is a very cool feature, but for the purposes of this demo, I’m leaving it out. I’ll cover this on a future blog post.
[ UPDATE: Matt (author of Caddy) has pointed out that since we are explicitly defining port 80, we don’t actually need this, but we can leave it in to be explicit. ]
tls off
This is the docroot where our php and html files will go:
root /opt/caddywww
This tells Caddy to enable gzip compression with default values. You can set more specific options, like file types or compression level, but for this example, default settings are fine:
gzip
Set your access log:
log /var/log/caddyaccess.log
Set your error log:
errors /var/log/caddyerror.log
This tells Caddy how to talk to your php5-fpm service. First it directs all requests from the root of your site to the php-fpm socket using the php preset:
fastcgi / /var/run/php5-fpm.sock php
If you need to configure your php settings with more granularity, you can use the fastcgi directive in the following way. The breakdown for each option is: If the requested file has the .php extension use fastcgi proxy(ext), store anything after .php in the PATH_INFO CGI variable(split), and check for index.php if no file is specified in the URL(index). These are also the default settings for the php preset.
fastcgi / /var/run/php5-fpm.sock { ext .php split .php index index.php }
The Caddyfile, while simple in syntax, can also provide advanced features. One useful feature is the ability to describe virtual hosts. A very simple example of defining two virtual hosts in a Caddyfile would be like this:
myfirstsite.com:80 { root /www/myfirstsite.com gzip tls off } mysecondsite.com:80 { root /www/mysecondsite.com gzip tls off }
Alright let’s get back to the task at hand. At this point we should configure some php items. We’ll leave the default config for php5-fpm alone, but for convenience let’s make sure short_open_tag is set to On in the PHP config. You’ll edit the following file to make that change:
/etc/php5/fpm/php.ini
Line 212 reads:
short_open_tag = Off
Change it to:
short_open_tag = On
Now let’s restart php-fpm*:
sudo restart php5-fpm
*this should already be started, restarting should grab the new php.ini changes.
Alright, time to start Caddy:
sudo /opt/caddy-server/caddy -conf="/etc/Caddyfile"
You should see:
Activating privacy features... done. :80
**On a fresh system you may get this error message:
Warning: File descriptor limit 1024 is too low for production sites. At least 4096 is recommended. Set with "ulimit -n 4096".
You can either run that command, or just leave it. For this example, it’s fine. If you’re running this in production, of course you’ll want to increase the file descriptor limit.
Now let’s leave that terminal alone, start a new one, and create a small file in our docroot to make sure PHP is working. Create:
/opt/caddywww/index.php
With:
<? echo 'PHP version: ' . phpversion() . "\n" ?>
I threw the new line in there at the end so that when you use curl to request this page, you’ll get a clean prompt back.
Now run it:
curl localhost:80
You should see:
PHP version: 5.5.9-1ubuntu4.14
And if it worked, congrats, you’ve just setup Caddy with PHP support! Not bad huh? When I attempted this, it worked on my first try. How many of you have had that happen the first time you tried setting up php-fpm with Apache or Nginx? Caddy makes it easier for sure.
Thanks for reading!
[ UPDATE: For those of you who want a simple init.d script to start Caddy so it runs in the background, I’ve added one here: https://github.com/nortone/caddythings.
Also, Caddy has released a PHP-FPM FastCGI troubleshooting page here in case you have any issues: https://github.com/mholt/caddy/wiki/Troubleshooting-PHP-FPM-and-FastCGI ]
-
https://twitter.com/mholt6 Matt
-
http://shad.me Shad Mickelberry
-
http://depado.markdownblog.com Depado
-
Eric
-
-
Eric
-