2020-07-03 00:31:29 +08:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"io/ioutil"
|
2021-11-16 14:22:55 +08:00
|
|
|
"os"
|
2020-07-03 00:31:29 +08:00
|
|
|
"path"
|
|
|
|
"strings"
|
|
|
|
"text/template"
|
|
|
|
|
|
|
|
"github.com/docker-library/go-dockerlibrary/manifest"
|
|
|
|
)
|
|
|
|
|
|
|
|
var manifestURL = "https://github.com/docker-library/official-images/raw/master/library/caddy"
|
|
|
|
|
|
|
|
var maintainers = []string{"Ambrose Chua <ambrose@makerforce.io> (@serverwentdown)"}
|
|
|
|
var gitRepo = "https://github.com/productionwentdown/caddy.git"
|
|
|
|
|
2021-11-16 14:22:55 +08:00
|
|
|
var readmeTemplate = template.Must(template.New("readme").Parse(`
|
2021-11-16 14:33:44 +08:00
|
|
|
# [caddy](https://hub.docker.com/r/productionwentdown/caddy) ![Docker Pulls](https://img.shields.io/docker/pulls/productionwentdown/caddy?style=flat-square) ![Docker Image Size (tag)](https://img.shields.io/docker/image-size/productionwentdown/caddy/alpine?style=flat-square)
|
2021-11-16 14:22:55 +08:00
|
|
|
|
|
|
|
A tiny <10MB Caddy image compressed with [UPX](https://github.com/upx/upx).
|
|
|
|
|
2021-11-16 14:33:44 +08:00
|
|
|
- [Docker Hub](https://hub.docker.com/r/productionwentdown/caddy)
|
|
|
|
- [GitHub](https://github.com/productionwentdown/caddy)
|
|
|
|
|
2021-11-16 15:07:56 +08:00
|
|
|
## Simple Tags
|
2021-11-16 14:22:55 +08:00
|
|
|
|
|
|
|
New versions are tracked within 4 hours. Currently available versions:
|
|
|
|
|
2021-11-16 15:07:56 +08:00
|
|
|
{{range $entry := .Entries}}* {{range $index, $tag := $entry.Tags}}{{if $index}}, {{end}}` + "`{{$tag}}`" + `{{end}}
|
|
|
|
{{end}}
|
|
|
|
## Shared Tags
|
2021-11-16 14:22:55 +08:00
|
|
|
|
2021-11-16 15:07:56 +08:00
|
|
|
{{range $entry := .Entries}}* {{range $index, $tag := $entry.SharedTags}}{{if $index}}, {{end}}` + "`{{$tag}}`" + `{{end}}
|
|
|
|
* ` + "`{{index $entry.Tags 0}}`" + `
|
|
|
|
{{end}}
|
2021-11-16 14:22:55 +08:00
|
|
|
# Usage
|
|
|
|
|
2021-11-16 14:33:44 +08:00
|
|
|
See the [official image](https://hub.docker.com/_/caddy) for documentation. This image behaves the same way, except that it is slightly slimmer.
|
2021-11-16 14:22:55 +08:00
|
|
|
`))
|
|
|
|
|
2020-07-03 00:31:29 +08:00
|
|
|
var dockerfileTemplate = template.Must(template.New("name").Parse(`FROM caddy:{{.Tag}} as build
|
|
|
|
|
|
|
|
RUN apk add --no-cache upx ca-certificates \
|
|
|
|
&& upx --ultra-brute /usr/bin/caddy \
|
|
|
|
&& caddy version
|
|
|
|
|
|
|
|
FROM scratch
|
|
|
|
|
|
|
|
COPY --from=build /etc/caddy/Caddyfile /etc/caddy/Caddyfile
|
|
|
|
COPY --from=build /usr/share/caddy/index.html /usr/share/caddy/index.html
|
|
|
|
COPY --from=build /usr/bin/caddy /usr/bin/caddy
|
|
|
|
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
|
|
|
COPY --from=build /etc/nsswitch.conf /etc/nsswitch.conf
|
|
|
|
|
|
|
|
ENV XDG_CONFIG_HOME=/config
|
|
|
|
ENV XDG_DATA_HOME=/data
|
|
|
|
ENV HOME=/
|
|
|
|
|
|
|
|
VOLUME /config
|
|
|
|
VOLUME /data
|
|
|
|
|
|
|
|
LABEL org.opencontainers.image.version=v{{.Version}}
|
|
|
|
LABEL org.opencontainers.image.title="Caddy (productionwentdown build)"
|
|
|
|
LABEL org.opencontainers.image.description="a powerful, enterprise-ready, open source web server with automatic HTTPS written in Go"
|
|
|
|
LABEL org.opencontainers.image.url=https://productionwentdown.makerforce.io
|
|
|
|
LABEL org.opencontainers.image.documentation=https://caddyserver.com/docs
|
|
|
|
LABEL org.opencontainers.image.vendor="productionwentdown"
|
|
|
|
LABEL org.opencontainers.image.licenses=Apache-2.0
|
|
|
|
LABEL org.opencontainers.image.source="https://github.com/productionwentdown/caddy"
|
|
|
|
|
|
|
|
EXPOSE 80
|
|
|
|
EXPOSE 443
|
|
|
|
EXPOSE 2019
|
|
|
|
|
|
|
|
WORKDIR /srv
|
|
|
|
|
|
|
|
CMD ["/usr/bin/caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"]
|
|
|
|
`))
|
|
|
|
|
|
|
|
type dockerfileData struct {
|
|
|
|
Tag string
|
|
|
|
Version string
|
2021-11-16 14:22:55 +08:00
|
|
|
Arch string
|
2020-07-03 00:31:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
doDockerfiles := flag.Bool("dockerfiles", false, "Update Dockerfiles")
|
|
|
|
doManifest := flag.Bool("manifest", false, "Update manifest")
|
2021-11-16 14:22:55 +08:00
|
|
|
doReadme := flag.Bool("readme", false, "Update README.md")
|
2020-07-03 00:31:29 +08:00
|
|
|
commit := flag.String("commit", "", "Current commit hash")
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
_, _, man, err := manifest.Fetch("nonexistent", manifestURL)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
man = subsetManifest(man)
|
|
|
|
|
|
|
|
if *doDockerfiles {
|
|
|
|
err = updateDockerfiles(man)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if *doManifest {
|
|
|
|
err = updateManifest(man, *commit)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
2021-11-16 14:22:55 +08:00
|
|
|
if *doReadme {
|
|
|
|
err = updateReadme(man)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
2020-07-03 00:31:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// subsetManifest returns the subset of the manifest that can be built
|
|
|
|
func subsetManifest(man *manifest.Manifest2822) *manifest.Manifest2822 {
|
|
|
|
entries := make([]manifest.Manifest2822Entry, 0, 1)
|
|
|
|
for _, entry := range man.Entries {
|
|
|
|
|
2020-09-26 14:11:09 +08:00
|
|
|
isWindows := false
|
2020-07-03 00:31:29 +08:00
|
|
|
for _, arch := range entry.Architectures {
|
2020-09-26 14:11:09 +08:00
|
|
|
if strings.Contains(arch, "windows") {
|
|
|
|
isWindows = true
|
2020-07-03 00:31:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
isBuilder := false
|
|
|
|
for _, tag := range entry.Tags {
|
2020-09-26 14:11:09 +08:00
|
|
|
if strings.Contains(tag, "builder") {
|
2020-07-03 00:31:29 +08:00
|
|
|
isBuilder = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-26 14:11:09 +08:00
|
|
|
if isWindows || isBuilder {
|
2020-07-03 00:31:29 +08:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
entries = append(entries, entry)
|
|
|
|
}
|
|
|
|
return &manifest.Manifest2822{
|
|
|
|
Global: man.Global,
|
|
|
|
Entries: entries,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// updateDockerfiles generates a new set of Dockerfiles based on the manifest
|
|
|
|
func updateDockerfiles(man *manifest.Manifest2822) error {
|
|
|
|
for _, entry := range man.Entries {
|
|
|
|
tag := entry.Tags[0]
|
|
|
|
version := strings.Split(entry.Tags[0], "-")[0]
|
|
|
|
for _, arch := range entry.Architectures {
|
|
|
|
data := dockerfileData{Tag: tag, Version: version, Arch: arch}
|
|
|
|
err := writeDockerfile(entry, data)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// TODO: Remove old Dockerfiles
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func writeDockerfile(entry manifest.Manifest2822Entry, data dockerfileData) error {
|
|
|
|
dockerfilePath := path.Join(entry.ArchDirectory(data.Arch), entry.ArchFile(data.Arch))
|
|
|
|
err := os.MkdirAll(entry.ArchDirectory(data.Arch), 0755)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
dockerfileFile, err := os.OpenFile(dockerfilePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer dockerfileFile.Close()
|
|
|
|
|
|
|
|
err = dockerfileTemplate.Execute(dockerfileFile, data)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// updateManifest replaces upstream maintainer and Git info with this repo
|
|
|
|
func updateManifest(man *manifest.Manifest2822, gitCommit string) error {
|
|
|
|
man.Global.Maintainers = maintainers
|
|
|
|
for i := range man.Entries {
|
|
|
|
entry := &man.Entries[i]
|
|
|
|
entry.Maintainers = maintainers
|
|
|
|
entry.GitRepo = gitRepo
|
|
|
|
entry.GitCommit = gitCommit
|
|
|
|
}
|
|
|
|
manifestPath := path.Join("library", "caddy")
|
2020-07-03 00:42:23 +08:00
|
|
|
err := os.MkdirAll("library", 0755)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2020-07-03 00:31:29 +08:00
|
|
|
return ioutil.WriteFile(manifestPath, []byte(man.String()), 0644)
|
|
|
|
}
|
2021-11-16 14:22:55 +08:00
|
|
|
|
|
|
|
// updateReadme generates a new README.md
|
|
|
|
func updateReadme(man *manifest.Manifest2822) error {
|
|
|
|
readmeFile, err := os.OpenFile("README.md", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer readmeFile.Close()
|
|
|
|
|
|
|
|
err = readmeTemplate.Execute(readmeFile, man)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|