├── .github └── workflows │ ├── docker.yml │ └── versions.yml ├── .gitignore ├── .vscode └── settings.json ├── Caddyfile ├── Dockerfile ├── LICENSE ├── README.md ├── config.json └── versions ├── caddy.txt └── keeweb.txt /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: Docker Image CI 2 | 3 | on: 4 | push: 5 | paths: 6 | - 'versions/**' 7 | workflow_dispatch: 8 | 9 | jobs: 10 | 11 | build: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout Repository 17 | uses: actions/checkout@v3 18 | 19 | - name: Get version 20 | id: vars 21 | run: | 22 | echo "caddy_version=$(cat versions/caddy.txt)" >> "$GITHUB_OUTPUT" 23 | echo "keeweb_version=$(cat versions/keeweb.txt)" >> "$GITHUB_OUTPUT" 24 | 25 | - name: Setup QEMU 26 | id: qemu 27 | uses: docker/setup-qemu-action@v1.0.1 28 | with: 29 | platforms: all 30 | 31 | - name: Available platforms 32 | run: echo ${{ steps.qemu.outputs.platforms }} 33 | 34 | - name: Set up Docker Buildx 35 | id: buildx 36 | uses: docker/setup-buildx-action@v1.0.4 37 | 38 | - name: Login to Docker Hub 39 | uses: docker/login-action@v1.8.0 40 | with: 41 | username: ${{ secrets.DOCKER_HUB_USERNAME }} 42 | password: ${{ secrets.DOCKER_HUB_TOKEN }} 43 | 44 | - name: Login to GitHub Container Registry 45 | uses: docker/login-action@v1 46 | with: 47 | registry: ghcr.io 48 | username: ${{ github.repository_owner }} 49 | password: ${{ secrets.GITHUB_TOKEN }} 50 | 51 | - name: Build and push 52 | id: docker_build 53 | uses: docker/build-push-action@v2 54 | with: 55 | platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7 56 | push: true 57 | tags: | 58 | slurdge/keewebdav:latest 59 | ghcr.io/slurdge/keewebdav:latest 60 | slurdge/keewebdav:caddy_${{ steps.vars.outputs.caddy_version }}_keeweb_${{ steps.vars.outputs.keeweb_version }} 61 | ghcr.io/slurdge/keewebdav:caddy_${{ steps.vars.outputs.caddy_version }}_keeweb_${{ steps.vars.outputs.keeweb_version }} 62 | 63 | - name: Image digest 64 | run: echo ${{ steps.docker_build.outputs.digest }} 65 | 66 | -------------------------------------------------------------------------------- /.github/workflows/versions.yml: -------------------------------------------------------------------------------- 1 | #from https://stackoverflow.com/questions/58465057/trigger-a-github-action-when-another-repository-creates-a-new-release 2 | name: Upstream Versions CI 3 | on: 4 | schedule: 5 | - cron: '0 18 * * *' 6 | workflow_dispatch: 7 | jobs: 8 | get-version: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | with: 13 | token: ${{ secrets.REPO_SCOPED_TOKEN }} 14 | - name: Fetch release version 15 | id: vars 16 | run: | 17 | curl -sL https://api.github.com/repos/caddyserver/caddy/releases/latest | jq -r ".tag_name" > versions/caddy.txt 18 | curl -sL https://api.github.com/repos/keeweb/keeweb/releases/latest | jq -r ".tag_name" > versions/keeweb.txt 19 | echo "caddy_version=$(cat versions/caddy.txt)" >> "$GITHUB_OUTPUT" 20 | echo "keeweb_version=$(cat versions/keeweb.txt)" >> "$GITHUB_OUTPUT" 21 | - name: Check for modified files 22 | id: git-check 23 | run: echo "modified=$([ -z "`git status --porcelain`" ] && echo "false" || echo "true")" >> "$GITHUB_OUTPUT" 24 | - name: Commit latest release version 25 | if: steps.git-check.outputs.modified == 'true' 26 | run: | 27 | git config --global user.name 'Slurdge' 28 | git config --global user.email 'slurdge@users.noreply.github.com' 29 | git commit -am "Caddy: ${{ steps.vars.outputs.caddy_version }} - Keeweb: ${{ steps.vars.outputs.keeweb_version }}" 30 | git push -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | static/* 2 | dav/* 3 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "cSpell.words": [ 3 | "certresolver", 4 | "kdbx", 5 | "Keepass", 6 | "keeweb", 7 | "keewebdav", 8 | "traefik", 9 | "webdav" 10 | ] 11 | } -------------------------------------------------------------------------------- /Caddyfile: -------------------------------------------------------------------------------- 1 | { 2 | order webdav before file_server 3 | log { 4 | level INFO 5 | } 6 | } 7 | 8 | :8080 { 9 | @dbfiles { 10 | path *.kdbx 11 | path *.kdbx.* 12 | } 13 | 14 | webdav @dbfiles { 15 | root /srv/dav/ 16 | } 17 | 18 | file_server { 19 | root /srv 20 | index index.html 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:latest as builder 2 | LABEL maintainer "Slurdge " 3 | 4 | ARG platform="linux" 5 | ARG TARGETPLATFORM 6 | 7 | RUN apk add --no-cache openssh-client openssl ca-certificates git wget 8 | 9 | # install caddy 10 | RUN set -eux; \ 11 | apkArch="$(apk --print-arch)"; \ 12 | echo "$apkArch"; \ 13 | case "$apkArch" in \ 14 | x86_64) arch='amd64'; armv='';; \ 15 | armhf) arch='arm'; armv='6';; \ 16 | armv7) arch='arm'; armv='7';; \ 17 | aarch64) arch='arm64'; armv='';; \ 18 | ppc64el) arch='ppc64'; armv='';; \ 19 | ppc64le) arch='ppc64le'; armv='';; \ 20 | s390x) arch='s390x'; armv='';; \ 21 | *) echo >&2 "error: unsupported architecture ($arch)"; exit 1 ;;\ 22 | esac; \ 23 | wget --quiet "https://caddyserver.com/api/download?os=$platform&arch=$arch&arm=$armv&p=github.com%2Fmholt%2Fcaddy-webdav" -O caddy 24 | 25 | # get keeweb release 26 | RUN git clone --depth=1 --branch "gh-pages" https://github.com/keeweb/keeweb/ 27 | RUN sed -i "s/(no-config)/config.json/" keeweb/index.html 28 | RUN sed -i 's|pattern:"^https://.+"|pattern:"(^https://.+)\|(.+\\.kdbx$)"|' keeweb/index.html 29 | RUN sha512=`sed -n 's|.*>.*|\1|p' keeweb/index.html | openssl sha512 -binary | openssl base64 -A` && sed -i "s|script-src 'sha512\-[^']*'|script-src 'sha512-$sha512'|" keeweb/index.html 30 | 31 | FROM alpine:latest 32 | 33 | EXPOSE 8080 34 | WORKDIR /srv 35 | 36 | COPY Caddyfile /etc/Caddyfile 37 | COPY config.json /srv/ 38 | COPY --from=builder keeweb/ /srv/ 39 | COPY --from=builder caddy /usr/bin/caddy 40 | 41 | # validate install 42 | RUN mkdir /srv/dav/ && chmod +x /usr/bin/caddy && /usr/bin/caddy version && /usr/bin/caddy list-modules 43 | 44 | ENTRYPOINT ["caddy"] 45 | CMD ["run", "--config", "/etc/Caddyfile"] 46 | 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 slurdge 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 | # A docker solution for Keeweb+WebDav 2 | 3 | A Docker repository to have a simple Caddy+Keeweb+Webdav solution. 4 | 5 | The focus of this repository is **simplicity** so you can roll your own auto hosted Keeweb and Webdav solution. 6 | 7 | You can use Keepass synchronisation with the following url: 8 | ```https://example.com/database.kdbx``` 9 | 10 | ## Technical stack 11 | 12 | Pretty simple: 13 | 14 | * [Caddy](https://caddyserver.com/) in http mode with webdav extension; 15 | * [Keeweb](https://keeweb.info/) with a special config removing unused options by default. 16 | 17 | Caddy is configured to serve all files ending in `.kdbx` through webdav without authentication, for ease of use. 18 | 19 | ## Trial run in docker 20 | 21 | ⚠ **This will not be secured by `https`!** ⚠ 22 | 23 | ```docker run -p 8080:8080 slurdge/keewebdav``` 24 | 25 | ## Run in docker-compose with a traefik load balancer (https) 26 | 27 | You can use the following `docker-compose.yml` file with traefik v2: 28 | 29 | ```yaml 30 | version: '2' 31 | services: 32 | keeweb: 33 | image: slurdge/keewebdav:latest 34 | container_name: keeweb 35 | restart: always 36 | volumes: 37 | - ./data:/srv/dav 38 | labels: 39 | - "traefik.http.routers.keeweb.rule=Host(`example.com`)" 40 | - "traefik.http.routers.keeweb.tls.certresolver=le" 41 | networks: 42 | - proxy 43 | 44 | networks: 45 | proxy: 46 | external: true 47 | ``` 48 | 49 | You can use the following `docker-compose.yml` file with traefik v1: 50 | 51 | ```yaml 52 | version: '2' 53 | services: 54 | keeweb: 55 | image: slurdge/keewebdav:latest 56 | container_name: keeweb 57 | restart: always 58 | volumes: 59 | - ./data:/srv/dav 60 | labels: 61 | - "traefik.enable=true" 62 | - "traefik.port=8080" 63 | - "traefik.frontend.rule=Host:example.com" 64 | - "traefik.docker.network=proxy" 65 | networks: 66 | - proxy 67 | 68 | networks: 69 | proxy: 70 | external: true 71 | ``` 72 | 73 | Both examples supposes that there is a network named 'proxy' that is used by traefik. 74 | 75 | ## Extensions 76 | 77 | It's pretty easy to add http-auth to caddy and even https. Please send PR if you want this functionality included. 78 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "settings": { 3 | "expandGroups": false, 4 | "demoOpened": true, 5 | "canOpenDemo": false, 6 | "dropbox": false, 7 | "gdrive": false, 8 | "onedrive": false, 9 | "canImportXml": false, 10 | "webdavSaveMethod": "put" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /versions/caddy.txt: -------------------------------------------------------------------------------- 1 | v2.8.4 2 | -------------------------------------------------------------------------------- /versions/keeweb.txt: -------------------------------------------------------------------------------- 1 | v1.18.7 2 | --------------------------------------------------------------------------------