fist commit

master
YunMao 4 years ago
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…
Cancel
Save