├── .dockerignore
├── .github
├── CODEOWNERS
├── CONTRIBUTING.md
├── FUNDING.yml
└── workflows
│ ├── ci.yml
│ └── dockerhub-description.yml
├── .gitignore
├── Caddyfile
├── Dockerfile
├── LICENSE
├── README.md
├── docker-compose.yml
└── title.svg
/.dockerignore:
--------------------------------------------------------------------------------
1 | .git
2 | .github
3 | .gitignore
4 | docker-compose.yml
5 | LICENSE
6 | README.md
7 | title.svg
8 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | @qdm12
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Contributions are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [open source license of this project](../LICENSE).
4 |
5 | ## Submitting a pull request
6 |
7 | 1. [Fork](https://github.com/qdm12/caddy-scratch/fork) and clone the repository
8 | 1. Create a new branch `git checkout -b my-branch-name`
9 | 1. Modify the code
10 | 1. Ensure the docker build succeeds `docker build .`
11 | 1. Commit your modifications
12 | 1. Push to your fork and [submit a pull request](https://github.com/qdm12/caddy-scratch/compare)
13 |
14 | ## Resources
15 |
16 | - [Using Pull Requests](https://help.github.com/articles/about-pull-requests/)
17 | - [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/)
18 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [qdm12]
2 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on:
3 | push:
4 | paths:
5 | - .github/workflows/ci.yml
6 | - .dockerignore
7 | - Caddyfile
8 | - Dockerfile
9 |
10 | jobs:
11 | verify:
12 | runs-on: ubuntu-latest
13 | env:
14 | DOCKER_BUILDKIT: "1"
15 | steps:
16 | - uses: actions/checkout@v2.3.4
17 |
18 | - name: Build image
19 | run: docker build .
20 |
21 | publish:
22 | needs: [verify]
23 | runs-on: ubuntu-latest
24 | steps:
25 | - uses: actions/checkout@v2.3.4
26 |
27 | - uses: docker/setup-qemu-action@v1
28 | - uses: docker/setup-buildx-action@v1
29 |
30 | - uses: docker/login-action@v1
31 | with:
32 | username: qmcgaw
33 | password: ${{ secrets.DOCKERHUB_PASSWORD }}
34 |
35 | - name: Set variables
36 | id: vars
37 | env:
38 | EVENT_NAME: ${{ github.event_name }}
39 | run: |
40 | BRANCH=${GITHUB_REF#refs/heads/}
41 | TAG=${GITHUB_REF#refs/tags/}
42 | echo ::set-output name=commit::$(git rev-parse --short HEAD)
43 | echo ::set-output name=created::$(date -u +%Y-%m-%dT%H:%M:%SZ)
44 | if [ "$TAG" != "$GITHUB_REF" ]; then
45 | echo ::set-output name=version::$TAG
46 | echo ::set-output name=platforms::linux/amd64,linux/386,linux/arm64,linux/arm/v7
47 | elif [ "$BRANCH" = "master" ]; then
48 | echo ::set-output name=version::latest
49 | echo ::set-output name=platforms::linux/amd64,linux/386,linux/arm64,linux/arm/v7
50 | else
51 | echo ::set-output name=version::$BRANCH
52 | echo ::set-output name=platforms::linux/amd64,linux/386,linux/arm64,linux/arm/v7
53 | fi
54 | - name: Build and push final image
55 | uses: docker/build-push-action@v2.6.1
56 | with:
57 | platforms: ${{ steps.vars.outputs.platforms }}
58 | build-args: |
59 | CREATED=${{ steps.vars.outputs.created }}
60 | COMMIT=${{ steps.vars.outputs.commit }}
61 | VERSION=${{ steps.vars.outputs.version }}
62 | tags: qmcgaw/caddy-scratch:${{ steps.vars.outputs.version }}
63 | push: true
64 |
--------------------------------------------------------------------------------
/.github/workflows/dockerhub-description.yml:
--------------------------------------------------------------------------------
1 | name: Docker Hub description
2 | on:
3 | push:
4 | branches: [master]
5 | paths:
6 | - README.md
7 | - .github/workflows/dockerhub-description.yml
8 | jobs:
9 | dockerHubDescription:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v2
14 | - name: Docker Hub Description
15 | uses: peter-evans/dockerhub-description@v2.1.0
16 | env:
17 | DOCKERHUB_USERNAME: qmcgaw
18 | DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }}
19 | DOCKERHUB_REPOSITORY: qmcgaw/caddy-scratch
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qdm12/caddy-scratch/69e2a8a43e7a4ff04abc3adc15912ca1f3003d30/.gitignore
--------------------------------------------------------------------------------
/Caddyfile:
--------------------------------------------------------------------------------
1 | {
2 | admin 0.0.0.0:2019
3 | http_port 8080
4 | https_port 8443
5 | }
6 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG ALPINE_VERSION=3.13
2 | ARG GO_VERSION=1.16
3 |
4 | FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS builder
5 | RUN apk add -q --progress --update --no-cache git ca-certificates tzdata
6 | RUN mkdir -p /caddydir/data && \
7 | chmod -R 700 /caddydir
8 | ENV GO111MODULE=on \
9 | CGO_ENABLED=0
10 | RUN go get github.com/caddyserver/xcaddy/cmd/xcaddy
11 | ARG CADDY_VERSION=v2.4.1
12 | WORKDIR /caddy
13 | ARG PLUGINS=
14 | RUN for plugin in $(echo $PLUGINS | tr "," " "); do withFlags="$withFlags --with $plugin"; done && \
15 | xcaddy build ${CADDY_VERSION} ${withFlags}
16 |
17 | FROM scratch
18 | ARG VERSION
19 | ARG CADDY_VERSION
20 | ARG CREATED
21 | ARG COMMIT
22 | LABEL \
23 | org.opencontainers.image.authors="quentin.mcgaw@gmail.com" \
24 | org.opencontainers.image.created=$CREATED \
25 | org.opencontainers.image.version=$VERSION \
26 | org.opencontainers.image.revision=$COMMIT \
27 | org.opencontainers.image.url="https://github.com/qdm12/caddy-scratch" \
28 | org.opencontainers.image.documentation="https://github.com/qdm12/caddy-scratch/blob/master/README.md" \
29 | org.opencontainers.image.source="https://github.com/qdm12/caddy-scratch" \
30 | org.opencontainers.image.title="caddy-scratch" \
31 | org.opencontainers.image.description="Caddy server ${CADDY_VERSION} on Alpine"
32 | COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
33 | COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
34 | EXPOSE 8080 8443 2015
35 | ENV HOME=/caddydir \
36 | CADDYPATH=/caddydir/data \
37 | TZ=America/Montreal
38 | COPY --from=builder --chown=1000 /caddydir /caddydir
39 | VOLUME ["/caddydir"]
40 | ENTRYPOINT ["/caddy"]
41 | USER 1000
42 | # see https://caddyserver.com/docs/cli
43 | CMD ["run","--config","/caddydir/Caddyfile"]
44 | COPY --chown=1000 Caddyfile /caddydir/Caddyfile
45 | COPY --from=builder --chown=1000 /caddy/caddy /caddy
46 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Quentin McGaw
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Caddy Scratch Docker
2 |
3 | Caddy server v2.4.1 / v1.0.5 without root, without OS and with optional Caddy plugins
4 |
5 |
6 |
7 | [](https://github.com/qdm12/caddy-scratch/actions/workflows/ci.yml)
8 |
9 | [](https://hub.docker.com/r/qmcgaw/caddy-scratch)
10 |
11 | 
12 | 
13 | [](https://hub.docker.com/r/qmcgaw/caddy-scratch/tags?page=1&ordering=last_updated)
14 | 
15 | 
16 |
17 | [](https://hub.docker.com/r/qmcgaw/caddy-scratch/tags)
18 |
19 | [](https://github.com/qdm12/caddy-scratch/commits/main)
20 | [](https://github.com/qdm12/caddy-scratch/graphs/contributors)
21 | [](https://github.com/qdm12/caddy-scratch/pulls?q=is%3Apr+is%3Aclosed)
22 | [](https://github.com/qdm12/caddy-scratch/issues)
23 | [](https://github.com/qdm12/caddy-scratch/issues?q=is%3Aissue+is%3Aclosed)
24 |
25 | [](https://github.com/qdm12/caddy-scratch/master/LICENSE)
26 | 
27 |
28 | ## Features
29 |
30 | - [Scratch](https://hub.docker.com/_/scratch/) based, so less attack surface and tiny
31 | - Runs **without** root
32 | - [Plugins](#Plugins)
33 |
34 | | Docker tag | Caddy version | Size | Documentation | CPU architectures |
35 | | --- | --- | --- | --- | --- |
36 | | `:latest` | [`v2.4.1`](https://github.com/caddyserver/caddy/releases/tag/v2.4.1) | 37.3MB | ➡️ [Setup below](#Setup) | `amd64`, `386`, `arm64`, `armv7` |
37 | | `:v2.4.1` | [`v2.4.1`](https://github.com/caddyserver/caddy/releases/tag/v2.4.1) | 37.5MB | ➡️ [Setup below](#Setup) | `amd64`, `386`, `arm64`, `armv7` |
38 | | `:2.3.0` | [`v2.3.0`](https://github.com/caddyserver/caddy/releases/tag/v2.3.0) | 37.3MB | ➡️ [Setup below](#Setup) | `amd64`, `386`, `arm64`, `armv7` |
39 | | `:v2.2.1` | [`v2.2.1`](https://github.com/caddyserver/caddy/releases/tag/v2.2.1) | 33.9MB | ➡️ [Setup below](#Setup) | `amd64`, `386`, `arm64`, `armv7` |
40 | | `:v2.1.0` | [`v2.1.0`](https://github.com/caddyserver/caddy/releases/tag/v2.1.0) | 39.2MB | ➡️ [Wiki link](https://github.com/qdm12/caddy-scratch/wiki/Caddy-v2.1.0) | `amd64`, `386`, `arm64`, `armv7` |
41 | | `:v2.0.0` | [`v2.0.0`](https://github.com/caddyserver/caddy/releases/tag/v2.0.0) | 35.4MB | ➡️ [Wiki link](https://github.com/qdm12/caddy-scratch/wiki/Caddy-v2.0.0) | `amd64`, `386`, `arm64`, `armv7` |
42 | | `:v1.0.5` | [`v1.0.5`](https://github.com/caddyserver/caddy/releases/tag/v1.0.5) | 17.2MB | ➡️ [Wiki link](https://github.com/qdm12/caddy-scratch/wiki/Caddy-v1.0.5) | `amd64`, `386`, `arm64` |
43 | | `:v1.0.4` | [`v1.0.4`](https://github.com/caddyserver/caddy/releases/tag/v1.0.4) | 17.3MB | ➡️ [Wiki link](https://github.com/qdm12/caddy-scratch/wiki/Caddy-v1.0.4) | `amd64`, `386`, `arm64` |
44 |
45 | Size: *uncompressed amd64 built Docker image*
46 |
47 | ## Setup
48 |
49 | ✈️ Migrating from v1.0.x? ➡️ [Wiki: Migrating](https://github.com/qdm12/caddy-scratch/wiki/Migrating)
50 |
51 | ⚠️ The following applies to the `:latest` tag. For other Docker tags, refer to the [Wiki](https://github.com/qdm12/caddy-scratch/wiki/)
52 |
53 | ```sh
54 | docker run -d --name caddy -p 80:8080/tcp -p 443:8443/tcp qmcgaw/caddy-scratch
55 | ```
56 |
57 | or use [docker-compose.yml](https://github.com/qdm12/caddy-scratch/blob/master/docker-compose.yml) with:
58 |
59 | ```sh
60 | docker-compose up -d
61 | ```
62 |
63 | The data is persistent in a Docker anonymous volume by default.
64 |
65 | ### Caddyfile
66 |
67 | By default, this runs using the [repository Caddyfile](https://github.com/qdm12/caddy-scratch/blob/master/Caddyfile).
68 | You could work you way out modifying the Caddy configuration using the [Caddy API](#Caddy-API). Otherwise, if you want to use a Caddyfile, follow these steps.
69 |
70 | 1. Create the directory: `mkdir caddydir`
71 | 1. Create a [Caddyfile](https://caddyserver.com/docs/caddyfile) with the content you would like, in `caddydir/Caddyfile`.
72 | Note that at the top of your *Caddyfile*, there should be at least the following global block:
73 |
74 | ```Caddyfile
75 | {
76 | http_port 8080
77 | https_port 8443
78 | }
79 | ```
80 |
81 | 1. Change the ownership and permission to match the Docker container
82 |
83 | ```sh
84 | chown -R 1000 caddydir
85 | chmod -R 700 caddydir
86 | ```
87 |
88 | If you are on Windows, you may skip this step.
89 |
90 | Alternatively, you can run the container with `--user="1001"` for example, or as root with `--user="root"` (*unadvised*).
91 |
92 | 1. Assuming your current file path is `/yourpath`, run the container with:
93 |
94 | ```sh
95 | docker run -d --name caddy -p 80:8080/tcp -p 443:8443/tcp \
96 | -v /yourpath/caddydir:/caddydir qmcgaw/caddy-scratch
97 | ```
98 |
99 | ### Log times
100 |
101 | If log times are not correct, it's because you need to set your timezone in the `TZ` environment variable. For example, add `-e TZ=America/Montreal` to your Docker run command.
102 |
103 | ### Update
104 |
105 | Update the docker image with `docker pull qmcgaw/caddy-scratch`
106 |
107 | ### Caddy API
108 |
109 | To access the [Caddy API](https://caddyserver.com/docs/api), you need:
110 |
111 | - your Caddyfile to contain `admin 0.0.0.0:2019` at the top global block (as is in the default Caddyfile)
112 | - (eventually) have port 2019 published by adding `-p 2019:2019/tcp` to your Docker run command
113 |
114 | ### Plugins
115 |
116 | You need [Git](https://git-scm.com/downloads) installed.
117 |
118 | If you want to have for example the `github.com/caddyserver/ntlm-transport` plugin, build the image with
119 |
120 | ```sh
121 | docker build -t qmcgaw/caddy \
122 | --build-arg PLUGINS=github.com/caddyserver/ntlm-transport \
123 | https://github.com/qdm12/caddy-scratch.git
124 | ```
125 |
126 | ## Extra
127 |
128 | - Assuming your container is called `caddy`, you can reload the Caddyfile with:
129 |
130 | ```sh
131 | docker kill --signal=USR1 caddy
132 | ```
133 |
134 | ## TODOs
135 |
136 | - [ ] Telemetry off with build argument
137 | - [ ] Use lists of IPs to block with ipfilter with `import blockIps`
138 | - [ ] Healthcheck for Caddy
139 | - [ ] Intelligent IP blocking
140 |
141 | ## Thanks
142 |
143 | - To the Caddy developers and mholt especially
144 | - To the Caddy plugins developers
145 | - To abiosoft for helping me out building this Docker image
146 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.7"
2 | services:
3 | caddy:
4 | image: qmcgaw/caddy-scratch
5 | container_name: caddy
6 | #volumes:
7 | # - ./caddydir:/caddydir
8 | environment:
9 | - TZ=America/Montreal
10 | network_mode: bridge
11 | ports:
12 | - 80:8080/tcp
13 | - 443:8443/tcp
14 | - 2015:2015/tcp
15 | restart: always
16 |
--------------------------------------------------------------------------------
/title.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------