Skip to content

keeweb/keeweb

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

43 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Docker image for Keeweb

πŸ”‘ Keeweb Password Manager πŸ”‘


The πŸ”€ docker/keeweb branch contains the Keeweb password manager within a docker image, which allows you to host it within Docker, instead of a bare-metal or local install.





Version Docker Version Downloads Docker Pulls Build Status Size Last Commit







About

This repository contains Keeweb Password Manager, distributed within a docker image which can be deployed and utilized in your browser.




Images

Use any of the following images in your πŸ“„ docker-compose.yml or run command:


Service Version Image Link
Docker Hub Docker Version πŸ”– keeweb/keeweb:latest
πŸ”– keeweb/keeweb:1.19.0
πŸ”– keeweb/keeweb:1.19.0-amd64
πŸ”– keeweb/keeweb:1.19.0-arm64
πŸ”– keeweb/keeweb:development
πŸ”– keeweb/keeweb:development-amd64
πŸ”– keeweb/keeweb:development-arm64
Github Github Version πŸ”– ghcr.io/keeweb/keeweb:latest
πŸ”– ghcr.io/keeweb/keeweb:1.19.0
πŸ”– ghcr.io/keeweb/keeweb:1.19.0-amd64
πŸ”– ghcr.io/keeweb/keeweb:1.19.0-arm64
πŸ”– ghcr.io/keeweb/keeweb:development
πŸ”– ghcr.io/keeweb/keeweb:development-amd64
πŸ”– ghcr.io/keeweb/keeweb:development-arm64



Install

Instructions on using this container


Docker Run

If you want to bring the docker container up quickly, use the following command:

docker run -d --restart=unless-stopped -p 443:443 --name keeweb -v ${PWD}/keeweb:/config ghcr.io/keeweb/keeweb:latest

Docker Compose

Create a new πŸ“„ docker-compose.yml with the following:

services:
    keeweb:
        container_name: keeweb
        image: ghcr.io/keeweb/keeweb:latest          # Github image
      # image: keeweb/keeweb:latest                  # Dockerhub image
        restart: unless-stopped
        volumes:
            - ./keeweb:/config
        environment:
            - PUID=1000
            - PGID=1000
            - TZ=Etc/UTC


Traefik Integration


Note

These steps are optional.

If you do not use Traefik, you can skip this section of steps. This is only for users who wish to put this container behind Traefik.

If you do not wish to use Traefik, remember that if you make your Keeweb container public facing, you will need to utilize a service such as certbot/lets encrypt to generate SSL certificates.


Our first step is to tell Traefik about our Keeweb container. We highly recommend you utilize a Traefik dynamic file, instead of labels. Using a dynamic file allows for automatic refreshing without the need to restart Traefik when a change is made.

If you decide to use labels instead of a dynamic file, any changes you want to make to your labels will require a restart of Traefik.


We will be setting up the following:

  • A middleware to re-direct http to https
  • A route to access Keeweb via http (optional)
  • A route to access Keeweb via https (secure)
  • A service to tell Traefik how to access your Keeweb container
  • A resolver so that Traefik can generate and apply a wildcard SSL certificate

Labels

To add Keeweb to Traefik, you will need to open your πŸ“„ docker-compose.yml and apply the following labels to your Keeweb container. Ensure you change domain.lan to your actual domain name.

services:
    keeweb:
        container_name: keeweb
        image: ghcr.io/keeweb/keeweb:latest       # Github image
      # image: keeweb/keeweb:latest               # Dockerhub image
        restart: unless-stopped
        volumes:
            - ./keeweb:/config
        environment:
            - PUID=1000
            - PGID=1000
            - TZ=Etc/UTC
        labels:

          #   General
          - traefik.enable=true

          #   Router > http
          - traefik.http.routers.keeweb-http.rule=Host(`keeweb.localhost`) || Host(`keeweb.domain.lan`)
          - traefik.http.routers.keeweb-http.service=keeweb
          - traefik.http.routers.keeweb-http.entrypoints=http
          - traefik.http.routers.keeweb-http.middlewares=https-redirect@file

          #   Router > https
          - traefik.http.routers.keeweb-https.rule=Host(`keeweb.localhost`) || Host(`keeweb.domain.lan`)
          - traefik.http.routers.keeweb-https.service=keeweb
          - traefik.http.routers.keeweb-https.entrypoints=https
          - traefik.http.routers.keeweb-https.tls=true
          - traefik.http.routers.keeweb-https.tls.certresolver=cloudflare
          - traefik.http.routers.keeweb-https.tls.domains[0].main=domain.lan
          - traefik.http.routers.keeweb-https.tls.domains[0].sans=*.domain.lan

          #   Load Balancer
          - traefik.http.services.keeweb.loadbalancer.server.port=443
          - traefik.http.services.keeweb.loadbalancer.server.scheme=https

After you've added the labels above, skip the dynamic.yml section and go straight to the static.yml section.



Dynamic.yml

If you decide to not use labels and want to use a dynamic file, you will first need to create your dynamic file. the Traefik dynamic file is usually named dynamic.yml. We need to add a new middleware, router, and service to our Traefik dynamic file so that it knows about our new Keeweb container and where it is.

http:
    middlewares:
        https-redirect:
            redirectScheme:
                scheme: "https"
                permanent: true

    routers:
        keeweb-http:
            service: keeweb
            rule: Host(`keeweb.localhost`) || Host(`keeweb.domain.lan`)
            entryPoints:
                - http
            middlewares:
                - https-redirect@file

        keeweb-https:
            service: keeweb
            rule: Host(`keeweb.localhost`) || Host(`keeweb.domain.lan`)
            entryPoints:
                - https
            tls:
                certResolver: cloudflare
                domains:
                    - main: "domain.lan"
                      sans:
                          - "*.domain.lan"

    services:
        keeweb:
            loadBalancer:
                servers:
                    - url: "https://keeweb:443"

Static.yml

These entries will go in your Traefik static.yml file. Any changes made to this file requires that you restart Traefik afterward.


Providers

Note

This step is only for users who opted to use the dynamic file method.

Users who opted to use labels can skip to the section certificatesResolvers


Ensure you add the following new section to your static.yml:


providers:
    docker:
        endpoint: "unix:///var/run/docker.sock"
        exposedByDefault: false
        network: traefik
        watch: true
    file:
        filename: "/etc/traefik/dynamic.yml"
        watch: true

The code above is what enables the use of a dynamic file instead of labels. Change /etc/traefik/dynamic.yml if you are placing your dynamic file in a different location. This path is relative to inside the container, not your host machine mounted volume path. Traefik keeps most files in the /etc/traefik/ folder.


After you add the above, open your Traefik's πŸ“„ docker-compose.yml file and mount a new volume so that Traefik knows where your new dynamic file is:

    traefik:
        container_name: traefik
        image: traefik:latest
        restart: unless-stopped
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock:ro
            - /etc/localtime:/etc/localtime:ro
            - ./config/traefik.yml:/etc/traefik/traefik.yml:ro
            - ./config/dynamic.yml:/etc/traefik/dynamic.yml:ro

You must ensure you add a new volume like shown above:

  • /config/dynamic.yml:/etc/traefik/dynamic.yml:ro

On your host machine, make sure you place the dynamic.yml file in a sub-folder called config, which should be inside the same folder where your Traefik's πŸ“„ docker-compose.yml file is. If you want to change this location, ensure you change the mounted volume path above.


After you have completed this, proceed to the section certificatesResolvers.


certificatesResolvers

Note

This step is required no matter which option you picked above, both for dynamic file setups, as well as people using labels.


Open your Traefik static.yml file. We need to define the certResolver that we added above either in your dynamic file, or label. To define the certResolver, we will be adding a new section labeled certificatesResolvers. We are going to use Cloudflare in this example, you can use whatever from the list at:


certificatesResolvers:
    cloudflare:
        acme:
            email: youremail@address.com
            storage: /cloudflare/acme.json
            keyType: EC256
            preferredChain: 'ISRG Root X1'
            dnsChallenge:
                provider: cloudflare
                delayBeforeCheck: 15
                resolvers:
                    - "1.1.1.1:53"
                    - "1.0.0.1:53"
                disablePropagationCheck: true

Once you pick the DNS / SSL provider you want to use from the code above, you need to see if that provider has any special environment variables that must be set. The Providers Page lists all providers and also what env variables need set for each one.


In our example, since we are using Cloudflare for dnsChallenge -> provider, we must set the following environment variables:

  • CF_API_EMAIL
  • CF_API_KEY

Create a .env environment file in the same folder where your Traefik πŸ“„ docker-compose.yml file is located, and add the following:

CF_API_EMAIL=yourcloudflare@email.com
CF_API_KEY=Your-Cloudflare-API-Key

Save the .env file and exit. For these environment variables to be detected by Traefik, you must give your Traefik container a restart. Until you restart Traefik, it will not be able to generate your new SSL certificates.

You can wait and restart in a moment after you finish editing the static.yml file, as there are more items to add below.


entryPoints (Normal)

Finally, inside the Traefik static.yml, we need to make sure we have our entryPoints configured. Add the following to the Traefik static.yml file only if you DON'T have entry points set yet:

entryPoints:
    http:
        address: :80
        http:
            redirections:
                entryPoint:
                    to: https
                    scheme: https

    https:
        address: :443
        http3: {}
        http:
            tls:
                options: default
                certResolver: cloudflare
                domains:
                    - main: domain.lan
                      sans:
                          - '*.domain.lan'

entryPoints (Cloudflare)

If your website is behind Cloudflare's proxy service, you need to modify your entryPoints above so that you can automatically allow Cloudflare's IP addresses through. This means your entry points will look a bit different.


In the example below, we will add forwardedHeaders -> trustedIPs and add all of Cloudflare's IPs to the list which are available here:

    http:
        address: :80
        forwardedHeaders:
            trustedIPs: &trustedIps
                - 103.21.244.0/22
                - 103.22.200.0/22
                - 103.31.4.0/22
                - 104.16.0.0/13
                - 104.24.0.0/14
                - 108.162.192.0/18
                - 131.0.72.0/22
                - 141.101.64.0/18
                - 162.158.0.0/15
                - 172.64.0.0/13
                - 173.245.48.0/20
                - 188.114.96.0/20
                - 190.93.240.0/20
                - 197.234.240.0/22
                - 198.41.128.0/17
                - 2400:cb00::/32
                - 2606:4700::/32
                - 2803:f800::/32
                - 2405:b500::/32
                - 2405:8100::/32
                - 2a06:98c0::/29
                - 2c0f:f248::/32
        http:
            redirections:
                entryPoint:
                    to: https
                    scheme: https

    https:
        address: :443
        http3: {}
        forwardedHeaders:
            trustedIPs: *trustedIps
        http:
            tls:
                options: default
                certResolver: cloudflare
                domains:
                    - main: domain.lan
                      sans:
                          - '*.domain.lan'

Save the files and then give Traefik and your Keeweb containers a restart.




Authentik Integration

This section will not explain how to install and set up Authentik. We are only going to cover adding Keeweb integration to Authentik.


Sign into the Authentik admin panel, go to the left-side navigation, select Applications -> Providers. Then at the top of the new page, click Create.



Authentik: Select Applications β€Ί Providers



Authentik: Select Create


For the provider, select Proxy Provider.



Authentik: Select desired provider type, or select Proxy Provider


Add the following provider values:

  • Name: Keeweb ForwardAuth
  • Authentication Flow: default-source-authentication (Welcome to authentik!)
  • Authorization Flow: default-provider-authorization-implicit-consent (Authorize Application)

Select Forward Auth (single application):

  • External Host: https://keeweb.domain.lan


Authentik: Create new Provider


Once finished, click Create. Then on the left-side menu, select Applications -> Applications. Then at the top of the new page, click Create.



Authentik: Select Applications β€Ί Applications



Authentik: Select Create


Add the following parameters:

  • Name: Keeweb (Password Manager)
  • Slug: keeweb
  • Group: Security
  • Provider: Keeweb ForwardAuth
  • Backchannel Providers: None
  • Policy Engine Mode: any


Authentik: Create Application


Save, and then on the left-side menu, select Applications -> Outposts:



Authentik: Select Applications β€Ί Outposts


Find your Outpost and edit it.


Authentik: Edit outpost


Move Keeweb (Password Manager) to the right side Selected Applications box.



Authentik: Assign application to outpost


If you followed our Traefik guide above, you were shown how to add your Keeweb container to Traefik using either the πŸ“„ dynamic file or labels. Depending on which option you picked, follow that section's guide below.


Labels

Open your Keeweb's πŸ“„ docker-compose.yml and modify your labels to include Authentik as a middleware by adding authentik@file to the label traefik.http.routers.keeweb-https.middlewares. You should have something similar to the example below:

services:
    keeweb:
        container_name: keeweb
        image: ghcr.io/keeweb/keeweb:latest       # Github image
      # image: keeweb/keeweb:latest               # Dockerhub image
        restart: unless-stopped
        volumes:
            - ./keeweb:/config
        environment:
            - PUID=1000
            - PGID=1000
            - TZ=Etc/UTC
        labels:

          #   General
          - traefik.enable=true

          #   Router > http
          - traefik.http.routers.keeweb-http.rule=Host(`keeweb.localhost`) || Host(`keeweb.domain.lan`)
          - traefik.http.routers.keeweb-http.service=keeweb
          - traefik.http.routers.keeweb-http.entrypoints=http
          - traefik.http.routers.keeweb-http.middlewares=https-redirect@file

          #   Router > https
          - traefik.http.routers.keeweb-https.rule=Host(`keeweb.localhost`) || Host(`keeweb.domain.lan`)
          - traefik.http.routers.keeweb-https.service=keeweb
          - traefik.http.routers.keeweb-https.entrypoints=https
          - traefik.http.routers.keeweb-https.middlewares=authentik@file
          - traefik.http.routers.keeweb-https.tls=true
          - traefik.http.routers.keeweb-https.tls.certresolver=cloudflare
          - traefik.http.routers.keeweb-https.tls.domains[0].main=domain.lan
          - traefik.http.routers.keeweb-https.tls.domains[0].sans=*.domain.lan

          #   Load Balancer
          - traefik.http.services.keeweb.loadbalancer.server.port=443
          - traefik.http.services.keeweb.loadbalancer.server.scheme=https

Dynamic.yml

If you opted to use the πŸ“„ dynamic file, open your Traefik's πŸ“„ dynamic.yml file and apply the authentik@file middleware to look something like the following:


        keeweb-https:
            service: keeweb
            rule: Host(`keeweb.localhost`) || Host(`keeweb.domain.com`)
            entryPoints:
                - https
            middlewares:
                - authentik@file
            tls:
                certResolver: cloudflare
                domains:
                    - main: "domain.com"
                      sans:
                          - "*.domain.com"

After you've done everything above, give your Traefik and Authentik containers a restart. Once they come back up; you should be able to access keeweb.domain.lan and be prompted now to authenticate with Authentik. Once you authenticate, you should be re-directed to your Keeweb home screen which asks you to load a vault file.




Env Variables & Volumes

This section outlines that environment variables can be specified, and which volumes you can mount when the container is started.


Environment Variables

The following env variables can be modified before spinning up this container:


Env Var Default Description
PUID 1000 User ID running the container
PGID 1000 Group ID running the container
TZ Etc/UTC Timezone
PORT_HTTP 80 Defines the HTTP port to run on
PORT_HTTPS 443 Defines the HTTPS port to run on

Volumes

The following volumes can be mounted with this container:


Volume Description
./keeweb:/config Path which stores Keeweb, nginx configs, and optional SSL certificate/keys
./custom-scripts:/custom-cont-init.d:ro Experts Only: Allows you to load advanced startup scripts executed when the container comes online

By mounting the volume above, you should now have access to the following folders:

Folder Description
πŸ“ keys SSL certificate cert.crt + key cert.key
πŸ“ log All nginx and php logs
πŸ“ nginx nginx.conf, resolver.conf, ssl.conf, site-confs
πŸ“ www Folder which stores the Keeweb files, images, and plugins



Shell / Bash

You can access the docker container's shell by running:

docker exec -it keeweb ash



SSL Certificates

This docker image automatically generates an SSL certificate when the nginx server is brought online.


You may opt to either use the generated self-signed certificate, or you can add your own. If you decide to use your own self-signed certificate, ensure you have mounted the /config volume in your πŸ“„ docker-compose.yml:

services:
    keeweb:
        container_name: keeweb
        image: ghcr.io/keeweb/keeweb:latest    # Github image
        restart: unless-stopped
        volumes:
            - ./keeweb:/config

Then navigate to the newly mounted folder and add your πŸ“„ cert.crt and πŸ”‘ cert.key files to the πŸ“ /keeweb/keys/* folder.


Note

If you are generating your own certificate and key, we recommend a minimum of:

  • RSA: 2048 bits
  • ECC: 256 bits
  • ECDSA: P-384 or P-521



Logs

This image spits out detailed information about its current progress. You can either use docker logs or a 3rd party app such as Portainer to view the logs.


 Migrations   : Started
 Migrations   : 01-nginx-site-confs-default β€Ί Skipped
 Migrations   : Complete
──────────────────────────────────────────────────────────────────────────────────────────
                              Keeweb Password Manager                             
──────────────────────────────────────────────────────────────────────────────────────────
  Thanks for choosing Keeweb. Get started with some of the links below:

        Official Repo           https://github.com/keeweb/keeweb
        Official Site           https://keeweb.info/
        Beta Demo               https://beta.keeweb.info/
        Web App                 https://app.keeweb.info/
        Favicon Service         https://services.keeweb.info/favicon

  If you are making this copy of Keeweb available on a public-facing domain,
  please consider using Traefik and Authentik to protect this container from
  outside access.

        User:Group              1000:1000
        (Ports) HTTP/HTTPS      80/443
──────────────────────────────────────────────────────────────────────────────────────────

 SSL          : Using existing keys found in /config/keys
 Loader       : Custom files found, loading them ...
 Loader       : Executing ...
 Loader       : Checking keeweb-plugins
 Loader       : keeweb-plugins already installed in /config/www/plugins; skipping
 Loader       : plugins: Exited 0
 Core         : Completed loading container



Build

To build your own Keeweb docker image, there are numerous things to remember. Our Keeweb docker image is built from several parts which we host within different branches of our repo.

Branch Description
πŸ”€ docker/alpine-base The base alpine image, which installs alpine, nginx, minimal packages, and SSL
πŸ”€ docker/core These scripts are loaded by the πŸ”€ docker/alpine-base πŸ“„ Dockerfile
πŸ”€ docker/keeweb This branch, which stores the Keeweb docker image files

To build a docker image for Keeweb, you need two different docker images:

  • Step 1: Build πŸ”€ docker/alpine-base image
    • When being build, the alpine-base πŸ“„ Dockerfile will grab and install the files from this branch πŸ”€ docker/core
  • Step 2: Build πŸ”€ docker/keeweb image
  • Step 3: Release the docker image built from Step 2 to Github's Ghcr.io or hub.docker.com

Warning

You should NOT need to modify any of the files within this branch πŸ”€ docker/keeweb unless you absolutely know what you are doing.


Before Building

Prior to building the πŸ”€ docker/alpine-base and πŸ”€ docker/keeweb docker images, you must ensure the following conditions are met. If the below tasks are not performed, your docker container will throw the following errors when started:

  • Failed to open apk database: Permission denied
  • s6-rc: warning: unable to start service init-adduser: command exited 127
  • unable to exec /etc/s6-overlay/s6-rc.d/init-envfile/run: Permission denied
  • /etc/s6-overlay/s6-rc.d/init-adduser/run: line 34: kwown: command not found
  • /etc/s6-overlay/s6-rc.d/init-adduser/run: /usr/bin/kwown: cannot execute: required file not found

LF over CRLF

You cannot utilize Windows' Carriage Return Line Feed. All files must be converted to Unix' Line Feed. This can be done with Visual Studio Code. OR; you can run the Linux terminal command dos2unix to convert these files.

For the branches πŸ”€ docker/alpine-base and πŸ”€ docker/keeweb, you can use the following recursive commands:


Caution

Be careful using the command to change ALL files. You should NOT change the files in your .git folder, otherwise you will corrupt your git indexes.

If you accidentally run dos2unix on your .git folder, do NOT push anything to git. Pull a new copy from the repo.


# Change ALL files
find ./ -type f | grep -Ev '.git|*.jpg|*.jpeg|*.png' | xargs dos2unix --

# Change run / binaries
find ./ -type f -name 'run' | xargs dos2unix --

For the branch πŸ”€ docker/core, you can use the following commands:

dos2unix docker-images.v3
dos2unix kwown.v1
dos2unix package-install.v1
dos2unix with-contenv.v1

Set +x / 0755 Permissions

The files contained within this repo MUST have chmod 755 / +x executable permissions. If you are using the Keeweb Github Workflow, this is done automatically. If you are builting the images manually; you need to do this. Ensure those files have the correct permissions prior to building the Alpine base docker image.

If you are building the πŸ”€ docker/alpine-base or πŸ”€ docker/keeweb images, you must ensure the files in those branches have the proper permissions. All of the executable files are named run:

find ./ -name 'run' -exec chmod +x {} \;

If you want to set the permissions manually, run the following:

sudo chmod +x /root/etc/s6-overlay/s6-rc.d/init-adduser/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/init-crontab-config/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/init-custom-files/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/init-envfile/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/init-folders/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/init-keygen/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/init-migrations/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/init-nginx/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/init-permissions/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/init-php/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/init-samples/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/init-version-checks/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/svc-cron/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/svc-nginx/run
sudo chmod +x /root/etc/s6-overlay/s6-rc.d/svc-php-fpm/run

For the branch πŸ”€ docker/core, there are a few files to change. The ending version number may change, but the commands to change the permissions are as follows:

sudo chmod +x docker-images.v3
sudo chmod +x kwown.v1
sudo chmod +x package-install.v1
sudo chmod +x with-contenv.v1

Build docker/alpine-base Image

The scripts contained within this πŸ”€ docker/core branch do not need anything done to them. In order to use these scripts, clone the Keeweb Alpine Base branch πŸ”€ docker/alpine-base:

git clone -b docker/alpine-base https://github.com/keeweb/keeweb.git .

Once cloned, the calls to include the scripts in this πŸ”€ docker/core branch are within the πŸ“„ Dockerfile and πŸ“„ Dockerfile.aarch64. All you need to do is simply build your alpine-base image:

amd64

# Build keeweb alpine-base amd64 πŸ–₯️
docker build --build-arg VERSION=3.20 --build-arg BUILD_DATE=20241216 -t alpine-base:latest -t alpine-base:3.20-amd64 -f Dockerfile .

arm64 / aarch64

# Build keeweb alpine-base arm64 πŸ–₯️
docker build --build-arg VERSION=3.20 --build-arg BUILD_DATE=20241216 -t alpine-base:3.20-arm64 -f Dockerfile.aarch64 .

The flow of the process is outlined below:

%%{init: { 'themeVariables': { 'fontSize': '10px' }}}%%
flowchart TB

subgraph GRAPH_KEEWEB ["Build keeweb:latest"]
    direction TB
    obj_step10["`> git clone -b docker/keeweb github.com/keeweb/keeweb.git`"]
    obj_step11["`**Dockerfile
     Dockerfile.aarch64**`"]
    obj_step12["`> docker build \
    --build-arg VERSION=1.19.0 \
    --build-arg BUILD_DATE=20241216 \
    -t keeweb:latest \
    -t keeweb:1.19.0-amd64 \
    -f Dockerfile . \`"]
    obj_step13["`Download **alpine-base** from branch **docker/alpine-base**`"]
    obj_step14["`New Image: **keeweb:latest**`"]

    style obj_step10 text-align:center,stroke-width:1px,stroke:#555
    style obj_step11 text-align:left,stroke-width:1px,stroke:#555
    style obj_step12 text-align:left,stroke-width:1px,stroke:#555
    style obj_step13 text-align:left,stroke-width:1px,stroke:#555
end

style GRAPH_KEEWEB text-align:center,stroke-width:1px,stroke:transparent,fill:transparent

subgraph GRAPH_ALPINE["Build alpine-base:latest Image"]
direction TB
    obj_step20["`> git clone -b docker/alpine-base github.com/keeweb/keeweb.git`"]
    obj_step21["`**Dockerfile
     Dockerfile.aarch64**`"]
    obj_step22["`> docker build \
    --build-arg VERSION=3.20 \
    --build-arg BUILD_DATE=20241216 \
    -t docker-alpine-base:latest \
    -t docker-alpine-base:3.20-amd64 \
    -f Dockerfile . \`"]
    obj_step23["`Download files from branch **docker/core**`"]
    obj_step24["`New Image: **alpine-base:latest**`"]

    style obj_step20 text-align:center,stroke-width:1px,stroke:#555
    style obj_step21 text-align:left,stroke-width:1px,stroke:#555
    style obj_step22 text-align:left,stroke-width:1px,stroke:#555
    style obj_step23 text-align:left,stroke-width:1px,stroke:#555
end

style GRAPH_ALPINE text-align:center,stroke-width:1px,stroke:transparent,fill:transparent

GRAPH_KEEWEB --> obj_step10 --> obj_step11 --> obj_step12 --> obj_step13 --> obj_step14
GRAPH_ALPINE --> obj_step20 --> obj_step21 --> obj_step22 --> obj_step23 --> obj_step24
Loading

Once the base alpine image is built, you can now build the actual docker version of Keeweb. The files for this docker image are stored in the branch πŸ”€ docker/keeweb:


Build docker/keeweb Image

After the πŸ”€ docker/alpine-base image is built, you can now use that docker image as a base to build the πŸ”€ docker/keeweb image. Navigate to the branch πŸ”€ docker/keeweb and open the files:

  • πŸ“„ Dockerfile
  • πŸ“„ Dockerfile.aarch64

Next, specify the πŸ”€ docker/alpine-base image which will be used as the foundation of the πŸ”€ docker/keeweb image:

# πŸ“„ Dockerfile
FROM ghcr.io/keeweb/alpine-base:3.20-amd64

# πŸ“„ Dockerfile.aarch64
FROM ghcr.io/keeweb/alpine-base:3.20-arm64

After you have completed configuring the πŸ”€ docker/keeweb πŸ“„ Dockerfile, you can now build the official version of Keeweb. Remember to build an image for both amd64 and aarch64.


For the argument VERSION; specify the current release of Keeweb which will be contained within the docker image. It should be in the format of YYYYMMDD:


amd64

# Build docker/keeweb amd64
docker build --build-arg VERSION=1.19.0 --build-arg BUILD_DATE=20241216 -t keeweb:latest -t keeweb:1.19.0 -t keeweb:1.19.0-amd64 -f Dockerfile .

arm64 / aarch64

# Build docker/keeweb arm64
docker build --build-arg VERSION=1.19.0 --build-arg BUILD_DATE=20241216 -t keeweb:1.19.0-arm64 -f Dockerfile.aarch64 .

Upload: hub.docker.com / ghcr.io / local

After you have your πŸ”€ docker/keeweb image built, you can either upload the image to a public repository such as:

  • hub.docker.com (Docker Hub)
  • ghcr.io (Github)

After it is uploaded, you can use the docker run command, or create a πŸ“„ docker-compose.yml, and call the docker image to be used.

This is discussed in the section Using docker/keeweb Image below.


Image Tags

When building your images with the commands provided above, ensure you create two sets of tags:

Architecture Dockerfile Tags
πŸ–₯️ amd64 πŸ“„ Dockerfile πŸ”– keeweb:latest
πŸ”– keeweb:1.19.0
πŸ”– keeweb:1.19.0-amd64
πŸ–₯️ arm64 πŸ“„ Dockerfile.aarch64 πŸ”– keeweb:1.19.0-arm64

the πŸ–₯️ amd64 arch gets a few extra tags because it should be the default image people download.


Extra Notes

The following are other things to take into consideration when creating the πŸ”€ docker/alpine-base and πŸ”€ docker/keeweb images:


Custom Scripts

The πŸ”€ docker/alpine-base and πŸ”€ docker/keeweb images support the ability of adding custom scripts that will be ran when the container is started. To create / add a new custom script to the container, you need to create a new folder in the container source files /root folder

mkdir -p /root/custom-cont-init.d/

Within this new folder, add your custom script:

nano /root/custom-cont-init.d/my_customs_script

#!/bin/bash

echo "**** INSTALLING BASH ****"
apk add --no-cache bash

When you create the docker image, this new script will automatically be loaded. You can also do this via the πŸ“„ docker-compose.yml file by mounting a new volume:

services:
    keeweb:
        volumes:
            - ./keeweb:/config
            - ./custom-scripts:/custom-cont-init.d:ro

Note

if using compose, we recommend mounting them read-only (:ro) so that container processes cannot write to the location.

Warning

The folder πŸ“‚ /root/custom-cont-init.d MUST be owned by root. If this is not the case, this folder will be renamed and a new empty folder will be created. This is to prevent remote code execution by putting scripts in the aforesaid folder.


The πŸ”€ docker/keeweb image already contains a custom script called πŸ“„ /root/custom-cont-init.d/plugins. Do NOT edit this script. It is what automatically downloads the official Keeweb plugins and adds them to the container.


Associated Workflows

The following workflows are associated to the Keeweb docker image and management of the files:


Prior to v1.19.0, the docker image source files for Keeweb were stored in the πŸ”€ main / master branch within the folder πŸ“ package/docker. Upon release of v1.19.0, the primary storage location of these source files were migrated to their own independent branch πŸ”€ docker/keeweb.

We utilize the Github workflow deploy-docker-github-sync.yml to copy the source files from the πŸ”€ docker/keeweb branch over to the πŸ”€ main / master branch.



deploy-docker-github-sync.yml manual workflow trigger


Once the workflow is triggered, it will copy the following from the branch πŸ”€ docker/keeweb

  • πŸ“ root
  • πŸ“„ Dockerfile
  • πŸ“„ Dockerfile.aarch64

This workflow triggers under a few different conditions:

  • ☝️ Manual Activation

    When the workflow is activated manually (via the trigger workflow_dispatch), you can select which branch to copy the docker files to.



    deploy-docker-github-sync.yml destination branch to
    copy docker files to


    In the screenshot above, if you select the branch πŸ”€ develop/1.19.0, the docker files from the branch πŸ”€ docker/keeweb will be copied to the branch πŸ”€ develop/1.19.0 within the folder πŸ“‚ package/docker.


    Manual activation gives you the ability to adjust a few settings

    Setting Description
    Use workflow from Destination branch where the docker files will be copied to
    πŸ”€ Branch β€Ί Source Source branch which contains the docker files
    πŸ“‚ Folder β€Ί Destination Destination folder where the docker files will be copied to
    πŸ› Dry Run (Debug) Dry run test; does not actually commit changes for files

  • ⬆️ Push

    The workflow deploy-docker-github-sync.yml will be triggered each time a push is made to the branch πŸ”€ docker/keeweb. The docker files within the branch πŸ”€ docker/keeweb will be copied over to the repositories' default branch which is either πŸ”€ master or πŸ”€ main.


The workflow deploy-docker-github.yml is responsible for each new release of the Keeweb docker image available to the public.

Upon the workflow being triggered, the branch πŸ”€ docker/keeweb will be accessed, and the files that make up the docker image will be compiled into new public releases for each offered architecture.

  • πŸ–₯️ amd64: πŸ“„ Dockerfile
  • πŸ–₯️ arm64: πŸ“„ Dockerfile.aarch64

Once the new docker images are built, they will be pushed to Github's ghcr.io repository service, and available at:



deploy-docker-github.yml manual triggering


This workflow triggers under a few different conditions:

  • ☝️ Manual Activation

    When the workflow is activated manually (via the trigger workflow_dispatch), you are given a few settings you can adjust.



    deploy-docker-github.yml manual trigger options


    Manual activation gives you the ability to adjust a few settings

    Setting Description
    Use workflow from Branch where action is activated. Keep this on πŸ”€ master / main
    πŸ“¦ Image Name Name of the image to display on packages page
    πŸͺͺ Image Author Author of image
    🏷️ Image Version Version of the docker image to be released
    πŸͺͺ ghcr.io Username Username associated to the Github ghcr.io service
    πŸ› Dry Run (Debug) Simulates a run and outputs debug info, does not actually push an image
    πŸ§ͺ Development Release Adds the πŸ”– -development tag to each docker image

    If not checked, a release will get the πŸ”– -latest tag

  • πŸ”– Tag Push

    The workflow deploy-docker-github.yml will be triggered each time a new tag is created. Upon tag creation, the workflow will create a set of new docker images for each offered architecture.


    The tag assigned to the docker image will be the tag created on the repo's releases page.



    Triggering workflow by creating new tag


Note

This trigger is not widely used. Creating a release tag for each docker release would mean that these would mix in with the list of Keeweb releases.


Existing release tags


The workflow deploy-docker-dockerhub.yml is responsible for each new release of the Keeweb docker image available to the public.

Upon the workflow being triggered, the branch πŸ”€ docker/keeweb will be accessed, and the files that make up the docker image will be compiled into new public releases for each offered architecture.

  • πŸ–₯️ amd64: πŸ“„ Dockerfile
  • πŸ–₯️ arm64: πŸ“„ Dockerfile.aarch64

Once the new docker images are built, they will be pushed to Dockerhub, and available at:



deploy-docker-dockerhub.yml manual triggering


This workflow triggers under a few different conditions:

  • ☝️ Manual Activation

    When the workflow is activated manually (via the trigger workflow_dispatch), you are given a few settings you can adjust.



    deploy-docker-dockerhub.yml manual trigger options


    Manual activation gives you the ability to adjust a few settings

    Setting Description
    Use workflow from Branch where action is activated. Keep this on πŸ”€ master / main
    πŸ“¦ Image Name Name of the image to display on packages page
    πŸͺͺ Image Author Author of image
    🏷️ Image Version Version of the docker image to be released
    πŸͺͺ Dockerhub Username Username associated to Dockerhub
    πŸ› Dry Run (Debug) Simulates a run and outputs debug info, does not actually push an image
    πŸ§ͺ Development Release Adds the πŸ”– -development tag to each docker image

    If not checked, a release will get the πŸ”– -latest tag

  • πŸ”– Tag Push

    The workflow deploy-docker-dockerhub.yml will be triggered each time a new tag is created. Upon tag creation, the workflow will create a set of new docker images for each offered architecture.


    The tag assigned to the docker image will be the tag created on the repo's releases page.



    Triggering workflow by creating new tag


Note

This trigger is not widely used. Creating a release tag for each docker release would mean that these would mix in with the list of Keeweb releases.


Existing release tags