前言

Caddy 是一款用golang编写的轻量级web server

老早就看到caddy web server,但是找不到去用的理由,因为nginx足够好
如果用docker打包应用,如果要实现跑php php-fpm应用且要单容器,用nginx就不太爽了
一般用php官方docker镜像作为base,然后在上面再装nginx,nginx复杂的编译环境非常麻烦
试用了下 caddy,他就没那么麻烦,还是用php官方docker镜像,然后只需要简单的几行就可以把caddy加进去
非常特别的一点是caddy自带php-fpm的进程启动
在配置文件中增加on startup php-fpm —nodaemonize 即可
容器的入口只需要启动caddy即可,caddy可以自动启动php-fpm进程
目前发现唯一的问题是caddy对个人免费,对公司和商业收费,价格还非常贵
下面是一些参考文件

Dockerfile 参考

FROM php:7.2-fpm-alpine

LABEL version="7.2" \
    description="php-fpm7.2 alpine" \
    maintainer="wwek<licoolgo@gmail.com>"

# 国内源
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
# 系统基础包
RUN apk update \
    && apk upgrade \
    # && apk add s6 \
    && apk add bash \
    # && apk add openssl \
    # && apk add openssl-dev \
    && apk add ca-certificates \
    #&& apk add wget \
    && apk add curl \
    #&& apk add tcpdump \
    && apk add iputils \
    && apk add iproute2 \
    && apk add libc6-compat \
    && apk add zlib \
    && apk add -U tzdata \
    && apk add libpng \
    && apk add libpng-dev \
    #&& apk add libstdc++ \
    && rm -rf /var/cache/apk/*

# 系统设置(设置时区)
RUN rm -rf /etc/localtime \
    && ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" /etc/timezone

# --- PHP --- #
## PHP Core核心扩展
RUN docker-php-ext-install opcache mysqli pdo_mysql mbstring zip pcntl gd
## 三方扩展
## redis
RUN set -xe \
    #&& apk add --no-cache --update --virtual .phpize-deps $PHPIZE_DEPS \
    && apk add --update --virtual .phpize-deps $PHPIZE_DEPS \
    && pecl install -o -f redis  \
    #&& pecl install -o -f swoole  \
    && echo "extension=redis.so" > /usr/local/etc/php/conf.d/redis.ini \
    #&& echo "extension=swoole.so" > /usr/local/etc/php/conf.d/swoole.ini \
    && rm -rf /usr/share/php \
    && rm -rf /tmp/* \
    && apk del  .phpize-deps


# 增加 PHP 配置文件
ADD docker/www.conf /usr/local/etc/php-fpm.d/
ADD docker/php.ini /usr/local/etc/php

##  PHP设置
# 设置php运行权限为母鸡中 www的用户和组 1000:1000
# RUN addgroup -g 1000 -S www && \
#     adduser -u 1000 -S www -G www www

# 设置php-fpm运行账户和组为 www www
# RUN set -ex \
#     && cd /usr/local/etc \
#     && { \
#         echo 'listen.owner = www'; \
#         echo 'listen.group = www'; \
#         echo 'listen.mode = 0660'; \
#     } | tee php-fpm.d/www.conf

# -- Caddy -- #
## 安装 Caddy Web Server
#RUN curl -sSL -o- "https://caddyserver.com/download/linux/amd64?plugins=http.jwt,http.login,http.prometheus,http.realip,http.restic,http.expires&license=personal&telemetry=off" | tar -xvz -C /usr/bin/
RUN curl --silent --show-error --fail --location \
    --header "Accept: application/tar+gzip, application/x-gzip, application/octet-stream" -o - \
    "https://caddyserver.com/download/linux/amd64?plugins=http.jwt,http.login,http.prometheus,http.realip,http.restic,http.expires&license=personal&telemetry=off" \
    | tar --no-same-owner -C /usr/bin/ -xz caddy \
    && chmod 0755 /usr/bin/caddy \
    && /usr/bin/caddy -version

## 增加 Caddy 配置文件
ADD docker/Caddyfile /etc/Caddyfile


# -- APP -- #
## APP环境变量
ENV APPROOT="/data/wwwroot/www.iamle.com/" \
    PHP_MYSQL_HOSTNAME='' \
    PHP_MYSQL_DATABASE='' \
    PHP_MYSQL_USERNAME='' \
    PHP_MYSQL_PASSWORD='' \
    PHP_MYSQL_PORT='' \
    PHP_REDIS_HOST=''

## APP增加
RUN mkdir -p $APPROOT
COPY ./ $APPROOT


## APP配置
WORKDIR $APPROOT
# 巴拉巴拉 APP 配置修改


## APP 权限
## APP设置文件权限 这里的82为php-fpm容器中的 www-data的 usreid 和groupid
RUN chown -R www-data:www-data $APPROOT
#RUN chown -R 82:82 $APPROOT

# 入口
CMD ["/usr/bin/caddy", "--conf", "/etc/Caddyfile", "--log", "stdout"]

Caddyfile 参考

0.0.0.0:80
log stdout
errors stdout

root /data/wwwroot/www.iamle.com/public/

fastcgi / 127.0.0.1:9000 php {
    ext   .php
    split .php
    index index.php
}

rewrite {
    to {path} {path}/ /index.php?s={uri}
}

on startup php-fpm --nodaemonize

www.conf

[www]
prefix = /var/
user = www-data
group = www-data
listen = 127.0.0.1:9000
;listen.backlog = 511
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
;listen.acl_users =
;listen.acl_groups =
;listen.allowed_clients = 127.0.0.1

pm = dynamic
; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
pm.max_children = 100
; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
pm.start_servers = 20
pm.min_spare_servers = 20
pm.max_spare_servers = 100
;pm.process_idle_timeout = 10s;
pm.max_requests = 50000
;pm.status_path = /status

;ping.path = /ping
;ping.response = pong

;access.log = log/$pool.access.log

;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"

slowlog = log/$pool.slow.log

request_slowlog_timeout = 30

;request_terminate_timeout = 0

;rlimit_files = 1024

;rlimit_core = 0

;chroot =

;chdir = /var/www

catch_workers_output = yes

;clear_env = no

;security.limit_extensions = .php .php3 .php4 .php5 .php7

;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp


;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M

其他

在dockerfile中,是直接下载的caddy二进制程序,这个会受到caddy的授权协议影响,对个人免费,对商业收费
如果是基于源码自己编译安装那么就只需要遵守Apache license协议即可,即可以用于商业

常见应用框架配置参考
https://github.com/caddyserver/examples

cady缺省(占位符)变量
https://caddyserver.com/docs/placeholders