Caddy, a Web Server implemented with Go

Source: Internet
Author: User
Tags php server
This is a creation in Article, where the information may have evolved or changed.

This is a Web server era, apache2 and Nginx dances, in the pursuit of extreme performance on the road, there is no highest, only higher. But this is another era of the pursuit of personalization, some Web server did not squeeze the "performance Ascension" of the single-plank bridge, but has its own positioning, caddy is such an open source Web server.

Caddy's author, Matt Holt, explains the goals of Caddy in Caddy's official website and FAQs: Other Web servers are designed for the web and caddy for human. Functional positioning, unlike nginx, which often acts as the front-end reverse proxy, Caddy is committed to becoming an easy-to-use static file Web Server. You can see that caddy is easy to use and easy to configure. And thanks to the cross-platform features of Go, Caddy easily supports three main platforms: Windows, Linux, Mac. In the Caddy developer documentation, we can see that caddy can also run on Android (Linux arm). Caddy current version is 0.7.1, is not stable, and subsequent versions may vary significantly, or even incompatible with previous versions, so the author does not recommend that caddy be used heavily in the production environment at this time.

Focus on Caddy, because caddy fills the blank of go in general Web server (perhaps there are other, but I don't know), and Web server in Go also "responds" to the recent trend of Golang to C (Go 1.5 C is gone! , even if the Caddy author mentions that Caddy's goal is not as nginx. But who knows about the future? Once the go performance is high enough, once the caddy is stable enough, it is natural for someone to replace Nginx or apache2 in the production environment of some applications. A full go system, there are advantages in the deployment, operation and maintenance.

First, installation and operation of Caddy

As with many go apps, we can find the latest release (currently 0.7.1) binary package directly from Caddy's github.com releases page. The Caddy_darwin_amd64.zip is used here.

After downloading the extract, go to the directory and execute it directly./caddy can run the caddy.

$caddy
0.0.0.0:2015

Access localhost:2015 in the browser, there is no similar "Caddy works!" on the page that is expected to appear such as the default Welcome page, instead of "404 Not Found". Although this shows that Caddy has worked, but not a default welcome page after all, for Caddy Beginer is not friendly. A sugguestion issue has been presented to the author here.

Second, the principle of caddy

Go's net/http Standard library has already provided the HTTP server implementation, in most cases this HTTP server can meet your needs, whether it is functional or performance. Caddy is essentially a go web app, it also imports net/http, embedded *http. Server and service each request through the handler Servehttp method. Caddy uses HTTP. Fileserver as the basis for handling static files. Caddy's allure lies in its middleware, which has strung many middleware into a middleware chain to provide a flexible Web service. In addition, the middleware in caddy can be used independently of the caddy.

Caddy reads the configuration from the Caddyfile (default) file of the current directory, but you can also specify the profile path by-conf. Caddyfile's configuration format is really easy, which is also in line with Caddy's goal.

Caddyfile always start with the addr of the site.

The caddyfile example for a single site is as follows:

Caddyfile
localhost:2015
Gzip
Log./2015.log

Caddy also supports configuring multiple sites, similar to the VirtualHost configuration (80 port multiplexing):

Caddyfile
foo.com:80 {
Log./foo.log
Gzip
}

bar.com:80 {
Log./bar.log
Gzip
}

In order to achieve style uniformity, a single site is also best configured as the following format (called Server Block within the code):

localhost:2015 {
Gzip
Log./2015.log
}

This way the Caddyfile profile template style resembles the following:

Host1:port {
Middleware1
Middleware2 {
... ...
}
... ...
}

Host2:port {
Middleware1
Middleware2 {
... ...
}
... ...
}
... ...

For middleware, there are more detailed explanations and examples in the Caddy documentation. For a young open-source project such as caddy, its documentation is relatively complete, although it can not be compared with Nginx, Apache.

Caddy in the middleware is a realization of the middleware. Handler interface of the struct, for example gzip this middleware:

Middleware.go
Type middleware func (Handler) Handler
Type Handler Interface {
Servehttp (http. Responsewriter, *http. Request) (int, error)
}

Gzip/gzip.go
Type Gzip struct {
Next Middleware. Handler
}

Func (g Gzip) servehttp (w http. Responsewriter, R *http. Request) (int, error) {
If!strings. Contains (R.header.get ("accept-encoding"), "gzip") {
Return G.next.servehttp (W, R)
}
.... ...
GZ: = Gzipresponsewriter{writer:gzipwriter, responsewriter:w}

Any response in forward middleware'll now be compressed
Status, Err: = G.next.servehttp (GZ, R)
... ...
}

Middleware. The function prototype of handler is different from the Http.handler, and cannot be used directly as the handler of Http.server. Caddy uses the following idiomatic go pattern:

Type Apphandler func (http. Responsewriter, *http. Request) (int, error)

Func (FN Apphandler) servehttp (w http. Responsewriter, R *http. Request) {
If status, err: = FN (W, R); Err! = Nil {
http. Error (W, err. Error (), status)
}
}
Of course there are many variants of this pattern, but the idea is roughly similar. A middleware chain is roughly handler1 (Handler2 (HANDLER3)) call passing.

As I said earlier, Caddy is HTTP-based. Fileserver static file Web Server,fileserver will always be the last ring of middleware chain, if you do not configure any middleware, then your Server is a static file server.

Iii. Typical application of caddy

"Static file Server"

The most basic application of caddy is actually a static file server, the underlying is HTTP. Fileserver is hosted, and of course the Caddy encapsulates HTTP. Fileserver, did some interception processing, and finally passed W, R to HTTP. Servecontent to process file data.

The first time you execute the./caddy, a static file server is actually started. But this server does not support you navigate directory by default. If you know the website root directory (if you do not specify root, the current path executed by caddy will be the file name under the website root path), such as Foo.txt, which you can enter in the browser: localhost:2015/ Foo.txt,caddy will perform the correct service and the browser will display the full text of foo.txt.

For static file Server,caddy support, under the root path of website, first look for the following four files:

Caddy/middleware/browse/browse.go
var indexpages = []string{
"Index.html",
"Index.htm",
"Default.html",
"Default.htm",
}

If there is one, then the priority is to return this file content, this is the home page of the static site.

If you want to support directory file list browsing, you need to configure browse middleware for website, so we can see a list of directory files for directories without index file.

localhost:2015 {
Browse
}

"Reverse proxy"

The Caddy supports basic reverse proxy functionality. The reverse proxy configuration is implemented via proxy middleware.

localhost:2015 {
Log./2015.log

Proxy/foo localhost:9001
Proxy/bar localhost:9002
}

When you visit Localhost:2015/foo, you actually access the 9001-Port service program;
When you visit Localhost:2015/bar, you actually access a 9002-port service program.

"Load Balancing"

The caddy supports load balancing configurations and supports three load-balancing algorithms: Random (Random), least_conn (minimum connection), and Round_robin (polling scheduling).

Load balancing is also achieved through proxy middleware.

localhost:2015 {
Log./2015.log

proxy/localhost:9001 localhost:9003 {
Policy Round_robin
}
Proxy/bar localhost:9002 localhost:9004 {
Policy Least_conn
}
}

"Support FASTCGI Agent"

Caddy also supports the FASTCGI proxy, which can send requests through the FASTCGI interface to the backend implementation fastcgi server. Let's take the example of a "Hello World" PHP server.

Mac OS comes with PHP-FPM, a PHP CGI process manager that implements the fastcgi. The Caddy forwards the request to the PHP-FPM listening port, which initiates the PHP-CGI interpreter, interprets the index.php, and returns the result to caddy.

PHP-FPM on Mac OS is not randomly started by default. We need a simple configuration:

$mkdir Phptest
$mkdir-P PHPTEST/ETC
$mkdir-P Phptest/log
$CD Phptest
$sudo Cp/private/etc/php-fpm.conf.default. etc
$CD. etc
$sudo chown Tony Php-fpm.conf.default
$MV Php-fpm.conf.default php-fpm.conf

Edit php-fpm.conf to ensure that the following two items are non-annotated:

Error_log = Log/php-fpm.log
Listen = 127.0.0.1:9000

We use the network socket for fastcgi communication.

Go back to the Phptest directory and execute:

Php-fpm-p ~/test/go/caddy/phptest

After execution, the PHP-FPM will be transferred to the background to execute.

Next we configure the Caddyfile:

localhost:2015 {
fastcgi/127.0.0.1:9000 PHP
Log./2015.log
}

The meaning of this configuration is: forward all requests to Port 9000, where PHP is a preset (preconfigured collection), equivalent to:

Ext. php
Split. php
Index index.php

We create a index.php file in the Phptest directory with the following content:

OK, now start caddy, and use the browser to access localhost:2015 try it. You will see "Hello World" appearing in the browser.

"Git Push release"

For some static sites, Caddy supports GIT directive, enabling regular Git pull to your project library at server startup and runtime, pulling the latest updates to the server.

Two examples are given in the Caddy documentation:

The first one is a PHP site that periodically pull the project library to implement the server update:

Git git@github.com:user/myphpsite {
Key/home/user/.ssh/id_rsa
}
fastcgi/127.0.0.1:9000 PHP

The second one is a static site that Hugo supports, and after each pull, execute the Hugo command to generate a new static page:

Git github.com/user/site {
Path: /
Then Hugo–destination=/home/user/hugosite/public
}

Note: git directive is not middleware, but a separate goroutine implementation.

Iv. Summary

Caddy's function is not limited to the above examples, which are just a few of the most common scenarios. Caddy is still very young, the application is not many, but the well-known Golang site gopheracademy.com (Gophercon organization) is caddy support. Caddy is also actively evolving, with an interest in gopher sustainable attention.

Bigwhite. All rights reserved.

nd-https/"rel=" bookmark "title=" Go and HTTPS ">go and HTTPS
  • Build Your own Ngrok service
  • Using squid to build HTTP proxies
  • Related Article

    Contact Us

    The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

    If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.