commit
93b32220f1
@ -0,0 +1,35 @@
|
||||
FROM golang:1.13-alpine as builder
|
||||
RUN apk add --no-cache git gcc musl-dev
|
||||
RUN mkdir /www /caddy
|
||||
COPY builder.sh /usr/bin/builder.sh
|
||||
ARG version="1.0.5"
|
||||
ARG enable_telemetry="true"
|
||||
RUN VERSION=${version} /bin/sh /usr/bin/builder.sh
|
||||
|
||||
|
||||
FROM alpine:latest
|
||||
|
||||
ENV CADDY_VERSION=1.0.5
|
||||
|
||||
ENV CADDYPATH=/caddy/certs
|
||||
|
||||
RUN apk add --no-cache \
|
||||
ca-certificates \
|
||||
git \
|
||||
mailcap \
|
||||
openssh-client \
|
||||
tzdata
|
||||
|
||||
|
||||
COPY --from=builder /install/caddy /usr/bin/caddy
|
||||
|
||||
RUN /usr/bin/caddy -version
|
||||
RUN /usr/bin/caddy -plugins
|
||||
|
||||
EXPOSE 80 443 2015
|
||||
VOLUME /root/.caddy /www
|
||||
WORKDIR /www
|
||||
|
||||
COPY Caddyfile /caddy/Caddyfile
|
||||
|
||||
CMD ["caddy","--conf", "/caddy/Caddyfile", "--log", "stdout", "--agree"]
|
@ -0,0 +1,90 @@
|
||||
# caddy_docker
|
||||
|
||||
this is a docker image for Caddy. Thanks to [abiosoft](https://github.com/abiosoft/caddy-docker)
|
||||
|
||||
## why to build it
|
||||
|
||||
the docker image from abiosoft has something wrong. I think it may have some wrong links/packages to get, and I try to use an unfriendly way to fix it.
|
||||
|
||||
## version
|
||||
|
||||
caddy v1.0.5
|
||||
|
||||
## default plugins
|
||||
|
||||
```dnspod```, ```filter```, ```cache```, ```minify```, ```expires```, ```realip```, ```cors```
|
||||
|
||||
## how to add more plugins
|
||||
|
||||
### nomally
|
||||
|
||||
1. go to the [official website for plugins](https://caddyserver.com/v1/docs/http.filter).(for filter as example)
|
||||
|
||||
2. click the 'Full documentation' in the website.
|
||||
|
||||
3. copy the packages/repository link as like ```github.com/echocat/caddy-filter/```.
|
||||
|
||||
4. add it into 'builder.sh' following where you can see the word like that ```"import/path/here"```
|
||||
(note: don't foget the ```_``` in front of it)
|
||||
|
||||
5. it's ok.
|
||||
|
||||
### specially
|
||||
|
||||
as I know. some plugins you need do more things.(as cors for example).
|
||||
|
||||
1. do the same things like 1&2 in 'nomally'
|
||||
|
||||
2. you can see ```caddy``` folder in the repository, and in it there is a ```corsPlugin.go``` file.
|
||||
|
||||
3. open it can copy the content into ```builder.sh```.(you could see what I did, and just follow it to add other plugins like cors)
|
||||
|
||||
## build
|
||||
|
||||
I use docker-compose to build the image.
|
||||
|
||||
```docker
|
||||
|
||||
caddy:
|
||||
build:
|
||||
context: ./caddy
|
||||
container_name: caddy
|
||||
environment:
|
||||
- TZ=
|
||||
- DNSPOD_API_KEY=
|
||||
- DNSPOD_HTTP_TIMEOUT=10
|
||||
volumes:
|
||||
- ./caddy/data/Caddyfile:/caddy/Caddyfile
|
||||
- ./caddy/data/certs:/caddy/certs
|
||||
- ./caddy/data/.caddy:/root/.caddy
|
||||
- ./www:/www/:rw
|
||||
ports:
|
||||
- 2015:2015
|
||||
- 80:80
|
||||
- 443:443
|
||||
restart: always
|
||||
networks:
|
||||
- net-default
|
||||
|
||||
```
|
||||
|
||||
you need change ```context``` to where your Dockerfile is.
|
||||
|
||||
### change environment.
|
||||
|
||||
```TZ``` is time zone.
|
||||
|
||||
if you use dnspod, you need ```DNSPOD_API_KEY``` like ```id,api_tokens```.
|
||||
|
||||
if you use cloudflare, you need ```CLOUDFLARE_EMAIL``` and ```CLOUDFLARE_API_KEY```
|
||||
you can get it from [cloudflare]( https://dash.cloudflare.com/profile/api-tokens)
|
||||
|
||||
## what's more
|
||||
|
||||
you can get 'cloudflare' plugins from [it](https://github.com/caddyserver/dnsproviders/blob/master/cloudflare/cloudflare.go)
|
||||
then you can do like ```specially``` to add it or to see how I add the ```dnspod``` plugins.
|
||||
|
||||
## Thanks
|
||||
|
||||
Thanks to [abiosoft](https://github.com/abiosoft/caddy-docker) again.
|
||||
What's more detail about build caddy v1 you can see [caddy v1.0.5](https://github.com/caddyserver/caddy/tree/v1.0.5)
|
@ -0,0 +1,245 @@
|
||||
#!/bin/sh
|
||||
|
||||
VERSION=${VERSION:-"1.0.5"}
|
||||
IMPORT="github.com/caddyserver/caddy"
|
||||
|
||||
# add `v` prefix for version numbers
|
||||
[ "$(echo $VERSION | cut -c1)" -ge 0 ] 2>/dev/null && VERSION="v$VERSION"
|
||||
|
||||
stage() {
|
||||
STAGE="$1"
|
||||
echo
|
||||
echo starting stage: $STAGE
|
||||
}
|
||||
|
||||
end_stage() {
|
||||
if [ $? -ne 0 ]; then
|
||||
>&2 echo error at \'$STAGE\'
|
||||
exit 1
|
||||
fi
|
||||
echo finished stage: $STAGE ✓
|
||||
echo
|
||||
}
|
||||
|
||||
|
||||
module() {
|
||||
mkdir -p /caddy
|
||||
cd /caddy # build dir
|
||||
|
||||
# main and telemetry
|
||||
cat > main.go <<EOF
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"github.com/caddyserver/caddy"
|
||||
"github.com/caddyserver/caddy/caddy/caddymain"
|
||||
"github.com/caddyserver/caddy/caddyhttp/httpserver"
|
||||
"github.com/captncraig/cors"
|
||||
// plug in plugins here, for example:
|
||||
// _ "import/path/here"
|
||||
"errors"
|
||||
|
||||
"github.com/caddyserver/caddy/caddytls"
|
||||
"github.com/go-acme/lego/v3/providers/dns/dnspod"
|
||||
_ "github.com/echocat/caddy-filter"
|
||||
_ "github.com/nicolasazrak/caddy-cache"
|
||||
_ "github.com/hacdias/caddy-minify"
|
||||
_ "github.com/epicagency/caddy-expires"
|
||||
_ "github.com/captncraig/caddy-realip"
|
||||
)
|
||||
|
||||
func main() {
|
||||
caddytls.RegisterDNSProvider("dnspod", NewDNSProvider)
|
||||
caddy.RegisterPlugin("cors", caddy.Plugin{
|
||||
ServerType: "http",
|
||||
Action: setup,
|
||||
})
|
||||
// optional: disable telemetry
|
||||
caddymain.EnableTelemetry = false
|
||||
caddymain.Run()
|
||||
}
|
||||
|
||||
func NewDNSProvider(credentials ...string) (caddytls.ChallengeProvider, error) {
|
||||
switch len(credentials) {
|
||||
case 0:
|
||||
return dnspod.NewDNSProvider()
|
||||
case 1:
|
||||
config := dnspod.NewDefaultConfig()
|
||||
config.LoginToken = credentials[0]
|
||||
return dnspod.NewDNSProviderConfig(config)
|
||||
default:
|
||||
return nil, errors.New("invalid credentials length")
|
||||
}
|
||||
}
|
||||
|
||||
type corsRule struct {
|
||||
Conf *cors.Config
|
||||
Path string
|
||||
}
|
||||
|
||||
func setup(c *caddy.Controller) error {
|
||||
rules, err := parseRules(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
siteConfig := httpserver.GetConfig(c)
|
||||
siteConfig.AddMiddleware(func(next httpserver.Handler) httpserver.Handler {
|
||||
return httpserver.HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) {
|
||||
for _, rule := range rules {
|
||||
if httpserver.Path(r.URL.Path).Matches(rule.Path) {
|
||||
rule.Conf.HandleRequest(w, r)
|
||||
if cors.IsPreflight(r) {
|
||||
return 200, nil
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return next.ServeHTTP(w, r)
|
||||
})
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseRules(c *caddy.Controller) ([]*corsRule, error) {
|
||||
rules := []*corsRule{}
|
||||
|
||||
for c.Next() {
|
||||
rule := &corsRule{Path: "/", Conf: cors.Default()}
|
||||
args := c.RemainingArgs()
|
||||
|
||||
anyOrigins := false
|
||||
if len(args) > 0 {
|
||||
rule.Path = args[0]
|
||||
}
|
||||
for i := 1; i < len(args); i++ {
|
||||
if !anyOrigins {
|
||||
rule.Conf.AllowedOrigins = nil
|
||||
}
|
||||
rule.Conf.AllowedOrigins = append(rule.Conf.AllowedOrigins, strings.Split(args[i], ",")...)
|
||||
anyOrigins = true
|
||||
}
|
||||
for c.NextBlock() {
|
||||
switch c.Val() {
|
||||
case "origin":
|
||||
if !anyOrigins {
|
||||
rule.Conf.AllowedOrigins = nil
|
||||
}
|
||||
args := c.RemainingArgs()
|
||||
for _, domain := range args {
|
||||
rule.Conf.AllowedOrigins = append(rule.Conf.AllowedOrigins, strings.Split(domain, ",")...)
|
||||
}
|
||||
anyOrigins = true
|
||||
case "origin_regexp":
|
||||
if arg, err := singleArg(c, "origin_regexp"); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
r, err := regexp.Compile(arg)
|
||||
|
||||
if err != nil {
|
||||
return nil, c.Errf("could no compile regexp: %s", err)
|
||||
}
|
||||
|
||||
if !anyOrigins {
|
||||
rule.Conf.AllowedOrigins = nil
|
||||
anyOrigins = true
|
||||
}
|
||||
|
||||
rule.Conf.OriginRegexps = append(rule.Conf.OriginRegexps, r)
|
||||
}
|
||||
case "methods":
|
||||
if arg, err := singleArg(c, "methods"); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
rule.Conf.AllowedMethods = arg
|
||||
}
|
||||
case "allow_credentials":
|
||||
if arg, err := singleArg(c, "allow_credentials"); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
var b bool
|
||||
if arg == "true" {
|
||||
b = true
|
||||
} else if arg != "false" {
|
||||
return nil, c.Errf("allow_credentials must be true or false.")
|
||||
}
|
||||
rule.Conf.AllowCredentials = &b
|
||||
}
|
||||
case "max_age":
|
||||
if arg, err := singleArg(c, "max_age"); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
i, err := strconv.Atoi(arg)
|
||||
if err != nil {
|
||||
return nil, c.Err("max_age must be valid int")
|
||||
}
|
||||
rule.Conf.MaxAge = i
|
||||
}
|
||||
case "allowed_headers":
|
||||
if arg, err := singleArg(c, "allowed_headers"); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
rule.Conf.AllowedHeaders = arg
|
||||
}
|
||||
case "exposed_headers":
|
||||
if arg, err := singleArg(c, "exposed_headers"); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
rule.Conf.ExposedHeaders = arg
|
||||
}
|
||||
default:
|
||||
return nil, c.Errf("Unknown cors config item: %s", c.Val())
|
||||
}
|
||||
}
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
return rules, nil
|
||||
}
|
||||
|
||||
func singleArg(c *caddy.Controller, desc string) (string, error) {
|
||||
args := c.RemainingArgs()
|
||||
if len(args) != 1 {
|
||||
return "", c.Errf("%s expects exactly one argument", desc)
|
||||
}
|
||||
return args[0], nil
|
||||
}
|
||||
EOF
|
||||
|
||||
# setup module
|
||||
go mod init caddy
|
||||
go get -v $IMPORT@$VERSION
|
||||
}
|
||||
|
||||
|
||||
# caddy source
|
||||
stage "fetching caddy source"
|
||||
git clone https://github.com/caddyserver/caddy -b "$VERSION" /go/src/$IMPORT \
|
||||
&& cd /go/src/$IMPORT
|
||||
end_stage
|
||||
|
||||
|
||||
|
||||
# check for modules support
|
||||
export GO111MODULE=on
|
||||
|
||||
# add plugins and telemetry
|
||||
stage "customising plugins and telemetry"
|
||||
module
|
||||
end_stage
|
||||
|
||||
# build
|
||||
stage "building caddy"
|
||||
go build -o caddy
|
||||
end_stage
|
||||
|
||||
# copy binary
|
||||
stage "copying binary"
|
||||
mkdir -p /install \
|
||||
&& mv caddy /install \
|
||||
&& /install/caddy -version
|
||||
end_stage
|
||||
|
||||
echo "installed caddy version $VERSION at /install/caddy"
|
Loading…
Reference in new issue