├── .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 | [![Build status](https://github.com/qdm12/caddy-scratch/actions/workflows/ci.yml/badge.svg)](https://github.com/qdm12/caddy-scratch/actions/workflows/ci.yml) 8 | 9 | [![dockeri.co](https://dockeri.co/image/qmcgaw/caddy-scratch)](https://hub.docker.com/r/qmcgaw/caddy-scratch) 10 | 11 | ![Last release](https://img.shields.io/github/release/qdm12/caddy-scratch?label=Last%20release) 12 | ![Last Docker tag](https://img.shields.io/docker/v/qmcgaw/caddy-scratch?sort=semver&label=Last%20Docker%20tag) 13 | [![Last release size](https://img.shields.io/docker/image-size/qmcgaw/caddy-scratch?sort=semver&label=Last%20released%20image)](https://hub.docker.com/r/qmcgaw/caddy-scratch/tags?page=1&ordering=last_updated) 14 | ![GitHub last release date](https://img.shields.io/github/release-date/qdm12/caddy-scratch?label=Last%20release%20date) 15 | ![Commits since release](https://img.shields.io/github/commits-since/qdm12/caddy-scratch/latest?sort=semver) 16 | 17 | [![Latest size](https://img.shields.io/docker/image-size/qmcgaw/caddy-scratch/latest?label=Latest%20image)](https://hub.docker.com/r/qmcgaw/caddy-scratch/tags) 18 | 19 | [![GitHub last commit](https://img.shields.io/github/last-commit/qdm12/caddy-scratch.svg)](https://github.com/qdm12/caddy-scratch/commits/main) 20 | [![GitHub commit activity](https://img.shields.io/github/commit-activity/y/qdm12/caddy-scratch.svg)](https://github.com/qdm12/caddy-scratch/graphs/contributors) 21 | [![GitHub closed PRs](https://img.shields.io/github/issues-pr-closed/qdm12/caddy-scratch.svg)](https://github.com/qdm12/caddy-scratch/pulls?q=is%3Apr+is%3Aclosed) 22 | [![GitHub issues](https://img.shields.io/github/issues/qdm12/caddy-scratch.svg)](https://github.com/qdm12/caddy-scratch/issues) 23 | [![GitHub closed issues](https://img.shields.io/github/issues-closed/qdm12/caddy-scratch.svg)](https://github.com/qdm12/caddy-scratch/issues?q=is%3Aissue+is%3Aclosed) 24 | 25 | [![MIT](https://img.shields.io/github/license/qdm12/caddy-scratch)](https://github.com/qdm12/caddy-scratch/master/LICENSE) 26 | ![Visitors count](https://visitor-badge.laobi.icu/badge?page_id=caddy-scratch.readme) 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 | image/svg+xml 23 | All in 39.2MBNo rootNo OS 291 | 292 | 293 | --------------------------------------------------------------------------------