├── .ci ├── docker-hub-helper.sh ├── setup-tools.sh └── travis-buildkit.sh ├── .editorconfig ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── question.md ├── pull_request_template.md └── workflows │ ├── goss.yml │ ├── reviewdog.yml-off │ └── stale.yml ├── .gitignore ├── .gitmodules ├── .hadolint.yaml ├── .markdownlint.json ├── .pylintrc ├── .travis.yml-deactivated ├── .trivyignore ├── .yamllint ├── ARCHITECTURE.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── Makefile ├── README.md ├── Vagrantfile ├── base ├── Dockerfile ├── README.md ├── Release.key ├── create-kopano-repo.sh ├── defaultconfigs │ └── cfg-from-env.py ├── kcconf.py └── test.sh ├── build ├── Dockerfile ├── README.md └── run.sh ├── core ├── Dockerfile ├── Dockerfile.dagent ├── README.md ├── bin │ ├── kopano-autorespond │ ├── kopano-cli │ └── show-folders.py ├── commander │ ├── grapi │ │ └── commander.yaml │ ├── server │ │ └── commander.yaml │ └── spooler │ │ └── commander.yaml ├── defaultconfigs │ ├── dagent.py │ ├── gateway.py │ ├── grapi.py │ ├── ical.py │ ├── kapi.py │ ├── monitor.py │ ├── search.py │ ├── server.py │ ├── spamd.py │ └── spooler.py ├── goss │ ├── dagent │ │ ├── goss.yaml │ │ └── goss_wait.yaml │ ├── gateway │ │ ├── goss.yaml │ │ └── goss_wait.yaml │ ├── grapi │ │ ├── goss.yaml │ │ └── goss_wait.yaml │ ├── ical │ │ ├── goss.yaml │ │ └── goss_wait.yaml │ ├── kapi │ │ ├── goss.yaml │ │ └── goss_wait.yaml │ ├── monitor │ │ ├── goss.yaml │ │ └── goss_wait.yaml │ ├── search │ │ ├── goss.yaml │ │ └── goss_wait.yaml │ ├── server │ │ ├── goss.yaml │ │ └── goss_wait.yaml │ ├── spamd │ │ ├── goss.yaml │ │ └── goss_wait.yaml │ └── spooler │ │ ├── goss.yaml │ │ └── goss_wait.yaml ├── healthcheck.sh └── start-service.sh ├── database ├── README.md └── create-additional-databases.sh ├── docker-compose.db.yml ├── docker-compose.kwmbridge-dnat.yml ├── docker-compose.kwmbridge.yml ├── docker-compose.ldap.yml ├── docker-compose.mail.yml ├── docker-compose.ports.yml ├── docker-compose.yml ├── examples ├── apache-proxy.md ├── core.yml ├── docker-compose.override.yml-disable-mail ├── docker-compose.override.yml-minio ├── docker-compose.override.yml-watchtower ├── kopano-multiserver │ ├── README.md │ └── kopano-multiserver.yml ├── meet │ ├── README.md │ ├── architecture.md │ ├── docker-compose-sfu.yml │ ├── docker-compose.yml │ ├── env-example │ ├── setup.sh │ └── tests │ │ ├── startup-test │ │ ├── Dockerfile │ │ └── test.sh │ │ └── test-container.yml ├── traefik-proxy-subdomain.md └── webapp.yml ├── grapi-explorer ├── README.md └── grapi-explorer.yml ├── kapps ├── Dockerfile ├── README.md ├── goss.yaml └── start-service.sh ├── kdav ├── Dockerfile ├── README.md ├── kopano-kdav.conf ├── kweb.cfg └── start.sh ├── konnect ├── Dockerfile ├── README.md ├── commander.yaml ├── konnectd-identifier-registration.yaml ├── konnectd-identifier-scopes.yaml ├── test-helper.sh └── wrapper.sh ├── kwmbridge ├── Dockerfile ├── README.md └── wrapper.sh ├── kwmserver ├── Dockerfile ├── README.md └── wrapper.sh ├── ldap-extras ├── README.md ├── ldap-account-manager.yml └── ldap-extras.yml ├── ldap ├── Dockerfile ├── README.md └── bootstrap │ ├── ldif │ └── optimize-index.ldif │ └── schema │ └── mmc │ └── kopano.schema ├── ldap_demo ├── Dockerfile ├── README.md └── bootstrap │ └── ldif │ └── demo-users.ldif ├── meet ├── Dockerfile ├── README.md ├── goss.yaml └── start-service.sh ├── owncloud ├── .gitignore ├── 99-ldap.sh ├── 99-oidc.sh ├── README.md ├── config.json ├── kopano │ ├── LICENSE │ ├── README.md │ ├── appinfo │ │ └── info.xml │ ├── core │ │ ├── css │ │ │ └── styles.css │ │ └── img │ │ │ ├── favicon.ico │ │ │ └── kopano-logo.svg │ └── defaults.php ├── owncloud-phoenix.yml ├── owncloud.sh └── owncloud.yml ├── php ├── Dockerfile ├── README.md ├── kweb.cfg ├── php-fpm.conf └── start-helper.sh ├── playground ├── Dockerfile ├── README.md └── playground.yml ├── python ├── Dockerfile └── README.md ├── renovate.json ├── scheduler ├── Dockerfile ├── README.md ├── commander.yaml ├── goss.yaml ├── goss_wait.yaml └── start.sh ├── setup-update-tag.sh ├── setup.sh ├── spamd-extras ├── README.md └── spamd-extras.yml ├── ssl ├── Dockerfile ├── README.md └── start.sh ├── tests ├── README.md ├── commander-supported.yaml ├── commander.yaml ├── startup-test │ ├── Dockerfile │ └── test.sh ├── test-container.yml └── test.exp ├── utils ├── Dockerfile └── README.md ├── version.sh ├── web ├── Dockerfile ├── README.md ├── kweb.cfg ├── tls_auto ├── tls_custom ├── tls_off ├── tls_selfsigned └── wrapper.sh ├── webapp ├── Dockerfile ├── Dockerfile.demo ├── Dockerfile.plugins ├── README.md ├── commander.yaml ├── goss.yaml ├── goss_wait.yaml ├── kopano-webapp.conf ├── kweb.cfg └── start.sh └── zpush ├── Dockerfile ├── README.md ├── commander.yaml ├── kopano-z-push.conf ├── kweb.cfg └── start.sh /.ci/docker-hub-helper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # bash .travis/docker-hub-helper.sh base 3 | 4 | set -euo pipefail 5 | IFS=$'\n\t' 6 | 7 | # this is a kind of ugly hack to be able to source the env file 8 | # this is sadly needed since postfix in https://github.com/tomav/docker-mailserver/ cannot deal with quoted values 9 | tmpfile=$(mktemp /tmp/kopano-docker-env.XXXXXX) 10 | cp ./.env "$tmpfile" 11 | sed -i '/LDAP_QUERY_FILTER/s/^/#/g' "$tmpfile" 12 | sed -i '/SASLAUTHD_LDAP_FILTER/s/^/#/g' "$tmpfile" 13 | sed -i '/KCUNCOMMENT_LDAP_1/s/^/#/g' "$tmpfile" 14 | sed -i '/KCCOMMENT_LDAP_1/s/^/#/g' "$tmpfile" 15 | 16 | # shellcheck disable=SC1090 17 | source "$tmpfile" 18 | 19 | docker_repo=${docker_repo:-zokradonh} 20 | docker_login=${docker_login:-""} 21 | docker_pwd=${docker_pwd:-""} 22 | 23 | if [ -z "$docker_login" ]; then 24 | docker_login="$(<~/.docker-account-user)" 25 | fi 26 | 27 | if [ -z "$docker_pwd" ]; then 28 | docker_pwd="$(<~/.docker-account-pwd)" 29 | fi 30 | 31 | image=${1:-""} 32 | if [ -z "$image" ]; then 33 | echo "ERROR: You must specify an image to modify." 34 | exit 1 35 | fi 36 | 37 | # below code is based on https://github.com/moikot/golang-dep/blob/aab3ea8462a19407544f1ce9daa11c3f0924394c/.travis/push.sh 38 | # code has since then moved to https://github.com/moikot/docker-tools.git 39 | # 40 | # Pushes README.md content to Docker Hub. 41 | # 42 | # $1 - The image name. 43 | # $2 - The JWT. 44 | # 45 | # Examples: 46 | # 47 | # push_readme "foo/bar" "token" 48 | # 49 | push_readme() { 50 | declare -r image="${1}" 51 | declare -r token="${2}" 52 | declare -r readme="${3}" 53 | 54 | local code 55 | code=$(jq -n --arg msg "$(<"${readme}")" \ 56 | '{"registry":"registry-1.docker.io","full_description": $msg }' | \ 57 | curl -s -o /dev/null -L -w "%{http_code}" \ 58 | https://hub.docker.com/v2/repositories/"${image}"/ \ 59 | -d @- -X PATCH \ 60 | -H "Content-Type: application/json" \ 61 | -H "Authorization: JWT ${token}") 62 | 63 | if [[ "${code}" = "200" ]]; then 64 | printf "Successfully pushed README to Docker Hub" 65 | else 66 | printf "Unable to push README to Docker Hub, response code: %s\n" "${code}" 67 | exit 1 68 | fi 69 | 70 | local code 71 | code=$(jq -n --arg msg "$(head -n 1 "${readme}" | cut -d' ' -f2-)" \ 72 | '{"registry":"registry-1.docker.io","description": $msg }' | \ 73 | curl -s -o /dev/null -L -w "%{http_code}" \ 74 | https://hub.docker.com/v2/repositories/"${image}"/ \ 75 | -d @- -X PATCH \ 76 | -H "Content-Type: application/json" \ 77 | -H "Authorization: JWT ${token}") 78 | 79 | if [[ "${code}" = "200" ]]; then 80 | printf "Successfully pushed description to Docker Hub" 81 | else 82 | printf "Unable to push description to Docker Hub, response code: %s\n" "${code}" 83 | exit 1 84 | fi 85 | } 86 | 87 | # Login into Docker repository 88 | #echo "$docker_pwd" | docker login -u "$docker_login" --password-stdin 89 | 90 | token=$(curl -s -X POST \ 91 | -H "Content-Type: application/json" \ 92 | -d '{"username": "'"$docker_login"'", "password": "'"$docker_pwd"'"}' \ 93 | https://hub.docker.com/v2/users/login/ | jq -r .token) 94 | 95 | push_readme "${docker_repo}"/kopano_"${image}" "${token}" "${image}"/README.md 96 | 97 | if [ -e "$tmpfile" ]; then 98 | rm "$tmpfile" 99 | fi 100 | -------------------------------------------------------------------------------- /.ci/setup-tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | IFS=$'\n\t' 5 | 6 | COMMANDER_VERSION=2.1.0 7 | DOCKER_COMPOSE_VERSION=1.25.5 8 | GOSS_VERSION=0.3.11 9 | HADOLINT_VERSION=1.23.0 10 | REG_VERSION=0.16.1 11 | SHELLCHECK_VERSION=0.7.1 12 | 13 | progname=$(basename "$0") 14 | tempdir=$(mktemp -d "/tmp/$progname.XXXXXX") 15 | function cleanup() { 16 | rm -rf "$tempdir" 17 | } 18 | trap cleanup INT EXIT 19 | 20 | cd "$tempdir" 21 | 22 | if ! command -v hadolint > /dev/null; then 23 | sudo curl -L "https://github.com/hadolint/hadolint/releases/download/v$HADOLINT_VERSION/hadolint-$(uname -s)-$(uname -m)" -o /usr/local/bin/hadolint 24 | sudo chmod +rx /usr/local/bin/hadolint 25 | fi 26 | 27 | if ! command -v docker-compose > /dev/null; then 28 | sudo curl -L "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose 29 | sudo chmod +rx /usr/local/bin/docker-compose 30 | fi 31 | 32 | if ! command -v goss > /dev/null; then 33 | sudo curl -L https://github.com/aelsabbahy/goss/releases/download/v$GOSS_VERSION/goss-linux-amd64 -o /usr/local/bin/goss 34 | sudo chmod +rx /usr/local/bin/goss 35 | fi 36 | 37 | if ! command -v dcgoss > /dev/null; then 38 | sudo curl -L https://raw.githubusercontent.com/fbartels/goss/dcgoss-v2/extras/dcgoss/dcgoss -o /usr/local/bin/dcgoss 39 | sudo chmod +rx /usr/local/bin/dcgoss 40 | fi 41 | 42 | if ! command -v commander > /dev/null; then 43 | sudo curl -L https://github.com/SimonBaeumer/commander/releases/download/v$COMMANDER_VERSION/commander-linux-amd64 -o /usr/local/bin/commander 44 | sudo chmod +rx /usr/local/bin/commander 45 | fi 46 | 47 | if ! command -v dccommander > /dev/null; then 48 | sudo curl -L https://raw.githubusercontent.com/fbartels/dccommander/master/dccommander -o /usr/local/bin/dccommander 49 | sudo chmod +rx /usr/local/bin/dccommander 50 | fi 51 | 52 | if ! command -v reg > /dev/null; then 53 | sudo curl -L https://github.com/genuinetools/reg/releases/download/v$REG_VERSION/reg-linux-amd64 -o /usr/local/bin/reg 54 | sudo chmod +rx /usr/local/bin/reg 55 | fi 56 | 57 | if ! command -v expect > /dev/null; then 58 | sudo apt update && sudo apt install -y expect 59 | fi 60 | 61 | if ! command -v pip > /dev/null; then 62 | sudo apt install -y python-pip 63 | fi 64 | 65 | if ! command -v yamllint > /dev/null; then 66 | sudo pip install --upgrade pip && sudo pip install yamllint 67 | fi 68 | 69 | if ! command -v npm > /dev/null; then 70 | curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - 71 | sudo apt install -y nodejs 72 | npm config set prefix ~ 73 | fi 74 | 75 | if ! command -v eclint > /dev/null; then 76 | npm install eclint -g 77 | fi 78 | 79 | if ! command -v shellcheck > /dev/null; then 80 | wget "https://github.com/koalaman/shellcheck/releases/download/v$SHELLCHECK_VERSION/shellcheck-v$SHELLCHECK_VERSION.linux.x86_64.tar.xz" 81 | tar -xf shellcheck-v*.linux.x86_64.tar.xz 82 | sudo mv shellcheck-v*/shellcheck /usr/local/bin/ 83 | fi 84 | 85 | if ! command -v jq > /dev/null; then 86 | sudo apt install -y jq 87 | fi 88 | -------------------------------------------------------------------------------- /.ci/travis-buildkit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | IFS=$'\n\t' 5 | 6 | # update to latest docker for buildkit support 7 | curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 8 | sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" 9 | sudo apt-get update 10 | sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce 11 | 12 | # get base images to pull, as it will otherwise fail in travis 13 | # git ls-files | xargs awk -F' ' '/^FROM/ { print $2 }' | sort -n | uniq | xargs --max-lines=1 docker pull 14 | 15 | docker pull docker/dockerfile:1.0-experimental 16 | docker pull docker.io/docker/dockerfile-copy:v0.1.9 17 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig tool configuration 2 | # see http://editorconfig.org for docs 3 | 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | indent_style = tab 9 | end_of_line = lf 10 | trim_trailing_whitespaces = true 11 | 12 | [{*.{yml,yaml,yml-off},.yamllint}] 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.{md,txt}] 17 | indent_style = space 18 | trim_trailing_whitespace = false 19 | 20 | [Dockerfile*] 21 | indent_style = space 22 | indent_size = 4 23 | 24 | [*.py] 25 | indent_style = space 26 | indent_size = 4 27 | 28 | [*.ldif] 29 | indent_style = space 30 | 31 | [*.json] 32 | indent_style = space 33 | 34 | [LICENSE] 35 | indent_style = space 36 | 37 | [Vagrantfile] 38 | indent_style = space 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 16 | 1. Go to '...' 17 | 2. Click on '....' 18 | 3. Scroll down to '....' 19 | 4. See error 20 | 21 | **Expected behavior** 22 | A clear and concise description of what you expected to happen. 23 | 24 | **Screenshots** 25 | If applicable, add screenshots to help explain your problem. Please don't post screenshots text blocks such as logfiles or general console output. 26 | 27 | **Additional context** 28 | Add any other context about the problem here. Please check the [troubleshooting section](https://github.com/zokradonh/kopano-docker#troubleshooting) of the readme for additional details. 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Select this if you have a question 4 | title: '' 5 | labels: question 6 | assignees: '' 7 | 8 | --- 9 | 10 | # For general questions about Kopano please consider posting them on the [Kopano Forum](https://forum.kopano.io) instead. -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | Fixes # 2 | 3 | ## Proposed Changes 4 | 5 | - 6 | - 7 | - 8 | -------------------------------------------------------------------------------- /.github/workflows/goss.yml: -------------------------------------------------------------------------------- 1 | name: Weekly Goss check 2 | 3 | on: 4 | schedule: 5 | - cron: "5 8 * * 1" 6 | #on: [pull_request] 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v1 15 | - name: install expect 16 | run: sudo apt-get update && sudo apt-get install -y expect 17 | - name: create .env 18 | run: ./tests/test.exp 19 | - name: install goss 20 | run: sudo curl -L https://github.com/aelsabbahy/goss/releases/download/v0.3.9/goss-linux-amd64 -o /usr/local/bin/goss && sudo chmod +rx /usr/local/bin/goss 21 | - name: install dcgoss 22 | run: sudo curl -L https://raw.githubusercontent.com/aelsabbahy/goss/master/extras/dcgoss/dcgoss -o /usr/local/bin/dcgoss && sudo chmod +rx /usr/local/bin/dcgoss 23 | - name: Run goss tests 24 | run: make test-goss 25 | -------------------------------------------------------------------------------- /.github/workflows/reviewdog.yml-off: -------------------------------------------------------------------------------- 1 | name: Linting checks via Reviewdog 2 | on: [pull_request] 3 | jobs: 4 | reviewdog: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - name: Check out code. 8 | uses: actions/checkout@v1 9 | - name: misspell 10 | uses: reviewdog/action-misspell@v1 11 | with: 12 | github_token: ${{ secrets.github_token }} 13 | locale: "US" 14 | - name: eclint 15 | uses: fbartels/action-eclint@master 16 | with: 17 | github_token: ${{ secrets.github_token }} 18 | - name: yamllint 19 | uses: fbartels/action-yamllint@master 20 | with: 21 | github_token: ${{ secrets.github_token }} 22 | - name: shellcheck 23 | uses: fbartels/action-shellcheck@master 24 | with: 25 | github_token: ${{ secrets.github_token }} 26 | - name: hadolint 27 | uses: mgrachev/action-hadolint@v1.0.1 28 | with: 29 | github_token: ${{ secrets.github_token }} 30 | -------------------------------------------------------------------------------- /.github/workflows/stale.yml: -------------------------------------------------------------------------------- 1 | name: Mark stale issues and pull requests 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 * * *" 6 | 7 | jobs: 8 | stale: 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/stale@v4.1.0 14 | with: 15 | repo-token: ${{ secrets.GITHUB_TOKEN }} 16 | stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days' 17 | days-before-stale: 30 18 | days-before-close: 5 19 | stale-pr-message: 'This pull request is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 5 days' 20 | stale-issue-label: 'no-issue-activity' 21 | stale-pr-label: 'no-pr-activity' 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | !.travis.yml 2 | .env 3 | .travis/config.yml 4 | .vagrant 5 | .vscode/settings.json 6 | *.env 7 | *.pem 8 | **/.vscode 9 | apt_auth.conf 10 | build.tags 11 | data/* 12 | dive.log 13 | docker-compose.override.yml 14 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kopano-dev/kopano-docker/9c5e0c9c2f250c3a02423946712671069318fefe/.gitmodules -------------------------------------------------------------------------------- /.hadolint.yaml: -------------------------------------------------------------------------------- 1 | ignored: 2 | # disable following sourced files 3 | - SC1091 4 | # disable check for versioned upstream image 5 | - DL3006 6 | # disable don't use :latest 7 | - DL3007 8 | # disable explicit version for apt install 9 | - DL3008 10 | # disable explicit version for apk install 11 | - DL3018 12 | trustedRegistries: 13 | - docker.io 14 | -------------------------------------------------------------------------------- /.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "MD013": false, 3 | "MD026": false, 4 | "MD034": false 5 | } 6 | -------------------------------------------------------------------------------- /.pylintrc: -------------------------------------------------------------------------------- 1 | [MASTER] 2 | init-hook='import sys; sys.path.append("base")' 3 | disable=C0114, # missing-module-docstring 4 | -------------------------------------------------------------------------------- /.travis.yml-deactivated: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: bionic 3 | language: node_js 4 | 5 | node_js: 6 | - stable 7 | services: 8 | - docker 9 | before_install: 10 | - sudo rm /usr/local/bin/docker-compose # remove pre-installed docker-compose (too old) 11 | - bash -x .ci/setup-tools.sh 12 | - .ci/travis-buildkit.sh # upgrade docker for buildkit support 13 | install: 14 | - "./version.sh" 15 | - make lint 16 | - "./tests/test.exp" 17 | - "./version.sh" 18 | - commander test tests/commander.yaml 19 | - make lint # rerun lint to see if output is different with .env in place 20 | - echo "docker_repo=$docker_repo" >> .env 21 | - echo "DOCKERREADME=yes" >> .env # add DOCKERREADME env var so that make publish also updates readme files on docker hub 22 | - echo "KCCONF_SERVER_SURVEYCLIENT_INTERVAL=0" >> kopano_server.env 23 | - echo "KOPANO_SURVEYCLIENT_ENABLED=false" >> kopano_konnect.env 24 | - echo "KOPANO_SURVEYCLIENT_ENABLED=false" >> kopano_kwmserver.env 25 | - travis_retry make build-all 26 | script: 27 | - make test-ci 28 | - docker-compose down -v 29 | - make test-startup-meet-demo 30 | deploy: 31 | # login to docker hub 32 | - provider: script 33 | skip-cleanup: true 34 | script: echo "$docker_pwd" | docker login -u "$docker_login" --password-stdin 35 | on: 36 | branch: master 37 | # push images 38 | - provider: script 39 | skip-cleanup: true 40 | script: make publish 41 | on: 42 | branch: master 43 | #cache: # uncomment to not load/upload trivy files each time 44 | # directories: 45 | # - $HOME/.cache/trivy 46 | -------------------------------------------------------------------------------- /.trivyignore: -------------------------------------------------------------------------------- 1 | # we're not using systemd 2 | CVE-2017-1000082 3 | 4 | # tar setuid issue 5 | CVE-2005-2541 6 | 7 | # libssh2 issue not relevant since not using ssh 8 | CVE-2019-3855 -------------------------------------------------------------------------------- /.yamllint: -------------------------------------------------------------------------------- 1 | extends: default 2 | 3 | rules: 4 | # 80 chars should be enough, but don't fail if a line is longer 5 | line-length: 6 | max: 80 7 | level: warning 8 | -------------------------------------------------------------------------------- /ARCHITECTURE.md: -------------------------------------------------------------------------------- 1 | # Architecture Overview 2 | 3 | Aka "How do the containers connect/relate/interact with each other?" 4 | 5 | ## web 6 | 7 | - external entry point for users accessing Kopano 8 | - reverse proxy for containers exposing a web interface 9 | - can retrieve ssl certificate from Let's Encrypt 10 | - redirects all requests to /webapp by default 11 | - recommended to use as it makes web configuration easy and secure (manual configuration will be tedious and potentially less secure) 12 | 13 | ## ldap 14 | 15 | - (optional) bundles OpenLDAP service 16 | - kopano_server is using LDAP to manage users 17 | 18 | ## ldap-admin and password-self-service 19 | 20 | - optional containers to manage users in ldap and let users change their password 21 | 22 | ## mail 23 | 24 | - MTA stack with anti-spam and anti-virus 25 | - connects against the ldap to verify users 26 | 27 | ## db 28 | 29 | - (optional) bundles MariaDB for the Kopano database 30 | 31 | ## kopano_ssl 32 | 33 | - helper container to generate ssl certificates for internal usage 34 | - will create required files and then stop 35 | 36 | ## kopano_server 37 | 38 | - main process of the Kopano deployment 39 | - connects towards LDAP to get a list of users and verify user logins via bind 40 | 41 | ## kopano_webapp 42 | 43 | - provides Kopano WebApp, so users can interact with their mailboxes via their browser 44 | 45 | ## kopano_zpush 46 | 47 | - provides Z-Push, so users can sync their mailboxes to phones and tablets 48 | 49 | ## kopano_grapi 50 | 51 | - groupware backend of the Kopano RestAPI 52 | 53 | ## kopano_kapi 54 | 55 | - http endpoint of the Kopano RestAPI 56 | - stores recent calls for the user in a key value stores (queried over Rest) 57 | 58 | ## kopano_kdav 59 | 60 | - provides KDav, so users can sync their calendars and contacts via CalDAV and CardDAV 61 | 62 | ## kopano_dagent 63 | 64 | - mail delivery part for kopano_server 65 | - mta delivers mail to it, dagent delivers the mail into the desired inbox 66 | 67 | ## kopano_spooler 68 | 69 | - mail sending part for kopano_server 70 | - monitors outboxes of users, submits mails to the mta 71 | 72 | ## kopano_gateway 73 | 74 | - provides Pop3 and IMAP access for users 75 | 76 | ## kopano_ical 77 | 78 | - provides iCAL and CalDAV access for users (will be replaced with KDav in the future) 79 | 80 | ## kopano_monitor 81 | 82 | - monitors mailbox usage and sends quota mails (by directly delivering a mail into the users inbox) 83 | 84 | ## kopano_search 85 | 86 | - provides full text indexing for mailboxes 87 | 88 | ## kopano_konnect 89 | 90 | - authentication component (OpenID Connect) 91 | - required for apps interacting with the Kopano RestAPI (e.g. Kopano Meet) 92 | 93 | ## kopano_kwmserver 94 | 95 | - WebRTC signalling server 96 | 97 | ## kopano_meet 98 | 99 | - provides the Meet web application/frontend 100 | 101 | ## kopano_scheduler 102 | 103 | - helper container to execute scheduled tasks within Kopano 104 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, email, or any other method with the owners of this repository before making a change. 4 | 5 | ## General architecture of containers 6 | 7 | To get an impression how the containers interact/relate with each other have a look at the [architecture](ARCHITECTURE.md) description. 8 | 9 | ## Helping others help you 10 | 11 | When reporting issues or asking questions please make sure to use the appropriate templates and include information such as your current configuration and versions (see https://github.com/zokradonh/kopano-docker#troubleshooting for interesting commands for this). If you are having questions about scripts and commands please make sure to include the command you're executing and the full output of this command. 12 | 13 | ## Testing 14 | 15 | This project includes a few automated tests that can be run to ensure that containers start up and are operational. Required tools for testing can be installed by executing `bash .ci/setup-tools.sh`. 16 | 17 | The startup test can be executed by calling `make test-startup`. It spins up all containers and checks if they listen on their expected interfaces afterwards as well as execute some commands that should succeed on a successful deployment. 18 | 19 | A more detailed test can be executed by calling `make test-goss`. This uses [Goss](https://github.com/aelsabbahy/goss) and its helper [dcgoss](https://github.com/aelsabbahy/goss/tree/master/extras/dcgoss) to validate the container configuration at runtime. These tests have not been implemented for all containers yet, but as an upside the same validation is used as part of the container health check. Contributions are welcome! 20 | 21 | Testing the startup scripts of the containers is still a work in progress. When running `make test-commander` [Commander](https://github.com/SimonBaeumer/commander) will be used to test output of the `version.sh` script and some of the container startup scripts. 22 | 23 | ## Tricks 24 | 25 | To speed up testing rebuilds you can override the git hash that is passed as a build argument. 26 | 27 | Example: `make vcs_ref=invalid build-web` or `make vcs_ref=invalid build-all` 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-2018 Andre Zoledziowski 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. -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | Vagrant.configure(2) do |config| 5 | if !Vagrant.has_plugin?("vagrant-docker-compose") 6 | print " WARN: Missing plugin 'vagrant-docker-compose'.\n" 7 | print " Use 'vagrant plugin install vagrant-docker-compose' to install.\n" 8 | end 9 | 10 | config.vm.box = "hashicorp/bionic64" 11 | 12 | config.vm.provider "virtualbox" do |v| 13 | v.memory = 4096 14 | v.cpus = 2 15 | end 16 | 17 | config.vm.network "private_network", ip: "10.16.73.20" 18 | 19 | config.vm.provision :docker 20 | config.vm.provision :docker_compose 21 | 22 | config.vm.provision :shell, :path => "./.ci/setup-tools.sh" 23 | 24 | config.vm.provision "app", 25 | type: "shell", 26 | keep_color: true, 27 | privileged: false, 28 | run: "always", 29 | inline: <<-SCRIPT 30 | cd /vagrant 31 | docker-compose up --detach 32 | SCRIPT 33 | end 34 | -------------------------------------------------------------------------------- /base/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:buster 2 | 3 | ARG ADDITIONAL_KOPANO_PACKAGES="" 4 | ARG DOWNLOAD_COMMUNITY_PACKAGES=1 5 | ARG KOPANO_CORE_REPOSITORY_URL="file:/kopano/repo/core" 6 | ARG KOPANO_CORE_VERSION=newest 7 | ARG KOPANO_REPOSITORY_FLAGS="" 8 | 9 | # Both UID and GID should not be set to values above 999 10 | ARG KOPANO_UID=999 11 | ARG KOPANO_GID=999 12 | 13 | ENV \ 14 | AUTOCONFIGURE=true \ 15 | BASE_VERSION=2.2.0 \ 16 | DEBIAN_FRONTEND=noninteractive \ 17 | DEBUG="" 18 | 19 | LABEL maintainer=az@zok.xyz \ 20 | org.label-schema.name="Kopano base container" \ 21 | org.label-schema.description="Base image for containers running the Kopano groupware stack" \ 22 | org.label-schema.url="https://kopano.io" \ 23 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 24 | org.label-schema.version=$BASE_VERSION \ 25 | org.label-schema.schema-version="1.0" 26 | 27 | SHELL ["/bin/bash", "-o", "pipefail", "-c"] 28 | 29 | RUN mkdir -p /kopano/repo /kopano/data /kopano/helper /kopano/path 30 | WORKDIR /kopano/repo 31 | 32 | # install basics 33 | RUN apt-get update && \ 34 | apt-get install --no-install-recommends -y \ 35 | apt-transport-https \ 36 | apt-utils \ 37 | ca-certificates \ 38 | curl \ 39 | dumb-init \ 40 | gpg \ 41 | gpg-agent \ 42 | jq \ 43 | locales \ 44 | moreutils \ 45 | python3-minimal \ 46 | && \ 47 | rm -rf /var/cache/apt /var/lib/apt/lists/* 48 | 49 | # Create kopano user and group 50 | RUN groupadd --system --gid ${KOPANO_GID} kopano 51 | RUN useradd --system --shell /usr/sbin/nologin --home /var/lib/kopano --gid ${KOPANO_GID} --uid ${KOPANO_UID} kopano 52 | 53 | ENV DOCKERIZE_VERSION v0.11.6 54 | RUN curl -sfL https://github.com/powerman/dockerize/releases/download/"$DOCKERIZE_VERSION"/dockerize-"$(uname -s)"-"$(uname -m)" \ 55 | | install /dev/stdin /usr/local/bin/dockerize && \ 56 | dockerize --version 57 | 58 | ENV GOSS_VERSION v0.3.11 59 | RUN curl -L https://github.com/aelsabbahy/goss/releases/download/$GOSS_VERSION/goss-linux-amd64 -o /usr/local/bin/goss && \ 60 | chmod +rx /usr/local/bin/goss && \ 61 | goss --version 62 | 63 | # if additional locales are required this should be adjusted here 64 | RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ 65 | sed -i -e 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/' /etc/locale.gen && \ 66 | sed -i -e 's/# nl_NL.UTF-8 UTF-8/nl_NL.UTF-8 UTF-8/' /etc/locale.gen && \ 67 | dpkg-reconfigure --frontend=noninteractive locales && \ 68 | update-locale LANG=en_US.UTF-8 69 | 70 | # get common utilities 71 | COPY create-kopano-repo.sh /kopano/helper/ 72 | COPY kcconf.py Release.key defaultconfigs/ /kopano/ 73 | RUN apt-key add /kopano/Release.key 74 | 75 | SHELL [ "/bin/bash", "-c"] 76 | 77 | ONBUILD ARG DOWNLOAD_COMMUNITY_PACKAGES=1 78 | ONBUILD ARG DOWNLOAD_DISTRIBUTION="Debian_10" 79 | ONBUILD ARG DOWNLOAD_CHANNEL="community" 80 | ONBUILD ARG DOWNLOAD_BRANCH="" 81 | ONBUILD WORKDIR /kopano/repo 82 | ONBUILD RUN \ 83 | # community download and package as apt source repository 84 | . /kopano/helper/create-kopano-repo.sh && \ 85 | if [ ${DOWNLOAD_COMMUNITY_PACKAGES} -eq 1 ]; then \ 86 | dl_and_package_community "core" "$DOWNLOAD_DISTRIBUTION" "$DOWNLOAD_CHANNEL" "$DOWNLOAD_BRANCH"; \ 87 | dl_and_package_community "kapps" "$DOWNLOAD_DISTRIBUTION" "$DOWNLOAD_CHANNEL" "$DOWNLOAD_BRANCH"; \ 88 | fi 89 | 90 | ARG VCS_REF 91 | LABEL org.label-schema.vcs-ref=$VCS_REF -------------------------------------------------------------------------------- /base/README.md: -------------------------------------------------------------------------------- 1 | # Kopano base image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_base.svg)](https://microbadger.com/images/zokradonh/kopano_base "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_base.svg)](https://microbadger.com/images/zokradonh/kopano_base "Microbadger version") 4 | 5 | Common base for Kopano images. Predefines arguments and prepares fetching of Kopano packages and building of a local repository (when using nightly downloads). 6 | -------------------------------------------------------------------------------- /base/Release.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | 3 | mQINBFcjak8BEACl/9+3+hgGmkIgn/G8dzfo4BY8gRtLdQkFPw/dhvZWGznvFkdY 4 | GbSdIbcFNp8uMKva8P75rIq5XSYAU8o21gjoGuVSi55MB/JNnR22whpXHnx3Os2i 5 | pkoFZEWqGoW/7CWAk6QVOpVK+0UXEaXTkuEKVsB+hRL9wRQNpcWN8M894/I5egGB 6 | b1gPD9OFMTlHEVjLYFLUwGeMCSpcTU4kHu93g7S/s2xVng31xlZ2FqUgUT2GWTrR 7 | YfPuNib0srIZXwsqmVMJdu4qx3FoIJeAd3KH11fbb2oZEmwGKYfULoATGQ6s9/nG 8 | wVR2aJPPgZJv2YIpoE4CqKixj8ll6yc6DWzp2dOOj/4JJvpdpeO3Vu3dMy+8qBsR 9 | VlsCRKAFJLkmnliaUxtGM3oH3URb8LSnLXWPrvDB3sEq4o5mRxooqcwzi5FQ8bvG 10 | jzoqdw4NWIuH24Y7cC80X7o28qmN+DxySkeOtMQ9hVxYhK+bab3kw9Q9KCIT70r6 11 | YsCPX2+5RSBDpWI4bmP/3xMD2EUsdZBZYx79Qccai9+Syhw+GgIC/Yj9tdK8++5D 12 | XJWxTZLhYBAfoI3RsOmx38Yg9Z8fFF2l43jgveFORrv0EMcWBrJTtvLEXBPdCjBi 13 | AYBhAsuku/Kc6/zXrbWOYnmtxiYqjiqsyOXFdXat9Vw163rup2UoGjw8sQARAQAB 14 | tCpLb3Bhbm8gRGV2ZWxvcG1lbnQgPGRldmVsb3BtZW50QGtvcGFuby5pbz6JAlYE 15 | EwEKAEACGwMHCwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgBYhBN83ibzrIZneCNdD 16 | pVyyfhNY4vKnBQJginN3BQkLSDyoAAoJEFyyfhNY4vKn3r0P/jgOS9vhQKR9a633 17 | D/Ydmbc9vGNb8802SCbVdH5IhHWeVzthrJ2tHwtYoCknpfAu+K1F2OZ0upFcTvxn 18 | qJbGnvd9UGq37o7boWic2RdLywOm5iru3YqFZXAfvtIMpGsfk7rc+ZH5SnQiRxrJ 19 | WO8b3dM8tW+rpvUKaG7UBc613Uqki8L98cUdhZrnvEl3AaaU7OjZmdu4X6+sayWG 20 | /bvlWcvtmJF3rNtDtZCtxf4iBgWxTKa8RkVV4XErhWtqn3vigxIspErCX0t6JY+v 21 | RCWSjBU1abeysVmW9+p4g+hxRxwQ+u2FNrsKdjMeh0nWa1517NSKuGDMT52JoPpI 22 | nukY0UxjvJ+0NuzM+J+0NpzG1as5eL0VU88v3bOmVyzvK9Bcrqrxxy3o5bmGVUUv 23 | P+7uo0Mmt5RO48Pv2bc+NN7RTO5lG8MqyHSBjqoRRRJnv7YIuH4Rao8GuvoVWlAW 24 | I2y31ed29TSsUtYbBODgtyPgydrpaj+REUj97LDXt4J1a7vvsm79GN3QQUjFP9NK 25 | Rc+uSjkUj5HR4cgonn7ABVfTSRHQ/Y5x/DbZIY8D8aGXewErfUYLk0ekN4yoOyth 26 | i4V5nx1BhQ+vSigqkL18ZBy+esf4nLu78PpXp2+H3C3+oV1/ahyFdjFD6BqkcR7d 27 | /MmZlaWM9tKS84biyRFUuwb+y55auQINBFcjak8BEADNzyS331yQ24nQFMRb5TzT 28 | ZBp/NnPtXrrdLDS5UdhwZMVMWJrQuweyl2NUlePq9J8/FarGktJnKALYzvSyAbyf 29 | v9M9Nlm8pbFJPJUkEkt93zEGFmJGAhpSnBEOXIziugtD9lZnIQ1YN861PsojGYuC 30 | J2Pl/HMi4mQEB9zcJ9SzqxjCS2DVD0S1hIjMrxrW3kTO8roSledHV59AkK0M6WxO 31 | IunN6Wg29ys7VwYnqg1hXCrFP2jtqQHeD9zOmW9LnZ/UDTNfipXJVqfb04+OQLUa 32 | LbD2HdzCLQcoIjwmOr3NZkbbXW0Luklzu6PRimLJ4mucz1ksAfFJqJAhF/0TjJiD 33 | ZRn/7rwpR+m4bba8MIMmiRf6e+WlpVgKTYL26BwuCSpyHjIxutoXTBGZ2fT1by5R 34 | /6Sl2cgQXGKJnNHWCla3sHVFvQmVMBenFFMjGel9l2bvl6I6Nyu5kxtD0rDynHMl 35 | 9OI2OklGzOLSlhioQnWabtoyu9glmEU+ofyNBe0BJmFJxH9jqvOwW2aMHW4NEMR1 36 | pP7LNgLbgQ6Q1Q1WehK70TiCuH4d0WVVQ+dl/OrQSWWmqo8EDy590UJTk2uLH5mr 37 | eamO0aVuw7GkwAoXoMowzGJjHP+bBWrDudfiLwZBpIHg2Ogct5ZxKpgr9Tx0hwix 38 | qfTj4eO0m76j070/hvgRnQARAQABiQIlBBgBAgAPBQJXI2pPAhsMBQkJZgGAAAoJ 39 | EFyyfhNY4vKnRC8P/jy75oYazCRhOjuNI7fPr2a546bjx4TCNMZPy3qnWg9qMwBx 40 | 8zNsx9cAg3dK4aQLN4vacPRZypVt4gKoGT2yalyVq+mE3roSAykjW+56efO6JGIP 41 | /y7HyQb3F5tzbMJb55M1D0zeQJJLvCut2U0M9T8s9zii2N0MybUWgSEx/IHmTxO9 42 | MEZoRBPjJkfRBnhpJ9jSiPthEutk2E+xMtti82RqWn5antUxdvZ+AXrn9VXxM1kU 43 | VZy0OJZL4tPf4w3S+yGYjOte7BEhDus+8PA+srfdroSSA+891fGDojo2nFzC4a4M 44 | vIPqutxy6Mu+WksRVA4w3E8WINuwEEpmsU/sWvSmJjaNu7EuZmTiF/gPapo8r6b1 45 | XX3vtPE6UETsvnGn2IKjsAzHcdx5KYpGpXT75g46yRqvwk4b0wsVDA2/rXCTp4N9 46 | yvINmZ0IcDqBG1RYwRdKjSN4TX+vPtu4ciDZTvTcgf7A2u/M/bc5MxZscjex6pno 47 | /vS6N8yV71sGaKpQJOJNNU4NvdgnajWMJ9IVchwGWJFGuY89oSzW+D9MZcYKhJKg 48 | U7N7JgDYUknY1xJpwT+XFjWBGbBjQAEQPQPcGerTCjRG9ijCsrytl2uRMGbFXueL 49 | YmCVCErITLjX9gvcxPH38wxMkO6MQnrvNSV8dBGwhY2E0nJfBT/amTwXoNjm 50 | =TAfQ 51 | -----END PGP PUBLIC KEY BLOCK----- 52 | -------------------------------------------------------------------------------- /base/create-kopano-repo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | [ "$DEBUG" ] && set -x 5 | 6 | function urldecode { : "${*//+/ }"; echo -e "${_//%/\\x}"; } 7 | 8 | function version_from_filename { 9 | basename "$1" | awk -F"-" '{print $2}' 10 | } 11 | 12 | function h5ai_query { 13 | component=${1:-core} 14 | distribution=${2:-Debian_10} 15 | channel=${3:-community} # could either be community, supported or limited 16 | branch=${4:-""} # could either be empty, "master/tarballs/", "pre-final/tarballs/" or "final/tarballs/" 17 | 18 | filename=$(curl -s -XPOST "https://download.kopano.io/$channel/?action=get&items\[href\]=/$channel/$component:/$branch&items\[what\]=1" | \ 19 | jq -r '.items[].href' | \ 20 | grep "$distribution-all\|$distribution-amd64" | sed "s#/$channel/$component:/##" | sed "s#/$channel/$component%3A/##") 21 | 22 | if [ -z "${filename// }" ]; then 23 | echo "unknown component" 24 | exit 1 25 | fi 26 | 27 | filename=$(urldecode "$filename") 28 | echo "$filename" 29 | } 30 | 31 | function dl_and_package_community { 32 | # take component as first argument and fallback to core if none given 33 | component=${1:-core} 34 | distribution=${2:-Debian_10} 35 | channel=${3:-community} 36 | branch=${4:-""} 37 | 38 | if [ -d "$component" ]; then 39 | echo "Packages have been downloaded in a previous stage. Skipping..." 40 | return 41 | fi 42 | 43 | # query community server by h5ai API 44 | filename=$(h5ai_query "$component" "$distribution" "$channel" "$branch") 45 | filename2=$(basename "$filename") 46 | 47 | # download & extract packages 48 | curl -s -S -L -o "$filename2" https://download.kopano.io/"$channel"/"$component":/"${filename}" 49 | tar xf "$filename2" 50 | 51 | # save buildversion 52 | #currentVersion=$(version_from_filename "$filename") 53 | #echo "$component-$currentVersion" >> /kopano/buildversion 54 | 55 | # save disk space 56 | rm "$filename2" 57 | 58 | mv "${filename2%.tar.gz}" "$component" 59 | 60 | # prepare directory to be apt source 61 | cd "$component" 62 | apt-ftparchive packages . | gzip -9c > Packages.gz 63 | cd ".." 64 | } 65 | -------------------------------------------------------------------------------- /base/defaultconfigs/cfg-from-env.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import kcconf 3 | 4 | # Override configs from environment variables 5 | kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/")) 6 | -------------------------------------------------------------------------------- /base/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | 5 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | DEBUG=true 7 | WORK_DIR=$(mktemp -d) 8 | component=${1:-core} 9 | 10 | function cleanup { 11 | rm -rf "$WORK_DIR" 12 | echo "Deleted temp working directory $WORK_DIR" 13 | } 14 | 15 | trap cleanup EXIT 16 | 17 | cd "$WORK_DIR" 18 | # shellcheck source=base/create-kopano-repo.sh 19 | . "$DIR"/create-kopano-repo.sh 20 | dl_and_package_community "$component" 21 | -------------------------------------------------------------------------------- /build/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM koalaman/shellcheck-alpine:v0.7.1 as shellcheck 2 | FROM docker:19.03 3 | ENV \ 4 | COMMANDER_VERSION=2.1.0 \ 5 | COMPOSE_VERSION=1.19.0 \ 6 | GOSS_VERSION=0.3.11 \ 7 | HADOLINT_VERSION=1.17.6 \ 8 | REG_VERSION=0.16.1 \ 9 | TRIVY_VERSION=0.1.1 10 | 11 | LABEL maintainer=az@zok.xyz \ 12 | org.label-schema.name="Kopano Container Builder" \ 13 | org.label-schema.description="Helper Container to help building and testing containers" \ 14 | org.label-schema.url="https://kopano.io" \ 15 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker/build/" \ 16 | org.label-schema.version=1.0.0 \ 17 | org.label-schema.schema-version="1.0" 18 | 19 | RUN apk add --no-cache bash curl coreutils git grep expect make nano npm jq py-pip 20 | #RUN apk add --no-cache shellcheck --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community 21 | COPY --from=shellcheck /bin/shellcheck /bin/shellcheck 22 | 23 | RUN curl -fSL "https://github.com/genuinetools/reg/releases/download/v$REG_VERSION/reg-linux-amd64" -o "/usr/local/bin/reg" && \ 24 | curl -fSL "https://github.com/hadolint/hadolint/releases/download/v$HADOLINT_VERSION/hadolint-$(uname -s)-$(uname -m)" -o /usr/local/bin/hadolint && \ 25 | curl -fSL "https://github.com/docker/compose/releases/download/$COMPOSE_VERSION/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \ 26 | curl -fSL "https://github.com/aelsabbahy/goss/releases/download/v$GOSS_VERSION/goss-linux-amd64" -o /usr/local/bin/goss && \ 27 | curl -L "https://raw.githubusercontent.com/fbartels/goss/dcgoss-v2/extras/dcgoss/dcgoss" -o /usr/local/bin/dcgoss && \ 28 | curl -fSL "https://github.com/SimonBaeumer/commander/releases/download/v$COMMANDER_VERSION/commander-linux-amd64" -o /usr/local/bin/commander && \ 29 | curl -fSL "https://raw.githubusercontent.com/fbartels/dccommander/master/dccommander" -o /usr/local/bin/dccommander && \ 30 | pip install --no-cache-dir yamllint==1.19.0 && \ 31 | npm config set unsafe-perm true && \ 32 | npm install -g eclint@2.8.1 && \ 33 | chmod a+x /usr/local/bin/* 34 | 35 | WORKDIR /kopano-docker 36 | CMD ["bash"] 37 | -------------------------------------------------------------------------------- /build/README.md: -------------------------------------------------------------------------------- 1 | # Minimal build environment 2 | 3 | Helper container for systems where build requirements (bash, curl, docker-compose, jq, make) are not available (for example on Synology) 4 | 5 | Run the following command to enter the "build environment" (command may need to be run with `sudo` to work with the `docker` command): 6 | 7 | ```bash 8 | $ ./run.sh 9 | This script may need to be run as root to be able to use docker/docker-compose through it. 10 | bash-4.4$ 11 | ``` 12 | 13 | (the first time it will take a moment before the bash prompt is displayed, since the container is built locally first) 14 | 15 | Afterwards you can execute the `setup.sh` script, modify `.env` to your liking and run any make commands: 16 | 17 | ```bash 18 | bash-4.4# ./setup.sh 19 | Creating an .env file for you 20 | Which tag do you want to use for Kopano Core components? [latest]: 21 | Which tag do you want to use for Kopano WebApp? [latest]: 22 | Which tag do you want to use for Z-Push? [latest]: 23 | Name of the Organisation for LDAP [Kopano Demo]: 24 | FQDN to be used (for reverse proxy) [kopano.demo]: 25 | Email address to use for Lets Encrypt. Use 'self_signed' as your email to create self signed certificates [self_signed]: 26 | Name of the BASE DN for LDAP [dc=kopano,dc=demo]: 27 | LDAP server to be used (defaults to the bundled OpenLDAP) [ldap://ldap:389]: 28 | Timezone to be used [Europe/Berlin.]: 29 | E-Mail Address displayed for the 'postmaster' [postmaster@kopano.demo]: 30 | Name/Address of Database server (defaults to the bundled one) [db]: 31 | Available options: 32 | 1 ) de-at 33 | 2 ) de-ch 34 | 3 ) de-de 35 | 4 ) en 36 | 5 ) en-gb 37 | 6 ) es 38 | 7 ) fr 39 | 8 ) it 40 | 9 ) nl 41 | 10 ) pl-pl 42 | Check language spell support (again to uncheck, ENTER when done): 43 | Available options: 44 | 1 ) contactfax 45 | 2 ) desktopnotifications 46 | 3 ) filepreviewer 47 | 4 ) files 48 | 5 ) filesbackend-smb 49 | 6 ) filesbackend-owncloud 50 | 7 ) folderwidgets 51 | 8 ) gmaps 52 | 9 ) intranet 53 | 10 ) mattermost 54 | 11 ) mdm 55 | 12 ) pimfolder 56 | 13 ) quickitems 57 | 14 ) smime 58 | 15 ) titlecounter 59 | 16 ) webappmanual 60 | 17 ) zdeveloper 61 | Check for additional plugins (again to uncheck, ENTER when done): 62 | Integrate WhatsApp into DeskApp yes/no [no]: 63 | 64 | bash-4.4# make build-all 65 | docker build -t zokradonh/kopano_ssl ssl/ 66 | Sending build context to Docker daemon 4.608kB 67 | [...] 68 | ``` 69 | 70 | This container also includes ´docker-compose´ for systems that can not be easily updated (again Synology). You can freely choose to use ´docker-compose up -d´ from inside or outside of this container. 71 | -------------------------------------------------------------------------------- /build/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ ! "$(id -u)" -eq 0 ]; then 3 | echo "This script may need to be run as root to be able to use docker/docker-compose through it." 4 | fi 5 | 6 | cd "$(dirname "$0")" || exit 7 | 8 | docker pull zokradonh/kopano_build:latest || true 9 | docker build --cache-from zokradonh/kopano_build:latest . 10 | 11 | docker run \ 12 | --rm -it \ 13 | -u "$(id -u)":"$(id -g)" \ 14 | -v /var/run/docker.sock:/var/run/docker.sock \ 15 | -v "$(pwd)"/..:/kopano-docker/ \ 16 | "$(docker build --cache-from zokradonh/kopano_build:latest -q .)" "$@" 17 | -------------------------------------------------------------------------------- /core/Dockerfile.dagent: -------------------------------------------------------------------------------- 1 | ARG docker_repo=zokradonh 2 | FROM ${docker_repo}/kopano_core 3 | 4 | ENV \ 5 | EXE=/usr/sbin/kopano-dagent \ 6 | SERVICE_TO_START=dagent -------------------------------------------------------------------------------- /core/README.md: -------------------------------------------------------------------------------- 1 | # Kopano Core image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_core.svg)](https://microbadger.com/images/zokradonh/kopano_core "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_core.svg)](https://microbadger.com/images/zokradonh/kopano_core "Microbadger version") 4 | 5 | Image for components out of the "Kopano Core" repository. Is used to start containers for e.g. `kopano-server` and `kopano-gateway`. 6 | 7 | E-Mail attachment directory is by default in `/kopano/data/attachments/` it is recommended to bind `/kopano/data` as volume. 8 | 9 | Attachment location can be configured by setting the environment variable `KCCONF_SERVER_ATTACHMENT_PATH`. 10 | 11 | All configuration can be adjusted dynamically through environment variables. 12 | 13 | ```bash 14 | KCCONF_SERVER_MYSQL_HOST=127.0.0.1 15 | ^ ^ ^ ^ 16 | | | | | 17 | General prefix | 18 | | | | 19 | Name of the relevant configuration file (server.cfg in this case) 20 | | | 21 | Name of the configuration option in the configuration file 22 | | 23 | Value of the configuration option 24 | ``` 25 | 26 | Examples: 27 | 28 | - specify `KCCONF_SERVER_MYSQL_HOST` for `mysql_host` setting in `server.cfg` 29 | - specify `KCCONF_LDAP_LDAP_SEARCH_BASE` to set `ldap_search_base` in `ldap.cfg` 30 | 31 | Additionally it is possible to comment specific options in/out with `KCCOMMENT_filenameWithoutExtension_anystring=searchline` 32 | e.g. `KCCOMMENT_LDAP_1=!include /usr/share/kopano/ldap.openldap.cfg` 33 | 34 | For core dumps on crashes kopano-server requires the `fs.suid_dumpable sysctl` to contain the value 2, not 0. 35 | 36 | It is recommended to sync the user list before the first login of a user. With the bundled ´docker-compose.yml´ the ´kopano_scheduler´ container will take care of this. Alternatively `kopano-admin --sync` could be run once after initial install in the kopano_server container. 37 | 38 | Example: 39 | 40 | `docker-compose exec kopano_server kopano-admin -l` 41 | 42 | Depending on the overall performance of the system and the amount of user the first execution of this command will take a moment before it produces any output. This is since this command kicks off the mailbox creation for the users. 43 | 44 | See https://documentation.kopano.io/kopanocore_administrator_manual/configure_kc_components.html#testing-ldap-configuration for more information. 45 | 46 | ## Ports & Proxying 47 | 48 | - kopano-server is configured to listen on the ports 236 (plain) and 237 (https) 49 | - kopano-ical is configured to listen on the port 8080, but the web container is also configured to proxy access to http(s)://FQDN/caldav to kopano-ical 50 | - kopano-gateway is configured to listen on IMAP traffic on port 143. Pop3 is deactivated by default but would be listening on port 110. Pop3s and IMAPs are currently not configured. (see https://github.com/zokradonh/kopano-docker/issues/16 for more details). 51 | -------------------------------------------------------------------------------- /core/bin/kopano-autorespond: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | /usr/sbin/kopano-autorespond -C "$KOPANO_CONFIG_PATH/autorespond.cfg" "$@" 4 | -------------------------------------------------------------------------------- /core/bin/kopano-cli: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ ! -f /usr/sbin/kopano-cli ]; then 4 | echo "kopano-cli has been removed from Kopano Groupware Core 10 and upwards. Please use kopano-admin instead." 5 | exit 1 6 | fi 7 | 8 | /usr/sbin/kopano-cli --config "$KOPANO_CONFIG_PATH/admin.cfg" "$@" 9 | -------------------------------------------------------------------------------- /core/bin/show-folders.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 4 | 5 | 6 | try: 7 | import kopano 8 | except ImportError: 9 | import zarafa as kopano 10 | from MAPI.Util import * 11 | import binascii 12 | 13 | def opt_args(): 14 | parser = kopano.parser('skpcf') 15 | parser.add_option("--user", dest="user", action="store", help="Username") 16 | parser.add_option("--public", dest="public", action="store_true", help="Show public folders") 17 | parser.add_option("--delete", dest="delete", action="store", help="Delete folder based on entryid") 18 | parser.add_option("--extend", dest="extend", action="store_true", help="show more values") 19 | 20 | return parser.parse_args() 21 | def printprop(typename, item): 22 | if typename == 'PT_MV_BINARY': 23 | listItem = [] 24 | for i in item: 25 | listItem.append(str(binascii.hexlify(i)).upper()) 26 | return listItem 27 | if typename == 'PT_OBJECT': 28 | return None 29 | if typename == 'PT_BINARY': 30 | return str(binascii.hexlify(item)).upper() 31 | if typename == 'PT_UNICODE': 32 | try: 33 | return item.encode('utf-8').decode() 34 | except: 35 | return item 36 | else: 37 | return item 38 | 39 | def printmapiprops(folder): 40 | props = [] 41 | for prop in folder.props(): 42 | if hex(prop.proptag) == "0x10130102L": 43 | props.append([prop.id_, prop.idname, hex(prop.proptag), prop.typename, printprop(prop.typename, prop.value), prop.value]) 44 | else: 45 | props.append([prop.id_, prop.idname, hex(prop.proptag), prop.typename, printprop(prop.typename, prop.value)]) 46 | 47 | return props 48 | def main(): 49 | options, args = opt_args() 50 | 51 | if not options.user and not options.public: 52 | print('Please use\n' \ 53 | '%s --user or\n' \ 54 | '%s --public' % (sys.argv[0], sys.argv[0])) 55 | sys.exit(1) 56 | if options.user: 57 | user = kopano.server(options).user(options.user) 58 | store = user.store 59 | name = user.name 60 | if options.public: 61 | name = 'Public' 62 | store = kopano.server(options).public_store 63 | if not options.delete: 64 | print('Store:', name.encode('utf-8').decode()) 65 | print('{:50} {:50} {:50}'.format('Folder name', 'Parent folder', 'Entryid')) 66 | 67 | for folder in store.root.folders(): 68 | print('{:50} {:50} {:50}'.format(folder.name.encode('utf8').decode(), folder.parent.name.encode('utf8').decode(), folder.entryid)) 69 | if options.extend: 70 | props = printmapiprops(folder) 71 | f = open('%s-%s.prop' % (folder.name, folder.entryid), 'w') 72 | for prop in props: 73 | f.write('{0:5} {1:37} {2:8} {3:10} {4:1}\n'.format(prop[0], prop[1], prop[2], prop[3], prop[4])) 74 | f.close() 75 | 76 | else: 77 | print('Not in yet') 78 | 79 | 80 | 81 | 82 | if __name__ == "__main__": 83 | main() 84 | -------------------------------------------------------------------------------- /core/commander/grapi/commander.yaml: -------------------------------------------------------------------------------- 1 | tests: 2 | start-service script: 3 | command: bash -c "shopt -s expand_aliases; alias exec='echo'; . /kopano/start-service.sh && env" 4 | exit-code: 0 5 | stdout: 6 | contains: 7 | - enable_experimental_endpoints=true 8 | config: 9 | env: 10 | KCCONF_GRAPI_ENABLE_EXPERIMENTAL_ENDPOINTS: true 11 | config: 12 | env: 13 | DEBUG: ${DEBUG} 14 | GRAPI_BACKEND: ${GRAPI_BACKEND} 15 | LANG: ${LANG} 16 | SERVICE_TO_START: ${SERVICE_TO_START} 17 | PATH: ${PATH} 18 | -------------------------------------------------------------------------------- /core/commander/spooler/commander.yaml: -------------------------------------------------------------------------------- 1 | tests: 2 | test sending mail: 3 | command: apt update && apt install -y swaks netbase && dockerize -wait tcp://"$KCCONF_SPOOLER_SMTP_SERVER":25 -timeout 1080s && swaks --to user1@kopano.demo --server $KCCONF_SPOOLER_SMTP_SERVER 4 | exit-code: 0 5 | stdout: 6 | contains: 7 | - "250 2.0.0 Ok: queued as" 8 | 9 | config: 10 | env: 11 | PATH: ${PATH} 12 | KCCONF_SPOOLER_SMTP_SERVER: ${KCCONF_SPOOLER_SMTP_SERVER} 13 | -------------------------------------------------------------------------------- /core/defaultconfigs/dagent.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import kcconf 3 | 4 | # Component specific configurations 5 | kcconf.configkopano({ 6 | r"/tmp/kopano/dagent.cfg": 7 | { 8 | # Certain configuration can be pre-defined at startup: 9 | #'lmtp_listen': "0.0.0.0:2003", 10 | } 11 | }) 12 | 13 | # Override configs from environment variables 14 | kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/")) 15 | -------------------------------------------------------------------------------- /core/defaultconfigs/gateway.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import kcconf 3 | 4 | # Component specific configurations 5 | kcconf.configkopano({ 6 | r"/tmp/kopano/gateway.cfg": 7 | { 8 | # Certain configuration can be pre-defined at startup: 9 | #'imap_listen': "0.0.0.0:143", 10 | } 11 | }) 12 | 13 | # Override configs from environment variables 14 | kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/")) 15 | -------------------------------------------------------------------------------- /core/defaultconfigs/grapi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import kcconf 3 | 4 | # Override configs from environment variables 5 | kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/")) 6 | -------------------------------------------------------------------------------- /core/defaultconfigs/ical.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import kcconf 3 | 4 | # Component specific configurations 5 | kcconf.configkopano({ 6 | r"/tmp/kopano/ical.cfg": 7 | { 8 | # Certain configuration can be pre-defined at startup: 9 | #'ical_listen': "0.0.0.0:8080", 10 | } 11 | }) 12 | 13 | # Override configs from environment variables 14 | kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/")) 15 | -------------------------------------------------------------------------------- /core/defaultconfigs/kapi.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import kcconf 3 | 4 | # Component specific configurations 5 | kcconf.configkopano({ 6 | r"/tmp/kopano/kapid.cfg": 7 | { 8 | # Certain configuration can be pre-defined at startup: 9 | #'listen': "0.0.0.0:8039", 10 | } 11 | }) 12 | 13 | # Override configs from environment variables 14 | kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/")) 15 | -------------------------------------------------------------------------------- /core/defaultconfigs/monitor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import kcconf 3 | 4 | # Component specific configurations 5 | kcconf.configkopano({ 6 | r"/tmp/kopano/monitor.cfg": 7 | { 8 | # Certain configuration can be pre-defined at startup: 9 | #'log_level': "4" 10 | } 11 | }) 12 | 13 | # Override configs from environment variables 14 | kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/")) 15 | -------------------------------------------------------------------------------- /core/defaultconfigs/search.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import kcconf 3 | 4 | # Component specific configurations 5 | kcconf.configkopano({ 6 | r"/tmp/kopano/search.cfg": 7 | { 8 | # Certain configuration can be pre-defined at startup: 9 | #'index_path': "/kopano/data/search/" 10 | } 11 | }) 12 | 13 | # Override configs from environment variables 14 | kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/")) 15 | -------------------------------------------------------------------------------- /core/defaultconfigs/server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import kcconf 3 | 4 | # Component specific configurations 5 | kcconf.configkopano({ 6 | r"/tmp/kopano/server.cfg": 7 | { 8 | # Certain configuration can be pre-defined at startup: 9 | #'server_listen': "0.0.0.0:236", 10 | } 11 | }) 12 | 13 | # Override configs from environment variables 14 | kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/")) 15 | -------------------------------------------------------------------------------- /core/defaultconfigs/spamd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import os 3 | import kcconf 4 | 5 | # Component specific configurations 6 | kcconf.configkopano({ 7 | r"/tmp/kopano/spamd.cfg": 8 | { 9 | # Certain configuration can be pre-defined at startup: 10 | #'log_level': "3" 11 | } 12 | }) 13 | 14 | # Override configs from environment variables 15 | kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/")) -------------------------------------------------------------------------------- /core/defaultconfigs/spooler.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import kcconf 3 | 4 | # Component specific configurations 5 | kcconf.configkopano({ 6 | r"/tmp/kopano/spooler.cfg": 7 | { 8 | # Certain configuration can be pre-defined at startup: 9 | #'log_level': "4", 10 | } 11 | }) 12 | 13 | # Override configs from environment variables 14 | kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/")) 15 | -------------------------------------------------------------------------------- /core/goss/dagent/goss.yaml: -------------------------------------------------------------------------------- 1 | port: 2 | tcp:2003: 3 | listening: true 4 | process: 5 | kopano-dagent: 6 | running: true 7 | -------------------------------------------------------------------------------- /core/goss/dagent/goss_wait.yaml: -------------------------------------------------------------------------------- 1 | port: 2 | tcp:2003: 3 | listening: true 4 | process: 5 | kopano-dagent: 6 | running: true 7 | -------------------------------------------------------------------------------- /core/goss/gateway/goss.yaml: -------------------------------------------------------------------------------- 1 | process: 2 | kopano-gateway: 3 | running: true 4 | -------------------------------------------------------------------------------- /core/goss/gateway/goss_wait.yaml: -------------------------------------------------------------------------------- 1 | process: 2 | kopano-gateway: 3 | running: true 4 | -------------------------------------------------------------------------------- /core/goss/grapi/goss.yaml: -------------------------------------------------------------------------------- 1 | file: 2 | /var/lib/kopano-grapi: 3 | exists: true 4 | mode: "0755" 5 | size: 4096 6 | owner: kapi 7 | group: kopano 8 | filetype: directory 9 | /var/run/kopano/grapi: 10 | exists: true 11 | mode: "0755" 12 | owner: kapi 13 | group: kopano 14 | filetype: directory 15 | mount: 16 | /var/lib/kopano-grapi: 17 | exists: true 18 | opts: 19 | - rw 20 | - relatime 21 | -------------------------------------------------------------------------------- /core/goss/grapi/goss_wait.yaml: -------------------------------------------------------------------------------- 1 | file: 2 | /var/run/kopano/grapi: 3 | exists: true 4 | mode: "0755" 5 | owner: kapi 6 | group: kopano 7 | filetype: directory 8 | -------------------------------------------------------------------------------- /core/goss/ical/goss.yaml: -------------------------------------------------------------------------------- 1 | process: 2 | kopano-ical: 3 | running: true 4 | -------------------------------------------------------------------------------- /core/goss/ical/goss_wait.yaml: -------------------------------------------------------------------------------- 1 | process: 2 | kopano-ical: 3 | running: true 4 | -------------------------------------------------------------------------------- /core/goss/kapi/goss.yaml: -------------------------------------------------------------------------------- 1 | process: 2 | kapid: 3 | running: true 4 | -------------------------------------------------------------------------------- /core/goss/kapi/goss_wait.yaml: -------------------------------------------------------------------------------- 1 | process: 2 | kapid: 3 | running: true 4 | -------------------------------------------------------------------------------- /core/goss/monitor/goss.yaml: -------------------------------------------------------------------------------- 1 | process: 2 | kopano-monitor: 3 | running: true 4 | -------------------------------------------------------------------------------- /core/goss/monitor/goss_wait.yaml: -------------------------------------------------------------------------------- 1 | process: 2 | kopano-monitor: 3 | running: true 4 | -------------------------------------------------------------------------------- /core/goss/search/goss.yaml: -------------------------------------------------------------------------------- 1 | file: 2 | /var/run/kopano/search.sock: 3 | exists: true 4 | mode: "0700" 5 | size: 0 6 | owner: kopano 7 | group: kopano 8 | filetype: socket 9 | contains: [] 10 | -------------------------------------------------------------------------------- /core/goss/search/goss_wait.yaml: -------------------------------------------------------------------------------- 1 | file: 2 | /var/run/kopano/search.sock: 3 | exists: true 4 | mode: "0700" 5 | size: 0 6 | owner: kopano 7 | group: kopano 8 | filetype: socket 9 | contains: [] 10 | -------------------------------------------------------------------------------- /core/goss/server/goss.yaml: -------------------------------------------------------------------------------- 1 | file: 2 | # TODO how to make path dynamic? 3 | /kopano/data/attachments/: 4 | exists: true 5 | mode: "0755" 6 | owner: kopano 7 | group: kopano 8 | filetype: directory 9 | /run/kopano/prio.sock: 10 | exists: true 11 | mode: "0660" 12 | owner: kopano 13 | group: kopano 14 | filetype: socket 15 | /run/kopano/server.sock: 16 | exists: true 17 | mode: "0666" 18 | owner: kopano 19 | group: kopano 20 | filetype: socket 21 | process: 22 | kopano-server: 23 | running: true 24 | http: 25 | # TODO what if plain http is deactivated? (or uses a different port?) 26 | http://localhost:236: 27 | status: 405 28 | timeout: 5000 29 | # TODO what if ssl is deactivated? (or uses a different port?) 30 | https://localhost:237: 31 | status: 405 32 | allow-insecure: true 33 | timeout: 5000 34 | -------------------------------------------------------------------------------- /core/goss/server/goss_wait.yaml: -------------------------------------------------------------------------------- 1 | http: 2 | http://localhost:236: 3 | status: 405 4 | timeout: 5000 5 | -------------------------------------------------------------------------------- /core/goss/spamd/goss.yaml: -------------------------------------------------------------------------------- 1 | process: 2 | kopano-spamd: 3 | running: true -------------------------------------------------------------------------------- /core/goss/spamd/goss_wait.yaml: -------------------------------------------------------------------------------- 1 | process: 2 | kopano-spamd: 3 | running: true -------------------------------------------------------------------------------- /core/goss/spooler/goss.yaml: -------------------------------------------------------------------------------- 1 | process: 2 | kopano-spooler: 3 | running: true 4 | -------------------------------------------------------------------------------- /core/goss/spooler/goss_wait.yaml: -------------------------------------------------------------------------------- 1 | process: 2 | kopano-spooler: 3 | running: true 4 | -------------------------------------------------------------------------------- /core/healthcheck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | case "$SERVICE_TO_START" in 6 | server|dagent|gateway|ical|grapi|kapi|monitor|search|spooler) 7 | goss -g /kopano/goss/"$SERVICE_TO_START"/goss.yaml validate --format json_oneline 8 | ;; 9 | *) 10 | echo "This service still needs a proper check" 11 | ;; 12 | esac 13 | 14 | exit 0 15 | -------------------------------------------------------------------------------- /database/README.md: -------------------------------------------------------------------------------- 1 | # Database helpers 2 | 3 | ## create-multiple-databases.sh 4 | 5 | Script to create additional databases during the initial container startup. Based on https://github.com/mrts/docker-postgresql-multiple-databases. 6 | -------------------------------------------------------------------------------- /database/create-additional-databases.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | mysql=${mysql:?} 6 | 7 | function create_user_and_database() { 8 | local database=$1 9 | echo " Creating database '$database'" 10 | echo "CREATE DATABASE IF NOT EXISTS ${database};" | "${mysql[@]}" 11 | echo "GRANT ALL PRIVILEGES ON ${database}.* TO '${MYSQL_USER}';" | "${mysql[@]}" 12 | } 13 | 14 | if [ -n "$MYSQL_ADDITIONAL_DATABASES" ]; then 15 | echo "Multiple database creation requested: $MYSQL_ADDITIONAL_DATABASES" 16 | for db in $(echo "$MYSQL_ADDITIONAL_DATABASES" | tr ',' ' '); do 17 | create_user_and_database "$db" 18 | done 19 | echo "Additional databases created" 20 | fi 21 | -------------------------------------------------------------------------------- /docker-compose.db.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | db: 5 | image: mariadb:10.3.10-bionic 6 | restart: unless-stopped 7 | container_name: ${COMPOSE_PROJECT_NAME}_db 8 | volumes: 9 | - mysql:/var/lib/mysql 10 | environment: 11 | - MYSQL_DATABASE=${MYSQL_DATABASE} 12 | - MYSQL_PASSWORD=${MYSQL_PASSWORD} 13 | - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} 14 | - MYSQL_USER=${MYSQL_USER} 15 | env_file: 16 | - db.env 17 | healthcheck: 18 | test: ["CMD-SHELL", 'mysql --database=$$MYSQL_DATABASE --password=$$MYSQL_ROOT_PASSWORD --execute="SELECT count(table_name) > 0 FROM information_schema.tables;" --skip-column-names -B'] 19 | interval: 30s 20 | timeout: 10s 21 | retries: 4 22 | networks: 23 | - kopano-net 24 | 25 | kopano_server: 26 | depends_on: 27 | - db 28 | 29 | volumes: 30 | mysql: 31 | -------------------------------------------------------------------------------- /docker-compose.kwmbridge-dnat.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | kopano_kwmserver: 5 | environment: 6 | - enable_mcu_api=yes 7 | - pipeline_forced_regexp=@conference/.* 8 | #- pipeline_forced_regexp=@group/.* 9 | 10 | kopano_kwmbridge: 11 | image: ${docker_repo:-zokradonh}/kopano_kwmbridge:${KWMBRIDGE_VERSION:-latest} 12 | read_only: true 13 | restart: unless-stopped 14 | depends_on: 15 | - kopano_kwmserver 16 | environment: 17 | - INSECURE=${INSECURE} 18 | - oidc_issuer_identifier=https://${FQDN} 19 | - kwm_server_urls=http://kwmserver:8778 20 | #- kwm_server_urls=https://${FQDNCLEANED}:8443 21 | - use_nat_1to1_ips=${PUBLICIP} 22 | - use_nat_1to1_candidate_type=host 23 | - ice_udp_port_range=65435:65535 24 | volumes: 25 | - /etc/machine-id:/etc/machine-id 26 | - /etc/machine-id:/var/lib/dbus/machine-id 27 | - kopanossl:/kopano/ssl 28 | ports: 29 | - 65435:65535/udp 30 | tmpfs: 31 | - /tmp 32 | -------------------------------------------------------------------------------- /docker-compose.kwmbridge.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | web: 5 | ports: 6 | - "8443:8443" # this port should be firewalled off so that only known instances of kwmbridge can connect tot it 7 | kopano_kwmserver: 8 | environment: 9 | - enable_mcu_api=yes 10 | 11 | kopano_kwmbridge: 12 | image: ${docker_repo:-zokradonh}/kopano_kwmbridge:${KWMBRIDGE_VERSION:-latest} 13 | read_only: true 14 | restart: unless-stopped 15 | depends_on: 16 | - kopano_kwmserver 17 | environment: 18 | - INSECURE=${INSECURE} 19 | - oidc_issuer_identifier=https://${FQDN} 20 | - kwm_server_urls=https://${FQDNCLEANED}:8443 21 | env_file: 22 | - kopano_kwmbridge.env 23 | volumes: 24 | - /etc/machine-id:/etc/machine-id 25 | - /etc/machine-id:/var/lib/dbus/machine-id 26 | - kopanossl:/kopano/ssl 27 | network_mode: "host" 28 | tmpfs: 29 | - /tmp 30 | -------------------------------------------------------------------------------- /docker-compose.ldap.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | ldap: 5 | image: ${docker_repo:-zokradonh}/${LDAP_CONTAINER:-kopano_ldap_demo}:${LDAP_VERSION:-latest} 6 | restart: unless-stopped 7 | container_name: ${COMPOSE_PROJECT_NAME}_ldap 8 | ports: 9 | - ${LDAPPORT:-389}:389 10 | environment: 11 | - LDAP_ADMIN_PASSWORD=${LDAP_ADMIN_PASSWORD} 12 | - LDAP_BASE_DN=${LDAP_BASE_DN} 13 | - LDAP_DOMAIN=${LDAP_DOMAIN} 14 | - LDAP_LOG_LEVEL=0 15 | - LDAP_ORGANISATION=${LDAP_ORGANISATION} 16 | - LDAP_READONLY_USER_PASSWORD=${LDAP_READONLY_USER_PASSWORD} 17 | - LDAP_READONLY_USER=true 18 | env_file: 19 | - ldap.env 20 | command: "--copy-service" 21 | volumes: 22 | - ldap:/var/lib/ldap 23 | - slapd:/etc/ldap/slapd.d 24 | networks: 25 | - ldap-net 26 | 27 | mail: 28 | depends_on: 29 | - ldap 30 | networks: 31 | - ldap-net 32 | 33 | kopano_server: 34 | depends_on: 35 | - ldap 36 | networks: 37 | - ldap-net 38 | 39 | volumes: 40 | ldap: 41 | slapd: 42 | 43 | networks: 44 | ldap-net: 45 | driver: bridge 46 | -------------------------------------------------------------------------------- /docker-compose.mail.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | mail: 5 | image: mailserver/docker-mailserver:10 6 | restart: unless-stopped 7 | hostname: mail # hostname and domainname may need to be commented on some platforms (e.g. ChromeOS) 8 | domainname: ${LDAP_DOMAIN} 9 | container_name: ${COMPOSE_PROJECT_NAME}_mail 10 | ports: 11 | - "${SMTPPORT:-25}:25" 12 | - "${SMTPSPORT:-465}:465" 13 | - "${MSAPORT:-587}:587" 14 | volumes: 15 | - maildata:/var/mail 16 | - mailstate:/var/mail-state 17 | - maillogs:/var/log/mail 18 | - mtaconfig:/tmp/docker-mailserver/ 19 | environment: 20 | - DMS_DEBUG=0 21 | - ENABLE_CLAMAV=1 22 | - ENABLE_FAIL2BAN=1 23 | - ENABLE_LDAP=1 24 | - ENABLE_POSTFIX_VIRTUAL_TRANSPORT=1 25 | - ENABLE_POSTGREY=1 26 | - ENABLE_SASLAUTHD=1 27 | - ENABLE_SPAMASSASSIN=1 28 | - LDAP_BIND_DN=${LDAP_BIND_DN} 29 | - LDAP_BIND_PW=${LDAP_BIND_PW} 30 | - LDAP_QUERY_FILTER_ALIAS=${LDAP_QUERY_FILTER_ALIAS} 31 | - LDAP_QUERY_FILTER_DOMAIN=${LDAP_QUERY_FILTER_DOMAIN} 32 | - LDAP_QUERY_FILTER_GROUP=${LDAP_QUERY_FILTER_GROUP} 33 | - LDAP_QUERY_FILTER_USER=${LDAP_QUERY_FILTER_USER} 34 | - LDAP_SEARCH_BASE=${LDAP_SEARCH_BASE} 35 | - LDAP_SERVER_HOST=${LDAP_SERVER} 36 | - ONE_DIR=1 37 | - PERMIT_DOCKER=connected-networks 38 | - POSTFIX_DAGENT=lmtp:kopano_dagent:2003 39 | - PFLOGSUMM_TRIGGER=logrotate 40 | - POSTMASTER_ADDRESS=${POSTMASTER_ADDRESS} 41 | - SASLAUTHD_LDAP_BIND_DN=${LDAP_BIND_DN} 42 | - SASLAUTHD_LDAP_FILTER=${SASLAUTHD_LDAP_FILTER} 43 | - SASLAUTHD_LDAP_PASSWORD=${LDAP_BIND_PW} 44 | - SASLAUTHD_LDAP_SEARCH_BASE=${LDAP_SEARCH_BASE} 45 | - SASLAUTHD_LDAP_SERVER=${LDAP_HOST} 46 | - SASLAUTHD_MECHANISMS=rimap 47 | - SASLAUTHD_MECH_OPTIONS=kopano_gateway 48 | - SMTP_ONLY=1 49 | - SPAMASSASSIN_SPAM_TO_INBOX=1 50 | - SSL_TYPE=self-signed 51 | - TZ=${TZ} 52 | env_file: 53 | - mail.env 54 | networks: 55 | - kopano-net 56 | # dns: 1.1.1.1 # using Google DNS can lead to lookup errors uncomment this option and 57 | # set to the ip of a trusted dns service (Cloudflare is given as an example). 58 | # See https://github.com/zokradonh/kopano-docker/issues/52 for more information. 59 | cap_add: 60 | - NET_ADMIN 61 | - SYS_PTRACE 62 | 63 | kopano_spooler: 64 | depends_on: 65 | - mail 66 | 67 | volumes: 68 | maildata: 69 | mailstate: 70 | maillogs: 71 | mtaconfig: 72 | -------------------------------------------------------------------------------- /docker-compose.ports.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | web: 5 | ports: 6 | - "${CADDY:-2015}:2015" 7 | - "${HTTP:-80}:80" 8 | - "${HTTPS:-443}:443" 9 | 10 | kopano_server: 11 | ports: 12 | - ${KOPANOPORT:-236}:236 13 | - ${KOPANOSPORT:-237}:237 14 | 15 | kopano_gateway: 16 | ports: 17 | - "${POP3PORT:-110}:110" 18 | - "${IMAPPORT:-143}:143" 19 | 20 | kopano_ical: 21 | ports: 22 | - "${ICALPORT:-8080}:8080" 23 | -------------------------------------------------------------------------------- /examples/apache-proxy.md: -------------------------------------------------------------------------------- 1 | # Using Apache as the front facing reverse proxy 2 | 3 | Example provided by [ronnybremer](https://github.com/ronnybremer) in [Add reverse proxy example for Apache](https://github.com/zokradonh/kopano-docker/issues/372). 4 | 5 | To be able to use a different proxy, than the bundled kweb the env variable `FQDNCLEANED` needs to be unset (to not route traffic through it, but the external proxy). Additionally `EMAIL` needs to be set to `off`. 6 | 7 | ```bash 8 | 9 | ServerName public.domain.com:443 10 | ServerAdmin your_friendly_admin@domain.com 11 | UseCanonicalName On 12 | 13 | ErrorLog logs/meet_ssl_error_log 14 | CustomLog logs/meet_ssl_access_log combined 15 | LogLevel warn 16 | 17 | SSLEngine on 18 | SSLCompression off 19 | SSLProxyEngine off 20 | 21 | SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 22 | SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA 23 | # for higher security 24 | # SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH 25 | SSLHonorCipherOrder on 26 | SSLCertificateFile /etc/pki/tls/certs/localhost.crt 27 | SSLCertificateKeyFile /etc/pki/tls/private/localhost.key 28 | SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt 29 | 30 | Header unset X-Frame-Options 31 | Header unset Content-Security-Policy 32 | 33 | RewriteEngine On 34 | # Meet and PWAs only work on https 35 | RewriteCond %{HTTPS} off 36 | RewriteCond %{REQUEST_URI} ^/meet$ [OR] 37 | RewriteCond %{REQUEST_URI} ^/meet/ 38 | RewriteRule ^(.*)$ https://public.domain.com/meet/ [R,L] 39 | # We need to access Meet through the proper domain 40 | RewriteCond %{REQUEST_URI} ^/meet$ [OR] 41 | RewriteCond %{REQUEST_URI} ^/meet/ 42 | RewriteCond %{HTTP_HOST} !^public.domain.com$ [NC] 43 | RewriteRule ^(.*)$ https://public.domain.com/meet/ [R,L] 44 | # Upgrade Websocket connections 45 | RewriteCond %{HTTP:Connection} Upgrade [NC] 46 | RewriteCond %{HTTP:Upgrade} websocket [NC] 47 | RewriteRule /api/kwm/v2/(.*) ws://internal.domain.com:2015/api/kwm/v2/$1 [P,L] 48 | 49 | 50 | Order deny,allow 51 | Deny from all 52 | 53 | 54 | 55 | ProxyPass http://internal.domain.com:2015/ 56 | ProxyPassReverse http://internal.domain.com:2015/ 57 | ProxyPreserveHost On 58 | 59 | 60 | 61 | ``` 62 | -------------------------------------------------------------------------------- /examples/core.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | ldap: 5 | image: ${docker_repo:-zokradonh}/kopano_ldap_demo 6 | container_name: ldap 7 | ports: 8 | - ${LDAPPORT:-389}:389 9 | environment: 10 | - LDAP_ORGANISATION=${LDAP_ORGANISATION} 11 | - LDAP_DOMAIN=${LDAP_DOMAIN} 12 | - LDAP_BASE_DN=${LDAP_BASE_DN} 13 | - LDAP_ADMIN_PASSWORD=${LDAP_ADMIN_PASSWORD} 14 | - LDAP_READONLY_USER=true 15 | - LDAP_READONLY_USER_PASSWORD=${LDAP_READONLY_USER_PASSWORD} 16 | command: "--loglevel info --copy-service" 17 | volumes: 18 | - ldap:/var/lib/ldap 19 | - slapd:/etc/ldap/slapd.d 20 | networks: 21 | - ldap-net 22 | 23 | db: 24 | image: mariadb:10.3.10-bionic 25 | restart: always 26 | container_name: kopano_db 27 | volumes: 28 | - mysql/:/var/lib/mysql 29 | environment: 30 | - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} 31 | - MYSQL_USER=${MYSQL_USER} 32 | - MYSQL_PASSWORD=${MYSQL_PASSWORD} 33 | - MYSQL_DATABASE=${MYSQL_DATABASE} 34 | healthcheck: 35 | test: ["CMD-SHELL", 'mysql --database=$$MYSQL_DATABASE --password=$$MYSQL_ROOT_PASSWORD --execute="SELECT count(table_name) > 0 FROM information_schema.tables;" --skip-column-names -B'] 36 | interval: 30s 37 | timeout: 10s 38 | retries: 4 39 | networks: 40 | - kopano-net 41 | 42 | kopano_ssl: 43 | image: ${docker_repo:-zokradonh}/kopano_ssl 44 | container_name: kopano_ssl 45 | environment: 46 | - FQDN=${FQDN} 47 | - PKI_COUNTRY=NL 48 | volumes: 49 | - /etc/kopano/ssl/:/kopano/ssl 50 | 51 | kopano_server: 52 | image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest} 53 | hostname: kopano_server 54 | container_name: kopano_server 55 | depends_on: 56 | - db 57 | - ldap 58 | - kopano_ssl 59 | ports: 60 | - ${KOPANOPORT:-236}:236 61 | - ${KOPANOSPORT:-237}:237 62 | environment: 63 | - SERVICE_TO_START=server 64 | - TZ=${TZ} 65 | - KCCONF_SERVER_COREDUMP_ENABLED=no 66 | - KCCONF_SERVER_LOG_LEVEL=3 67 | - KCCONF_SERVER_MYSQL_HOST=${MYSQL_HOST} 68 | - KCCONF_SERVER_MYSQL_PORT=3306 69 | - KCCONF_SERVER_MYSQL_DATABASE=${MYSQL_DATABASE} 70 | - KCCONF_SERVER_MYSQL_USER=${MYSQL_USER} 71 | - KCCONF_SERVER_MYSQL_PASSWORD=${MYSQL_PASSWORD} 72 | - KCCONF_SERVER_SERVER_SSL_KEY_FILE=/kopano/ssl/kopano_server.pem 73 | - KCCONF_SERVER_SERVER_SSL_CA_FILE=/kopano/ssl/ca.pem 74 | - KCCONF_SERVER_SERVER_NAME=Kopano 75 | - KCCONF_SERVER_SSLKEYS_PATH=/kopano/ssl/clients 76 | - KCCONF_SERVER_PROXY_HEADER=* # delete line if webapp is not behind reverse proxy 77 | - KCCONF_SERVER_SYSTEM_EMAIL_ADDRESS=${POSTMASTER_ADDRESS} 78 | - KCCONF_SERVER_SYNC_GAB_REALTIME=no 79 | - KCCONF_LDAP_LDAP_URI=${LDAP_SERVER} 80 | - KCCONF_LDAP_LDAP_BIND_USER=${LDAP_BIND_DN} 81 | - KCCONF_LDAP_LDAP_BIND_PASSWD=${LDAP_BIND_PW} 82 | - KCCONF_LDAP_LDAP_SEARCH_BASE=${LDAP_SEARCH_BASE} 83 | - KCUNCOMMENT_LDAP_1=${KCUNCOMMENT_LDAP_1} 84 | - KCCOMMENT_LDAP_1=${KCCOMMENT_LDAP_1} 85 | - ADDITIONAL_KOPANO_PACKAGES=${ADDITIONAL_KOPANO_PACKAGES} 86 | networks: 87 | - kopano-net 88 | - ldap-net 89 | - web-net 90 | volumes: 91 | - kopanodata/:/kopano/data 92 | - /etc/kopano/ssl/:/kopano/ssl 93 | - /run/kopano/:/run/kopano 94 | 95 | volumes: 96 | ldap: 97 | slapd: 98 | mysql: 99 | kopanodata: 100 | 101 | networks: 102 | web-net: 103 | kopano-net: 104 | driver: bridge 105 | ldap-net: 106 | name: ldap-net 107 | driver: bridge 108 | -------------------------------------------------------------------------------- /examples/docker-compose.override.yml-disable-mail: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | # disable services 5 | mail: 6 | image: hello-world 7 | restart: "no" 8 | -------------------------------------------------------------------------------- /examples/docker-compose.override.yml-minio: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | # example file to store attachments in s3 (provided by minio) 3 | # rename to docker-compose.override.yml and place it along the existing file to use it 4 | # (and change accesskey an secretkey below) 5 | 6 | services: 7 | kopano_server: 8 | depends_on: 9 | - minio 10 | environment: 11 | - KCCONF_SERVER_ATTACHMENT_STORAGE=s3 12 | - KCCONF_SERVER_LOG_LEVEL=6 13 | - KCCONF_SERVER_ATTACHMENT_S3_HOSTNAME=minio:9000 14 | - KCCONF_SERVER_ATTACHMENT_S3_PROTOCOL=http 15 | - KCCONF_SERVER_ATTACHMENT_S3_URISTYLE=path 16 | - KCCONF_SERVER_ATTACHMENT_S3_REGION=us-east-1 17 | - KCCONF_SERVER_ATTACHMENT_S3_ACCESSKEYID=ACCESSKEY 18 | - KCCONF_SERVER_ATTACHMENT_S3_SECRETACCESSKEY=SECRETKEY 19 | - KCCONF_SERVER_ATTACHMENT_S3_BUCKETNAME=kopano 20 | - KCCONF_SERVER_ATTACHMENT_PATH=attachments 21 | 22 | minio: 23 | image: minio/minio 24 | ports: 25 | - '9000:9000' 26 | volumes: 27 | - miniodata:/export 28 | - minioconfig:/root/.minio 29 | environment: 30 | - MINIO_ACCESS_KEY=ACCESSKEY 31 | - MINIO_SECRET_KEY=SECRETKEY 32 | command: server /data 33 | entrypoint: sh 34 | command: -c 'mkdir -p /export/kopano && /usr/bin/minio server /export' 35 | networks: 36 | - kopano-net 37 | 38 | volumes: 39 | miniodata: 40 | minioconfig: 41 | -------------------------------------------------------------------------------- /examples/docker-compose.override.yml-watchtower: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | watchtower: 5 | image: v2tec/watchtower 6 | volumes: 7 | - /var/run/docker.sock:/var/run/docker.sock 8 | -------------------------------------------------------------------------------- /examples/kopano-multiserver/README.md: -------------------------------------------------------------------------------- 1 | # Configuration example for running Kopano in a Multiserver setup 2 | 3 | This example shows how a Kopano Multiserver/Distributed setup can be achieved. The design is by no means perfect (a real deployment could make use of zero user/cachine nodes to handle front facing components), but its functional. Users will be able to login to Kopano WebApp as well as Meet and see users of other nodes and will be able to mail/call with them. 4 | 5 | **Hint:** The configuration as it is requires that you clean out existing Kopano containers and data volumes, as the additional database is only created on the initial start of the database container. 6 | 7 | 1. Add the `kopano-multiserver.yml` to the `COMPOSE_FILE` variable in your `.env` file. 8 | 9 | Example: 10 | 11 | ```bash 12 | COMPOSE_FILE=docker-compose.yml:docker-compose.ports.yml:examples/kopano-multiserver/kopano-multiserver.yml 13 | ``` 14 | 15 | 2. run `docker-compose up -d` from the root of this project. -------------------------------------------------------------------------------- /examples/kopano-multiserver/kopano-multiserver.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | db: 5 | volumes: 6 | - ./database/create-additional-databases.sh:/docker-entrypoint-initdb.d/create-additional-databases.sh 7 | environment: 8 | - MYSQL_ADDITIONAL_DATABASES=${MYSQL_DATABASE}2 9 | 10 | kopano_server: 11 | environment: 12 | - KCCONF_ADMIN_SSLKEY_FILE=/kopano/ssl/admin.pem 13 | - KCCONF_SERVER_ENABLE_DISTRIBUTED_KOPANO=true 14 | - KCCONF_SERVER_SERVER_NAME=kopano_server 15 | 16 | kopano_server_2: 17 | image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest} 18 | hostname: kopano_server_2 19 | container_name: ${COMPOSE_PROJECT_NAME}_server_2 20 | depends_on: 21 | - db 22 | - kopano_konnect 23 | - kopano_ssl 24 | - ldap 25 | environment: 26 | - ADDITIONAL_KOPANO_PACKAGES=${ADDITIONAL_KOPANO_PACKAGES} 27 | - KCCOMMENT_LDAP_1=${KCCOMMENT_LDAP_1} 28 | - KCCONF_ADMIN_SSLKEY_FILE=/kopano/ssl/admin.pem 29 | - KCCONF_LDAP_LDAP_BIND_PASSWD=${LDAP_BIND_PW} 30 | - KCCONF_LDAP_LDAP_BIND_USER=${LDAP_BIND_DN} 31 | - KCCONF_LDAP_LDAP_SEARCH_BASE=${LDAP_SEARCH_BASE} 32 | - KCCONF_LDAP_LDAP_URI=${LDAP_SERVER} 33 | - KCCONF_SERVER_COREDUMP_ENABLED=no 34 | - KCCONF_SERVER_ENABLE_DISTRIBUTED_KOPANO=true 35 | - KCCONF_SERVER_ENABLE_SSO=yes 36 | - KCCONF_SERVER_KCOIDC_INSECURE_SKIP_VERIFY=${INSECURE} 37 | - KCCONF_SERVER_KCOIDC_ISSUER_IDENTIFIER=https://${FQDN} 38 | - KCCONF_SERVER_MYSQL_DATABASE=${MYSQL_DATABASE}2 39 | - KCCONF_SERVER_MYSQL_HOST=${MYSQL_HOST} 40 | - KCCONF_SERVER_MYSQL_PASSWORD=${MYSQL_PASSWORD} 41 | - KCCONF_SERVER_MYSQL_PORT=3306 42 | - KCCONF_SERVER_MYSQL_USER=${MYSQL_USER} 43 | - KCCONF_SERVER_PROXY_HEADER=* # delete line if webapp is not behind reverse proxy 44 | - KCCONF_SERVER_SERVER_NAME=kopano_server_2 45 | - KCCONF_SERVER_SERVER_SSL_CA_FILE=/kopano/ssl/ca.pem 46 | - KCCONF_SERVER_SERVER_SSL_KEY_FILE=/kopano/ssl/kopano_server_2.pem 47 | - KCCONF_SERVER_SSLKEYS_PATH=/kopano/ssl/clients 48 | - KCCONF_SERVER_SYSTEM_EMAIL_ADDRESS=${POSTMASTER_ADDRESS} 49 | - KCUNCOMMENT_LDAP_1=${KCUNCOMMENT_LDAP_1} 50 | - SERVICE_TO_START=server 51 | - TZ=${TZ} 52 | env_file: 53 | - kopano_server.env 54 | networks: 55 | - kopano-net 56 | - ldap-net 57 | - web-net 58 | volumes: 59 | - /etc/machine-id:/etc/machine-id 60 | - /etc/machine-id:/var/lib/dbus/machine-id 61 | - kopanodata2/:/kopano/data 62 | - kopanosocket2/:/run/kopano 63 | - kopanossl/:/kopano/ssl 64 | 65 | kopano_spooler_2: 66 | image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest} 67 | restart: unless-stopped 68 | hostname: spooler_2 69 | container_name: ${COMPOSE_PROJECT_NAME}_spooler_2 70 | domainname: ${LDAP_DOMAIN} 71 | depends_on: 72 | - kopano_server_2 73 | - mail 74 | volumes: 75 | - kopanosocket2/:/run/kopano 76 | - kopanossl/:/kopano/ssl 77 | environment: 78 | - KCCONF_SPOOLER_LOG_LEVEL=3 79 | - KCCONF_SPOOLER_SMTP_SERVER=mail 80 | - KCCONF_SPOOLER_SSLKEY_FILE=/kopano/ssl/kopano_spooler.pem 81 | - SERVICE_TO_START=spooler 82 | - TZ=${TZ} 83 | env_file: 84 | - kopano_spooler.env 85 | networks: 86 | - kopano-net 87 | 88 | kopano_scheduler: 89 | depends_on: 90 | - kopano_server_2 91 | environment: 92 | - CRON_KOPANOUSERS2=10 * * * * docker exec kopano_server_2 kopano-admin --sync 93 | 94 | volumes: 95 | kopanodata2: 96 | kopanosocket2: 97 | -------------------------------------------------------------------------------- /examples/meet/README.md: -------------------------------------------------------------------------------- 1 | # Running Kopano Meet without Kopano (with only the LDAP backend) 2 | 3 | The docker-compose.yml file in this directory can be used as a template to run Kopano Meet against a LDAP user directory. The file as it is starts a demo deployment of Meet including some pre created users to explore Kopano Meet. 4 | 5 | Check https://github.com/zokradonh/kopano-docker/blob/master/ldap_demo/README.md to learn more about the included demo users. 6 | 7 | ## Instructions 8 | 9 | 1. run `setup.sh` 10 | 2. check `.env` for any required customization (port 443 already in use?) 11 | 3. run `docker-compose up` to start 12 | 4. navigate to https://your-domain to login to Kopano Meet 13 | 14 | ## Additional environment variables for using ActiveDirectory 15 | 16 | Create the a file named `docker-compose.override.yml` with the following content in case you are using Microsoft ActiveDirectory. 17 | 18 | ```yaml 19 | version: "3.5" 20 | 21 | services: 22 | 23 | kopano_grapi: 24 | environment: 25 | - LDAP_FILTER=(&(objectClass=organizationalPerson)(!(UserAccountControl:1.2.840.113556.1.4.803:=2))) 26 | - LDAP_LOGIN_ATTRIBUTE=sAMAccountName 27 | - LDAP_EMAIL_ATTRIBUTE=mail 28 | - LDAP_NAME_ATTRIBUTE=displayName 29 | - LDAP_FAMILY_NAME_ATTRIBUTE=sn 30 | - LDAP_GIVEN_NAME_ATTRIBUTE=givenName 31 | - LDAP_JOB_TITLE_ATTRIBUTE=title 32 | - LDAP_OFFICE_LOCATION_ATTRIBUTE=L 33 | - LDAP_BUSINESS_PHONE_ATTRIBUTE=telephoneNumber 34 | - LDAP_MOBILE_PHONE_ATTRIBUTE=mobile 35 | - USERID_SEARCH_FILTER_TEMPLATE=({loginAttribute}=%(userid)s) 36 | - SEARCH_SEARCH_FILTER_TEMPLATE=(&(objectClass=organizationalPerson)(!(UserAccountControl:1.2.840.113556.1.4.803:=2))(|({emailAttribute}=*%(search)s*)({givenNameAttribute}=*%(search)s*)({familyNameAttribute}=*%(search)s*))) 37 | 38 | 39 | kopano_konnect: 40 | environment: 41 | - LDAP_LOGIN_ATTRIBUTE=sAMAccountName 42 | - LDAP_NAME_ATTRIBUTE=displayName 43 | - LDAP_UUID_ATTRIBUTE_TYPE=binary 44 | - LDAP_UUID_ATTRIBUTE=objectGUID 45 | ``` 46 | -------------------------------------------------------------------------------- /examples/meet/architecture.md: -------------------------------------------------------------------------------- 1 | # Architecture Overview 2 | 3 | ## web 4 | 5 | - external entry point for users accessing Kopano Meet 6 | - reverse proxy for kopano_kapi, kopano_konnect, kopano_kwmserver and kopano_meet 7 | - can retrieve ssl certificate from Lets Encrypt 8 | - redirects all requests to /meet 9 | - recommended to use as it makes web configuration easy and secure (manual configuration will be tendious and potentially less secure) 10 | 11 | ## ldap 12 | 13 | - (optional) bundles OpenLDAP service 14 | - Konnect and Grapi are using it 15 | 16 | ## kopano_ssl 17 | 18 | - helper container to generate ssl certificates for internal usage 19 | - will create required files and then stop 20 | 21 | ## kopano_grapi 22 | 23 | - groupware backend of the Kopano RestAPI 24 | - connects to LDAP to provide a global addressbook to users 25 | 26 | ## kopano_kapi 27 | 28 | - http endpoint of the Kopano RestAPI 29 | - stores recent calls for the user in a key value stores (queried over Rest) 30 | 31 | ## kopano_konnect 32 | 33 | - authentification component (OpenID Connect) for Meet 34 | - connects to the LDAP backend to verify user logins via bind 35 | 36 | ## kopano_kwmserver 37 | 38 | - WebRTC signalling server 39 | 40 | ## kopano_meet 41 | 42 | - provides the Meet web application/frontend -------------------------------------------------------------------------------- /examples/meet/docker-compose-sfu.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | kopano_kwmserver: 5 | environment: 6 | - enable_mcu_api=yes 7 | - pipeline_forced_regexp=@conference/.* 8 | #- pipeline_forced_regexp=@group/.* 9 | 10 | kopano_kwmbridge: 11 | image: ${docker_repo:-zokradonh}/kopano_kwmbridge:${KWMBRIDGE_VERSION:-latest} 12 | read_only: true 13 | restart: unless-stopped 14 | depends_on: 15 | - kopano_kwmserver 16 | environment: 17 | - INSECURE=${INSECURE} 18 | - oidc_issuer_identifier=https://${FQDN} 19 | - kwm_server_urls=https://${FQDN} 20 | volumes: 21 | - /etc/machine-id:/etc/machine-id 22 | - /etc/machine-id:/var/lib/dbus/machine-id 23 | - kopanossl/:/kopano/ssl 24 | network_mode: "host" 25 | tmpfs: 26 | - /tmp 27 | -------------------------------------------------------------------------------- /examples/meet/env-example: -------------------------------------------------------------------------------- 1 | # please consult https://github.com/kopano-dev/kopano-docker 2 | # for possible configuration values and their impact 3 | 4 | # Access to the Kopano Turn service can be requested at https://portal.kopano.com/content/turn-server-access-request 5 | TURN_USER= 6 | TURN_PASSWORD= 7 | 8 | # Defines how Kopano can be accessed from the outside world 9 | FQDN=kopano.demo 10 | FQDNCLEANED=kopano.demo 11 | DEFAULTREDIRECT=/meet 12 | EMAIL=self_signed 13 | CADDY=2015 14 | HTTP=80 15 | HTTPS=443 16 | 17 | TZ=Europe/Berlin 18 | 19 | LDAP_CONTAINER=kopano_ldap_demo 20 | LDAP_ORGANISATION="Kopano Demo" 21 | LDAP_DOMAIN=kopano.demo 22 | LDAP_BASE_DN=dc=kopano,dc=demo 23 | LDAP_SERVER=ldap://ldap:389 24 | LDAP_ADMIN_PASSWORD=adminpassword 25 | LDAP_READONLY_USER_PASSWORD=readonlypassword 26 | LDAP_BIND_DN=cn=readonly,dc=kopano,dc=demo 27 | LDAP_BIND_PW=readonlypassword 28 | LDAP_SEARCH_BASE=dc=kopano,dc=demo 29 | 30 | # Settings for test environments 31 | INSECURE=yes 32 | 33 | # Docker and docker-compose settings 34 | # Docker Repository to push to/pull from 35 | docker_repo=kopano 36 | COMPOSE_PROJECT_NAME=kopano 37 | 38 | # Additional packages to install 39 | ADDITIONAL_KOPANO_PACKAGES=python3-grapi.backend.ldap 40 | 41 | -------------------------------------------------------------------------------- /examples/meet/tests/startup-test/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG docker_repo=zokradonh 2 | FROM ${docker_repo}/kopano_scheduler 3 | 4 | COPY test.sh /start.sh 5 | 6 | CMD ["/start.sh"] 7 | -------------------------------------------------------------------------------- /examples/meet/tests/startup-test/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | # waits for key events in various containers 6 | # e.g. kopano_server:236 signals successful start of kopano-server process 7 | dockerize \ 8 | -wait http://kopano_konnect:8777/.well-known/openid-configuration \ 9 | -wait tcp://kopano_kapi:8039 \ 10 | -wait tcp://kopano_kwmserver:8778 \ 11 | -wait tcp://kopano_meet:9080 \ 12 | -wait tcp://web:2015 \ 13 | -timeout 30s 14 | -------------------------------------------------------------------------------- /examples/meet/tests/test-container.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | test: 5 | build: 6 | context: tests/startup-test 7 | args: 8 | docker_repo: ${docker_repo:-zokradonh} 9 | networks: 10 | - kopano-net 11 | - ldap-net 12 | - web-net 13 | volumes: 14 | - /var/run/docker.sock:/var/run/docker.sock:ro 15 | - kopanodata/:/kopano/data 16 | - kopanosocket/:/run/kopano 17 | - kopanossl/:/kopano/ssl 18 | environment: 19 | - KCCONF_SERVER_MYSQL_HOST=${MYSQL_HOST} 20 | ldap: 21 | tmpfs: 22 | - /var/lib/ldap 23 | - /etc/ldap/slapd.d 24 | -------------------------------------------------------------------------------- /examples/traefik-proxy-subdomain.md: -------------------------------------------------------------------------------- 1 | # Situation and motivation: 2 | 3 | * running the kopano stack behind an ssl-terminating proxy 4 | * as less as possible maintenance effort --> run the kopano stack as close as possible at the default configuration 5 | * using the kopano-stack to provide a central ldap authentication for the domain, but running the frontend using a subdomain 6 | 7 | ## Way to go: 8 | 9 | 1. initial clean **setup of kopano stack** --> follow the documentation of https://github.com/zokradonh/kopano-docker/blob/master/README.md 10 | 1. clone the repo https://github.com/zokradonh/kopano-docker 11 | 2. run the setup.sh (only steps, necessary for the configuration is shown here) 12 | 1. Name of the Organisation for LDAP `mydomain.com` 13 | 2. FQDN to be used (for reverse proxy) `kopano.mydomain.com` 14 | 3. Email address to use for Lets Encrypt. `self_signed` 15 | 4. Name of the BASE DN for LDAP `dc=mydomain,dc=com` 16 | 5. E-Mail Address displayed for the 'postmaster' `postmaster@mydomain.com` 17 | 18 | 2. ensure ldap and reverse-proxy domain is split correctly in generated `.env` file: 19 | 20 | ```bash 21 | LDAP_DOMAIN=mydomain.com 22 | LDAP_BASE_DN=dc=mydomain,dc=com 23 | 24 | FQDN=kopano.mydomain.com 25 | ``` 26 | 27 | 3. ensure kwmserver is able to connect through an endpoint with valid ssl-certificate 28 | 29 | ```bash 30 | FQDNCLEANED=somethingInvalidToEnforceConnectionFromOutsideEndpoint 31 | ``` 32 | 33 | 4. ensure your traefik instance outside of the kopano-stack does allow **proxying to self-signed certificates**: 34 | 35 | ```bash 36 | command: --insecureSkipVerify=true 37 | ``` 38 | 39 | 5. disable the docker-host portmapping of the kopano-caddy proxy in `docker-compose.yml` to not interference with your traefik proxy 40 | 41 | ```yaml 42 | services: 43 | web: 44 | ... 45 | # ports: 46 | # - "${CADDY:-2015}:2015" 47 | # - "${HTTP:-80}:80" 48 | # - "${HTTPS:-443}:443" 49 | ``` 50 | 51 | 6. make the self-signed kopano reverse-proxy available in traefik via `docker-compose.override.yml` 52 | 53 | ```yaml 54 | version: "3.5" 55 | 56 | services: 57 | web: 58 | networks: 59 | proxy-net: 60 | labels: 61 | traefik.enable: true 62 | traefik.frontend.rule: "Host:${FQDN}" 63 | traefik.port: 2015 64 | traefik.protocol: https 65 | traefik.docker.network: "proxy-net" 66 | traefik.frontend.headers.forceSTSHeader: true 67 | traefik.frontend.headers.STSSeconds: 315360000 68 | traefik.frontend.headers.STSIncludeSubdomains: true 69 | traefik.frontend.headers.STSPreload: true 70 | 71 | networks: 72 | proxy-net: 73 | external: true 74 | ldap-net: 75 | name: ldap-net 76 | ``` 77 | 78 | Everything else should be configurable as normal. My test-setup showed a functional active-sync connection using the mdm plugin in the webapp, as well as screensharing via kopano-meet. 79 | -------------------------------------------------------------------------------- /examples/webapp.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | web: 5 | image: ${docker_repo:-zokradonh}/kopano_web 6 | container_name: web 7 | restart: always 8 | ports: 9 | - "2015:2015" 10 | - "${HTTP}:80" 11 | - "${HTTPS}:443" 12 | environment: 13 | - EMAIL=${EMAIL} 14 | - FQDN=${FQDN} 15 | command: wrapper.sh 16 | cap_drop: 17 | - ALL 18 | cap_add: 19 | - NET_BIND_SERVICE 20 | - CHOWN 21 | - SETGID 22 | - SETUID 23 | volumes: 24 | - /etc/machine-id:/etc/machine-id 25 | - /etc/machine-id:/var/lib/dbus/machine-id 26 | - web:/.kweb 27 | networks: 28 | web-net: 29 | aliases: 30 | - ${FQDN} 31 | 32 | kopano_webapp: 33 | image: ${docker_repo:-zokradonh}/kopano_webapp:${WEBAPP_VERSION:-latest} 34 | hostname: kopano_webapp 35 | container_name: kopano_webapp 36 | volumes: 37 | - /etc/kopano/ssl:/kopano/ssl 38 | - /etc/machine-id:/etc/machine-id 39 | - /etc/machine-id:/var/lib/dbus/machine-id 40 | - /run/kopano:/run/kopano 41 | environment: 42 | - TZ=${TZ} 43 | # hostname of kopano system, leave empty for unix socket 44 | - KCCONF_SERVERHOSTNAME= 45 | # https port of kopano system 46 | - KCCONF_SERVERPORT= 47 | #- ADDITIONAL_KOPANO_WEBAPP_PLUGINS=${ADDITIONAL_KOPANO_WEBAPP_PLUGINS} 48 | - ADDITIONAL_KOPANO_WEBAPP_PLUGINS=kopano-webapp-plugin-mdm 49 | - KCCONF_WEBAPPPLUGIN_MDM_PLUGIN_MDM_USER_DEFAULT_ENABLE_MDM=true 50 | - KCCONF_WEBAPPPLUGIN_MDM_PLUGIN_MDM_SERVER=kopano_zpush:9080 51 | - KCCONF_WEBAPPPLUGIN_MDM_PLUGIN_MDM_SERVER_SSL=false 52 | networks: 53 | - web-net 54 | 55 | volumes: 56 | web: 57 | 58 | networks: 59 | web-net: 60 | -------------------------------------------------------------------------------- /grapi-explorer/README.md: -------------------------------------------------------------------------------- 1 | # Kopano Grapi Explorer 2 | 3 | The Grapi Explorer is a fork of the Microsoft Graph Explorer, which has been modified so that it can connect against a self hosted Kopano GRAPI. Similar to the Grapi Playground it can be used to inspect the flows that are required to use the Kopano RestAPI and experiment with different query types. 4 | 5 | ## How to use the Grapi Explorer? 6 | 7 | 1. Add the `grapi-explorer.yml` to the `COMPOSE_FILE` variable in your `.env` file. 8 | 9 | Example: 10 | ``` 11 | COMPOSE_FILE=docker-compose.yml:docker-compose.ports.yml:grapi-explorer/grapi-explorer.yml 12 | ``` 13 | 14 | 2. Run `docker-compose up -d` and you will find the grapi-explorer at `https://your-fqdn/grapi-explorer/`. 15 | -------------------------------------------------------------------------------- /grapi-explorer/grapi-explorer.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | kopano_grapi-explorer: 5 | image: kopano/grapi-explorer 6 | restart: unless-stopped 7 | depends_on: 8 | - kopano_kapi 9 | - kopano_konnect 10 | environment: 11 | - GRAPI_EXPLORER_ISS=https://${FQDN} 12 | - GRAPI_EXPLORER_GRAPH_URL=https://${FQDN}/api/gc 13 | networks: 14 | - kopano-net 15 | - web-net 16 | -------------------------------------------------------------------------------- /kapps/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1.0-experimental 2 | ARG docker_repo=zokradonh 3 | FROM ${docker_repo}/kopano_base:latest 4 | 5 | ARG ADDITIONAL_KOPANO_PACKAGES="" 6 | ARG DOWNLOAD_COMMUNITY_PACKAGES=1 7 | ARG KOPANO_REPOSITORY_FLAGS="trusted=yes" 8 | ARG DEBIAN_FRONTEND=noninteractive 9 | ARG KOPANO_CORE_REPOSITORY_URL="file:/kopano/repo/core" 10 | ARG KOPANO_CORE_VERSION=newest 11 | ARG KOPANO_KAPPS_REPOSITORY_URL="file:/kopano/repo/kapps" 12 | ARG KOPANO_KAPPS_VERSION=newest 13 | 14 | ENV \ 15 | ADDITIONAL_KOPANO_PACKAGES=$ADDITIONAL_KOPANO_PACKAGES \ 16 | DOWNLOAD_COMMUNITY_PACKAGES=$DOWNLOAD_COMMUNITY_PACKAGES \ 17 | KOPANO_CORE_REPOSITORY_URL=$KOPANO_CORE_REPOSITORY_URL \ 18 | KOPANO_CORE_VERSION=$KOPANO_CORE_VERSION \ 19 | KOPANO_KAPPS_VERSION=$KOPANO_KAPPS_VERSION \ 20 | KOPANO_REPOSITORY_FLAGS=$KOPANO_REPOSITORY_FLAGS 21 | 22 | LABEL maintainer=az@zok.xyz \ 23 | org.label-schema.name="Kopano apps container" \ 24 | org.label-schema.description="Container for running Kopano Apps" \ 25 | org.label-schema.url="https://kopano.io" \ 26 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 27 | org.label-schema.version=$KOPANO_KAPPS_VERSION \ 28 | org.label-schema.schema-version="1.0" 29 | 30 | SHELL ["/bin/bash", "-o", "pipefail", "-c"] 31 | 32 | RUN --mount=type=secret,id=repocred,target=/etc/apt/auth.conf.d/kopano.conf \ 33 | # apt key for this repo has already been installed in base 34 | echo "deb [${KOPANO_REPOSITORY_FLAGS}] ${KOPANO_KAPPS_REPOSITORY_URL} ./" > /etc/apt/sources.list.d/kopano.list; \ 35 | # install 36 | apt-get update && \ 37 | # TODO mime-support could be remove once its an official dependency of kopano-kwebd 38 | apt-get install --no-install-recommends -y \ 39 | mime-support \ 40 | kopano-kwebd \ 41 | kopano-calendar \ 42 | ${ADDITIONAL_KOPANO_PACKAGES} \ 43 | && \ 44 | rm -rf /var/cache/apt /var/lib/apt/lists && \ 45 | # make configuration a symlink to prevent overwriting it 46 | mkdir -p /etc/kopano/kweb/overrides.d/config/kopano/ && \ 47 | ln -s /tmp/calendar.json /etc/kopano/kweb/overrides.d/config/kopano/calendar.json 48 | 49 | COPY start-service.sh /kopano/ 50 | COPY goss.yaml /goss/ 51 | CMD [ "/kopano/start-service.sh" ] 52 | 53 | HEALTHCHECK --interval=1m --timeout=10s \ 54 | CMD goss -g /goss/goss.yaml validate 55 | 56 | ARG VCS_REF 57 | LABEL org.label-schema.vcs-ref=$VCS_REF -------------------------------------------------------------------------------- /kapps/README.md: -------------------------------------------------------------------------------- 1 | # This is for the moment only for testing purposes -------------------------------------------------------------------------------- /kapps/goss.yaml: -------------------------------------------------------------------------------- 1 | file: 2 | /tmp/calendar.json: 3 | exists: true 4 | mode: "0644" 5 | owner: root 6 | group: root 7 | filetype: file 8 | contains: [] 9 | process: 10 | kwebd: 11 | running: true 12 | http: 13 | http://localhost:9080/calendar: 14 | status: 200 15 | allow-insecure: false 16 | no-follow-redirects: false 17 | timeout: 5000 18 | body: [] 19 | -------------------------------------------------------------------------------- /kapps/start-service.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ADDITIONAL_KOPANO_PACKAGES=${ADDITIONAL_KOPANO_PACKAGES:-""} 4 | AUTOCONFIGURE=${AUTOCONFIGURE:-true} # when set to false will disable all automatic configuration actions 5 | 6 | set -eu # unset variables are errors & non-zero return values exit the whole script 7 | [ "$DEBUG" ] && set -x 8 | 9 | if [ "${AUTOCONFIGURE}" == true ]; then 10 | # copy configuration files to /tmp/kopano to prevent modification of mounted config files 11 | mkdir -p /tmp/kopano 12 | cp /etc/kopano/*.cfg /tmp/kopano 13 | 14 | echo "Applying cfg changes from env" 15 | /usr/bin/python3 /kopano/cfg-from-env.py 16 | fi 17 | 18 | meetversion=$(dpkg-query --showformat='${Version}' --show kopano-calendar-webapp) 19 | echo "Using Kopano Calendar: $meetversion" 20 | 21 | # allow helper commands given by "docker-compose run" 22 | if [ $# -gt 0 ]; then 23 | exec "$@" 24 | exit 25 | fi 26 | 27 | if [ "${AUTOCONFIGURE}" == true ]; then 28 | cp /usr/share/doc/kopano-calendar-webapp/config.json.in /tmp/calendar.json 29 | CONFIG_JSON="/tmp/calendar.json" 30 | # TODO move into extra file to make it easier to reuse 31 | echo "Updating $CONFIG_JSON" 32 | for setting in $(compgen -A variable KCCONF_CALENDAR); do 33 | setting2=${setting#KCCONF_CALENDAR_} 34 | # dots in setting2 need to be escaped to not be handled as separate entities in the json file 35 | case ${!setting} in 36 | true|TRUE|false|FALSE|[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]) 37 | jq ".\"${setting2//_/\".\"}\" = ${!setting}" $CONFIG_JSON | sponge $CONFIG_JSON 38 | ;; 39 | *) 40 | jq ".\"${setting2//_/\".\"}\" = \"${!setting}\"" $CONFIG_JSON | sponge $CONFIG_JSON 41 | ;; 42 | esac 43 | done 44 | 45 | # Populate app grid 46 | # TODO move into extra file to make it easier to reuse 47 | # Note: if all of below variables are set to "no" kpop will fall back to its default behaviour and show all known apps. 48 | 49 | # enable Kopano Konnect in the app grid 50 | if [ "${GRID_KONNECT:-yes}" = "yes" ]; then 51 | jq '.apps.enabled += ["kopano-konnect"]' $CONFIG_JSON | sponge $CONFIG_JSON 52 | fi 53 | 54 | # enable Kopano Meet in the app grid 55 | if [ "${GRID_MEET:-yes}" = "yes" ]; then 56 | jq '.apps.enabled += ["kopano-meet"]' $CONFIG_JSON | sponge $CONFIG_JSON 57 | fi 58 | 59 | # enable Kopano WebApp in the app grid 60 | if [ "${GRID_WEBAPP:-yes}" = "yes" ]; then 61 | jq '.apps.enabled += ["kopano-webapp"]' $CONFIG_JSON | sponge $CONFIG_JSON 62 | fi 63 | 64 | # enable Kopano WebApp in the app grid 65 | if [ "${GRID_CALENDAR:-yes}" = "yes" ]; then 66 | jq '.apps.enabled += ["kopano-calendar"]' $CONFIG_JSON | sponge $CONFIG_JSON 67 | fi 68 | 69 | sed s/\ *=\ */=/g /tmp/kopano/kwebd.cfg > /tmp/kweb-env 70 | # always disable tls 71 | export tls=no 72 | # shellcheck disable=SC2046 73 | export $(grep -v '^#' /tmp/kweb-env | xargs -d '\n') 74 | 75 | # services need to be aware of the machine-id 76 | dockerize \ 77 | -wait file:///etc/machine-id \ 78 | -wait file:///var/lib/dbus/machine-id 79 | fi 80 | 81 | # cleaning up env variables 82 | unset "${!KCCONF_@}" 83 | exec kopano-kwebd serve 84 | -------------------------------------------------------------------------------- /kdav/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1.0-experimental 2 | ARG docker_repo=zokradonh 3 | FROM composer:1.9 as builder 4 | 5 | RUN git clone --depth 1 https://stash.kopano.io/scm/kc/kdav.git /usr/share/kopano-kdav 6 | WORKDIR /usr/share/kopano-kdav 7 | RUN composer install 8 | 9 | FROM ${docker_repo}/kopano_php 10 | 11 | ARG ADDITIONAL_KOPANO_PACKAGES="" 12 | ARG DOWNLOAD_COMMUNITY_PACKAGES=1 13 | ARG KOPANO_REPOSITORY_FLAGS="trusted=yes" 14 | ARG DEBIAN_FRONTEND=noninteractive 15 | ARG KOPANO_CORE_REPOSITORY_URL="file:/kopano/repo/core" 16 | ARG KOPANO_CORE_VERSION=newest 17 | 18 | ENV \ 19 | ADDITIONAL_KOPANO_PACKAGES=$ADDITIONAL_KOPANO_PACKAGES \ 20 | DOWNLOAD_COMMUNITY_PACKAGES=$DOWNLOAD_COMMUNITY_PACKAGES \ 21 | KOPANO_CORE_REPOSITORY_URL=$KOPANO_CORE_REPOSITORY_URL \ 22 | KOPANO_CORE_VERSION=$KOPANO_CORE_VERSION \ 23 | KOPANO_REPOSITORY_FLAGS=$KOPANO_REPOSITORY_FLAGS 24 | 25 | LABEL maintainer=az@zok.xyz \ 26 | org.label-schema.name="Kopano kDAV container" \ 27 | org.label-schema.description="Container for running Kopano kDAV" \ 28 | org.label-schema.url="https://kopano.io" \ 29 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 30 | org.label-schema.schema-version="1.0" 31 | 32 | # install Kopano kDAV 33 | RUN --mount=type=secret,id=repocred,target=/etc/apt/auth.conf.d/kopano.conf \ 34 | set -x && \ 35 | apt-get update && apt-get install -y --no-install-recommends \ 36 | php-mbstring \ 37 | php-xml \ 38 | php-zip \ 39 | sqlite \ 40 | php-sqlite3 \ 41 | unzip \ 42 | ${ADDITIONAL_KOPANO_PACKAGES} \ 43 | && rm -rf /var/cache/apt /var/lib/apt/lists/* 44 | 45 | # ensure right permissions of folders 46 | RUN \ 47 | mkdir -p /var/lib/kopano/kdav /var/log/kdav && \ 48 | chown www-data:www-data /var/lib/kopano/kdav /var/log/kdav 49 | 50 | COPY --from=builder /usr/share/kopano-kdav /usr/share/kopano-kdav 51 | 52 | # tweaks to make the container read-only 53 | RUN \ 54 | mv /usr/share/kopano-kdav/config.php /usr/share/kopano-kdav/config.php.dist && \ 55 | ln -s /tmp/config.php /usr/share/kopano-kdav/config.php 56 | 57 | COPY kopano-kdav.conf /etc/php/7.3/fpm/pool.d/ 58 | COPY start.sh /kopano/start.sh 59 | COPY kweb.cfg /etc/kweb.cfg 60 | 61 | ENTRYPOINT ["/usr/bin/dumb-init", "--"] 62 | CMD [ "/kopano/start.sh" ] 63 | 64 | ARG VCS_REF 65 | LABEL org.label-schema.vcs-ref=$VCS_REF 66 | -------------------------------------------------------------------------------- /kdav/README.md: -------------------------------------------------------------------------------- 1 | # Kopano kDAV image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_kdav.svg)](https://microbadger.com/images/zokradonh/kopano_kdav "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_kdav.svg)](https://microbadger.com/images/zokradonh/kopano_kdav "Microbadger version") 4 | 5 | Image to run [Kopano kDAV](https://github.com/kopano-dev/kdav). 6 | 7 | kDAV can be accessed on port 80 with the url ``/kdav``. 8 | -------------------------------------------------------------------------------- /kdav/kopano-kdav.conf: -------------------------------------------------------------------------------- 1 | [kopano-kdav] 2 | ; Unix user/group of processes 3 | ; Note: The user is mandatory. If the group is not set, the default user's group 4 | ; will be used. 5 | user = www-data 6 | group = www-data 7 | 8 | ; Set permissions for unix socket, if one is used. In Linux, read/write 9 | ; permissions must be set in order to allow connections from a web server. Many 10 | ; BSD-derived systems allow connections regardless of permissions. 11 | ; Default Values: user and group are set as the running user 12 | ; mode is set to 0660 13 | listen.owner = www-data 14 | listen.group = www-data 15 | 16 | listen = /run/php/php-fpm-kopano-kdav.sock 17 | 18 | ; Pool configuration intended for up to 500 users. 19 | pm = dynamic 20 | pm.max_children = 100 21 | pm.start_servers = 10 22 | pm.min_spare_servers = 10 23 | pm.max_spare_servers = 50 24 | pm.process_idle_timeout = 60s 25 | pm.max_requests = 200 26 | pm.status_path = /status 27 | 28 | ping.path = /ping 29 | ping.response = pong 30 | 31 | security.limit_extensions = .php 32 | 33 | php_flag[display_errors] = off 34 | 35 | php_admin_value[max_execution_time] = 60 36 | php_admin_value[post_max_size] = 20M 37 | php_admin_value[upload_max_filesize] = 20M 38 | php_admin_value[memory_limit] = 64M 39 | 40 | php_admin_flag[log_errors] = on 41 | 42 | ; Redirect worker stdout and stderr into main error log. If not set, stdout and 43 | ; stderr will be redirected to /dev/null according to FastCGI specs. 44 | ; Note: on highloaded environement, this can cause some delay in the page 45 | ; process time (several ms). 46 | ; Default Value: no 47 | catch_workers_output = no 48 | 49 | ; KDAV specifics, to reduce memory usage. 50 | php_flag[output_buffering] = off 51 | 52 | ; SabreDAV is not compatible with mbstring function overloading. 53 | php_flag[mbstring.func_overload] = off -------------------------------------------------------------------------------- /kdav/kweb.cfg: -------------------------------------------------------------------------------- 1 | :9080 { 2 | log stdout 3 | errors stderr 4 | 5 | # healthcheck 6 | status 200 /status 7 | 8 | rewrite /kdav/ { 9 | to /kdav/server.php 10 | } 11 | 12 | fastcgi2 /kdav/ /run/php/php-fpm-kopano-kdav.sock php { 13 | without /kdav/ 14 | root /usr/share/kopano-kdav 15 | read_timeout 259200s 16 | } 17 | 18 | redir 302 { 19 | /.well-known/carddav /kdav/ 20 | /.well-known/caldav /kdav/ 21 | } 22 | 23 | status 403 { 24 | /kdav/config.php 25 | /kdav/lib 26 | /kdav/mapi 27 | /kdav/vendor 28 | /kdav/version.php 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /kdav/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ADDITIONAL_KOPANO_PACKAGES=${ADDITIONAL_KOPANO_PACKAGES:-""} 4 | AUTOCONFIGURE=${AUTOCONFIGURE:-true} # when set to false will disable all automatic configuration actions 5 | 6 | # define default value for serverhostname and serverport if not passed into container 7 | KCCONF_SERVERHOSTNAME=${KCCONF_SERVERHOSTNAME:-127.0.0.1} 8 | KCCONF_SERVERPORT=${KCCONF_SERVERPORT:-236} 9 | 10 | set -eu # unset variables are errors & non-zero return values exit the whole script 11 | [ "$DEBUG" ] && set -x 12 | 13 | if [ "${AUTOCONFIGURE}" == true ]; then 14 | # Hint: this is not compatible with a read-only container. 15 | # The general recommendation is to already build a container that has all required packages installed. 16 | ADDITIONAL_KOPANO_PACKAGES=$(echo "$ADDITIONAL_KOPANO_PACKAGES" | tr -d '"') 17 | if mkdir -p "/var/lib/apt/lists/" 2&> /dev/null; then 18 | [ -n "${ADDITIONAL_KOPANO_PACKAGES// }" ] && apt update 19 | [ -n "${ADDITIONAL_KOPANO_PACKAGES// }" ] && for installpkg in $ADDITIONAL_KOPANO_PACKAGES; do 20 | # shellcheck disable=SC2016 disable=SC2086 21 | if [ "$(dpkg-query -W -f='${Status}' $installpkg 2>/dev/null | grep -c 'ok installed')" -eq 0 ]; then 22 | apt --assume-yes --no-upgrade install "$installpkg" 23 | fi 24 | done 25 | else 26 | echo "Notice: Container is run read-only, skipping package installation." 27 | echo "If you want to have additional packages installed in the container either:" 28 | echo "- build your own image with the packages already included" 29 | echo "- switch the container to 'read_only: false'" 30 | fi 31 | 32 | echo "Ensure directories" 33 | mkdir -p /run/sessions 34 | 35 | CONFIG_PHP=/tmp/config.php 36 | # copy latest config template. This should be the mount point for preexisting config files. 37 | cp /usr/share/kopano-kdav/config.php.dist $CONFIG_PHP 38 | 39 | if [ "$KCCONF_SERVERHOSTNAME" == "127.0.0.1" ]; then 40 | echo "kDAV is using the default: connection" 41 | else 42 | echo "kDAV is using an ip connection" 43 | sed -e "s#define([\"']MAPI_SERVER[\"'],\s*[\"']default:[\"'])#define('MAPI_SERVER', 'https://${KCCONF_SERVERHOSTNAME}:${KCCONF_SERVERPORT}/kopano')#" \ 44 | -i $CONFIG_PHP 45 | fi 46 | 47 | # change root uri to /kdav 48 | sed -e "s#define('DAV_ROOT_URI', '/');#define('DAV_ROOT_URI', '/kdav/');#" -i $CONFIG_PHP 49 | 50 | echo "Ensure config ownership" 51 | chown -R www-data:www-data /run/sessions 52 | 53 | # services need to be aware of the machine-id 54 | #dockerize \ 55 | # -wait file:///etc/machine-id \ 56 | # -wait file:///var/lib/dbus/machine-id 57 | fi 58 | 59 | touch /var/log/kdav/kdav.log 60 | chown www-data:www-data /var/log/kdav/kdav.log 61 | tail --pid=$$ -F --lines=0 -q /var/log/kdav/kdav.log & 62 | 63 | set +u 64 | # cleaning up env variables 65 | unset "${!KCCONF_@}" 66 | echo "Starting php-fpm" 67 | php-fpm7.3 -F & 68 | exec /usr/libexec/kopano/kwebd caddy -conf /etc/kweb.cfg 69 | -------------------------------------------------------------------------------- /konnect/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG CODE_VERSION=0.34.0 2 | 3 | FROM golang:1.15-alpine3.12 as builder-sponge 4 | 5 | RUN apk add --no-cache git 6 | RUN go get -d -v github.com/go-moreutils/sponge 7 | RUN go install -v github.com/go-moreutils/sponge 8 | 9 | FROM kopano/konnectd:${CODE_VERSION} 10 | 11 | ARG CODE_VERSION 12 | 13 | ENV \ 14 | AUTOCONFIGURE=true \ 15 | CODE_VERSION="${CODE_VERSION}" \ 16 | DEBUG="" \ 17 | FQDN=localhost \ 18 | KONNECT_BACKEND="kc" \ 19 | ecparam=/etc/kopano/ecparam.pem \ 20 | eckey=/etc/kopano/meet-kwmserver.pem \ 21 | signing_private_key=/etc/kopano/konnectd-signing-private-key.pem \ 22 | encryption_secret_key=/etc/kopano/konnectd-encryption-secret.key \ 23 | identifier_registration_conf=/etc/kopano/konnectd-identifier-registration.yaml \ 24 | identifier_scopes_conf=/etc/kopano/konnectd-identifier-scopes.yaml 25 | 26 | LABEL maintainer=az@zok.xyz \ 27 | org.label-schema.name="Kopano Konnect container" \ 28 | org.label-schema.description="Container for running Kopano Konnect" \ 29 | org.label-schema.url="https://kopano.io" \ 30 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 31 | org.label-schema.version=$CODE_VERSION \ 32 | org.label-schema.schema-version="1.0" 33 | 34 | # TODO use docker multistage for pip install yq https://pythonspeed.com/articles/multi-stage-docker-python/ 35 | RUN apk add --no-cache \ 36 | jq \ 37 | openssl \ 38 | py-pip \ 39 | && pip install --no-cache-dir yq==2.7.2 40 | 41 | COPY --from=builder-sponge /go/bin/sponge /usr/local/bin 42 | 43 | ENV DOCKERIZE_VERSION v0.6.1 44 | RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 45 | && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 46 | && rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz 47 | 48 | COPY --chown=nobody:nogroup konnectd-identifier-registration.yaml konnectd-identifier-scopes.yaml /etc/kopano/ 49 | COPY wrapper.sh /usr/local/bin 50 | 51 | USER nobody 52 | 53 | ENTRYPOINT ["wrapper.sh"] 54 | 55 | ARG VCS_REF 56 | LABEL org.label-schema.vcs-ref=$VCS_REF 57 | -------------------------------------------------------------------------------- /konnect/README.md: -------------------------------------------------------------------------------- 1 | # Kopano Konnect image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_konnect.svg)](https://microbadger.com/images/zokradonh/kopano_konnect "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_konnect.svg)](https://microbadger.com/images/zokradonh/kopano_konnect "Microbadger version") 4 | 5 | Image to run [Kopano Konnect](https://github.com/kopano-dev/konnect). Takes the [official image](https://cloud.docker.com/u/kopano/repository/docker/kopano/konnectd) and extends it for automatic configuration. 6 | 7 | Currently the container does not support dynamically adding additional clients to the konnectd identifier registration. To add additional values modify the file manually and mount it to `/etc/kopano/konnectd-identifier-registration.yaml` (the container uses this file as a template when adding the required values for Kopano Meet). 8 | -------------------------------------------------------------------------------- /konnect/commander.yaml: -------------------------------------------------------------------------------- 1 | tests: 2 | normal startup: 3 | command: /commander/test-helper.sh && wrapper.sh 4 | exit-code: 0 5 | stdout: 6 | contains: 7 | - "Entrypoint: Allowing guest login" 8 | - "--allow-client-guests" 9 | - "Entrypoint: Allowing dynamic client registration" 10 | - "--allow-dynamic-client-registration" 11 | guests disabled: 12 | command: /commander/test-helper.sh && wrapper.sh && yq . $identifier_registration_conf 13 | stdout: 14 | not-contains: 15 | - "--allow-client-guests" 16 | - "kpop-https://$FQDN/meet/" 17 | config: 18 | env: 19 | allow_client_guests: no 20 | external oidc provider: 21 | command: /commander/test-helper.sh && wrapper.sh && yq . $identifier_registration_conf 22 | stdout: 23 | contains: 24 | - '"authorities": [' 25 | config: 26 | env: 27 | external_oidc_provider: yes 28 | identifier scopes: 29 | command: /commander/test-helper.sh && wrapper.sh && yq . $identifier_scopes_conf 30 | stdout: 31 | contains: 32 | - '"description": "Access Kopano Meet"' 33 | #identifier registration in /etc/kopano: 34 | # command: /commander/test-helper.sh && wrapper.sh && yq . $identifier_registration_conf 35 | # config: 36 | # env: 37 | # identifier_registration_conf: /etc/kopano/konnectd-identifier-registration.yaml 38 | no write permissions for certificates: 39 | command: /commander/test-helper.sh && wrapper.sh 40 | exit-code: 1 41 | stderr: 42 | contains: 43 | - "can't create /root/sign.key: Permission denied" 44 | - 'Timeout after 1s waiting on dependencies to become available: [file:///root/sign.key]' 45 | config: 46 | env: 47 | signing_private_key: /root/sign.key 48 | DOCKERIZE_TIMEOUT: 1s 49 | #certificate creation in container: # currently does not work because of read-only container 50 | # command: /commander/test-helper.sh && wrapper.sh 51 | # stderr: 52 | # contains: 53 | # - "setup: creating new RSA private key at" 54 | # not-contains: 55 | # - "Timeout after 360s waiting on dependencies to become available:" 56 | # config: 57 | # env: 58 | # signing_private_key: /tmp/sign.key 59 | # encryption_secret_key: /tmp/secret.key 60 | config: 61 | env: 62 | PATH: ${PATH} 63 | eckey: ${eckey} 64 | allow_client_guests: ${allow_client_guests} 65 | ecparam: ${ecparam} 66 | signing_private_key: ${signing_private_key} 67 | KONNECT_BACKEND: ${KONNECT_BACKEND} 68 | FQDN: ${FQDN} 69 | identifier_registration_conf: ${identifier_registration_conf} 70 | encryption_secret_key: ${encryption_secret_key} 71 | identifier_scopes_conf: ${identifier_scopes_conf} 72 | allow_dynamic_client_registration: ${allow_dynamic_client_registration} 73 | DEBUG: ${DEBUG} 74 | LANG: ${LANG} 75 | 76 | -------------------------------------------------------------------------------- /konnect/konnectd-identifier-registration.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | # OpenID Connect client registry. 4 | clients: 5 | # - id: oidc-client-example.js 6 | # name: OIDC Playground 7 | # application_type: web 8 | # redirect_uris: 9 | # - https://devmail.kopano.com/kapi-playground/ 10 | # - id: playground.js 11 | # name: OIDC Playground 12 | # application_type: web 13 | # redirect_uris: 14 | # - https://my-host:8509/ 15 | 16 | # - id: playground-trusted.js 17 | # name: Trusted OIDC Playground 18 | # trusted: yes 19 | # application_type: web 20 | # redirect_uris: 21 | # - https://my-host:8509/ 22 | 23 | # - id: playground-trusted.js 24 | # name: Trusted Insecure OIDC Playground 25 | # trusted: yes 26 | # application_type: web 27 | # insecure: yes 28 | 29 | # - id: client-with-keys 30 | # secret: super 31 | # application_type: native 32 | # redirect_uris: 33 | # - http://localhost 34 | # jwks: 35 | # keys: 36 | # - kty: EC 37 | # use: sig 38 | # kid: client-with-keys-key-1 39 | # crv: P-256 40 | # x: RTZpWoRbjwX1YavmSHVBj6Cy3Yzdkkp6QLvTGB22D0c 41 | # y: jeavjwcX0xlDSchFcBMzXSU7wGs2VPpNxWCwmxFvmF0 42 | # request_object_signing_alg: ES256 43 | 44 | # - id: first 45 | # secret: lala 46 | # application_type: native 47 | # redirect_uris: 48 | # - my://app 49 | 50 | # - id: second 51 | # secret: lulu 52 | # application_type: native 53 | # redirect_uris: 54 | # - http://localhost 55 | -------------------------------------------------------------------------------- /konnect/konnectd-identifier-scopes.yaml: -------------------------------------------------------------------------------- 1 | # This file contains additional scopes for Konnect. All of the scopes listed 2 | # here are made available to clients upon request if not limited by other means. 3 | 4 | --- 5 | scopes: 6 | kopano/gc: 7 | description: "Kopano" 8 | 9 | kopano/kwm: 10 | description: "Access Kopano Meet" 11 | 12 | kopano/kvs: 13 | description: "Access Kopano Key Value Store" 14 | 15 | kopano/pubs: 16 | description: "Access Kopano Pub/Sub" 17 | -------------------------------------------------------------------------------- /konnect/test-helper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # add a dummy for the konnectd binary 4 | cat << 'EOF' > /commander/konnectd 5 | #!/bin/sh 6 | echo konnectd $@ 7 | EOF 8 | 9 | chmod +x /commander/konnectd 10 | 11 | exit 0 12 | -------------------------------------------------------------------------------- /kwmbridge/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG CODE_VERSION=0.1.3 2 | FROM kopano/kwmbridged:${CODE_VERSION} 3 | 4 | ARG CODE_VERSION 5 | ENV \ 6 | AUTOCONFIGURE=true \ 7 | CODE_VERSION="${CODE_VERSION}" 8 | 9 | LABEL maintainer=az@zok.xyz \ 10 | org.label-schema.name="Kopano Kwmbridge container" \ 11 | org.label-schema.description="Container for running Kopano Kwmbridge (SFU)" \ 12 | org.label-schema.url="https://kopano.io" \ 13 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 14 | org.label-schema.version=$CODE_VERSION \ 15 | org.label-schema.schema-version="1.0" 16 | 17 | SHELL ["/bin/ash", "-eo", "pipefail", "-c"] 18 | 19 | USER root 20 | ENV DOCKERIZE_VERSION v0.11.6 21 | RUN wget -O - https://github.com/powerman/dockerize/releases/download/"$DOCKERIZE_VERSION"/dockerize-"$(uname -s)"-"$(uname -m)" | install /dev/stdin /bin/dockerize 22 | USER nobody 23 | 24 | COPY wrapper.sh /usr/local/bin 25 | 26 | ENTRYPOINT ["wrapper.sh"] 27 | 28 | ARG VCS_REF 29 | LABEL org.label-schema.vcs-ref=$VCS_REF 30 | -------------------------------------------------------------------------------- /kwmbridge/README.md: -------------------------------------------------------------------------------- 1 | # Kopano Kwmbridge image (SFU for Kopano Meet) 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_kwmbridge.svg)](https://microbadger.com/images/zokradonh/kopano_kwmbridge "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_kwmbridge.svg)](https://microbadger.com/images/zokradonh/kopano_kwmbridge "Microbadger version") 4 | 5 | Image to run [Kopano Kwmbridge](https://github.com/kopano-dev/kwmbridge). Takes the [official image](https://cloud.docker.com/u/kopano/repository/docker/kopano/kwmserverd) and extends it for automatic configuration. Optional component of Kopano Meet/Kwmserver. 6 | 7 | To work Kwmbridge needs a large range of forwarded ports and therefore running the container in host mode is probably the most useful approach. In case Meet is running behind NAT it could additionally be helpful to run Kwmbridge on a dedicated system, which would be directly reachable. 8 | -------------------------------------------------------------------------------- /kwmbridge/wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | [ "$DEBUG" ] && set -x 5 | 6 | if [ -n "${log_level:-}" ]; then 7 | set -- "$@" --log-level="$log_level" 8 | fi 9 | 10 | if [ -n "${oidc_issuer_identifier:-}" ]; then 11 | set -- "$@" --iss="$oidc_issuer_identifier" 12 | fi 13 | 14 | if [ -n "${kwm_server_urls:-}" ]; then 15 | for url in $kwm_server_urls; do 16 | set -- "$@" --kwmserver-url="$url" 17 | done 18 | fi 19 | 20 | if [ -n "${ice_interfaces:-}" ]; then 21 | for ice_if in $ice_interfaces; do 22 | set -- "$@" --use-ice-if="$ice_if" 23 | done 24 | fi 25 | 26 | if [ -n "${ice_network_types:-}" ]; then 27 | for ice_network_type in $ice_network_types; do 28 | set -- "$@" --use-ice-network-type="$ice_network_type" 29 | done 30 | fi 31 | 32 | if [ -n "${ice_udp_port_range:-}" ]; then 33 | set -- "$@" --use-ice-udp-port-range="$ice_udp_port_range" 34 | fi 35 | 36 | if [ -n "${use_nat_1to1_ips:-}" ]; then 37 | for use_nat_1to1_ip in $use_nat_1to1_ips; do 38 | set -- "$@" --use-nat-1to1-ip="$use_nat_1to1_ip" 39 | done 40 | fi 41 | 42 | if [ -n "${use_nat_1to1_candidate_type:-}" ]; then 43 | set -- "$@" --use-nat-1to1-candidate-type="$use_nat_1to1_candidate_type" 44 | fi 45 | 46 | if [ "${with_metrics:-}" = "yes" ]; then 47 | set -- "$@" --with-metrics 48 | fi 49 | 50 | if [ "${metrics_listen:-}" ]; then 51 | set -- "$@" --metrics-listen="$metrics_listen" 52 | fi 53 | 54 | if [ "$INSECURE" = "yes" ]; then 55 | set -- "$@" --insecure 56 | fi 57 | 58 | if [ "${AUTOCONFIGURE}" = true ]; then 59 | if [ "$INSECURE" = "yes" ]; then 60 | dockerize \ 61 | -skip-tls-verify \ 62 | -wait "$oidc_issuer_identifier"/.well-known/openid-configuration \ 63 | -timeout 360s 64 | else 65 | dockerize \ 66 | -wait "$oidc_issuer_identifier"/.well-known/openid-configuration \ 67 | -timeout 360s 68 | fi 69 | 70 | # services need to be aware of the machine-id 71 | dockerize \ 72 | -wait file:///etc/machine-id \ 73 | -wait file:///var/lib/dbus/machine-id 74 | fi 75 | 76 | exec kwmbridged serve \ 77 | "$@" 78 | -------------------------------------------------------------------------------- /kwmserver/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG CODE_VERSION=1.2.0 2 | FROM kopano/kwmserverd:${CODE_VERSION} 3 | 4 | ARG CODE_VERSION 5 | ENV \ 6 | AUTOCONFIGURE=true \ 7 | CODE_VERSION="${CODE_VERSION}" 8 | 9 | LABEL maintainer=az@zok.xyz \ 10 | org.label-schema.name="Kopano Kwmserver container" \ 11 | org.label-schema.description="Container for running Kopano Kwmserver (WebRTC signalling server)" \ 12 | org.label-schema.url="https://kopano.io" \ 13 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 14 | org.label-schema.version=$CODE_VERSION \ 15 | org.label-schema.schema-version="1.0" 16 | 17 | SHELL ["/bin/ash", "-eo", "pipefail", "-c"] 18 | 19 | USER root 20 | ENV DOCKERIZE_VERSION v0.11.6 21 | RUN wget -O - https://github.com/powerman/dockerize/releases/download/"$DOCKERIZE_VERSION"/dockerize-"$(uname -s)"-"$(uname -m)" | install /dev/stdin /bin/dockerize 22 | USER nobody 23 | 24 | COPY wrapper.sh /usr/local/bin 25 | 26 | ARG VCS_REF 27 | LABEL org.label-schema.vcs-ref=$VCS_REF 28 | -------------------------------------------------------------------------------- /kwmserver/README.md: -------------------------------------------------------------------------------- 1 | # Kopano Kwmserver image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_kwmserver.svg)](https://microbadger.com/images/zokradonh/kopano_kwmserver "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_kwmserver.svg)](https://microbadger.com/images/zokradonh/kopano_kwmserver "Microbadger version") 4 | 5 | Image to run [Kopano Kwmserver](https://github.com/kopano-dev/kwmserver). Takes the [official image](https://cloud.docker.com/u/kopano/repository/docker/kopano/kwmserverdd) and extends it for automatic configuration. 6 | -------------------------------------------------------------------------------- /kwmserver/wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | [ "$DEBUG" ] && set -x 5 | 6 | if [ -n "${log_level:-}" ]; then 7 | set -- "$@" --log-level="$log_level" 8 | fi 9 | 10 | if [ -n "${oidc_issuer_identifier:-}" ]; then 11 | set -- "$@" --iss="$oidc_issuer_identifier" 12 | fi 13 | 14 | if [ "${enable_guest_api:-}" = "yes" ]; then 15 | set -- "$@" --enable-guest-api 16 | fi 17 | 18 | if [ "${enable_rtm_api:-}" = "yes" ]; then 19 | set -- "$@" --enable-rtm-api 20 | fi 21 | 22 | if [ "${enable_mcu_api:-}" = "yes" ]; then 23 | set -- "$@" --enable-mcu-api 24 | fi 25 | 26 | if [ "$INSECURE" = "yes" ]; then 27 | set -- "$@" --insecure 28 | fi 29 | 30 | # kwmserver turn 31 | # default to Kopano turn service 32 | turn_service_url=${turn_service_url:-https://turnauth.kopano.com/turnserverauth/} 33 | 34 | if [ -n "$turn_service_url" ]; then 35 | set -- "$@" --turn-service-url="$turn_service_url" 36 | fi 37 | 38 | if [ -n "${turn_service_credentials_user:-}" ] && [ -n "${turn_service_credentials_password:-}" ]; then 39 | turn_service_credentials=/tmp/turn_service_credentials 40 | echo "$turn_service_credentials_user":"$turn_service_credentials_password" > "$turn_service_credentials" 41 | fi 42 | 43 | if [ -n "${turn_service_credentials:-}" ]; then 44 | set -- "$@" --turn-service-credentials="$turn_service_credentials" 45 | fi 46 | 47 | if [ -n "${turn_server_shared_secret:-}" ]; then 48 | if [ ! -f "$turn_server_shared_secret" ]; then 49 | turn_server_shared_secret_file=/tmp/turn_server_shared_secret_file 50 | echo "$turn_server_shared_secret" > "$turn_server_shared_secret_file" 51 | turn_server_shared_secret="$turn_server_shared_secret_file" 52 | fi 53 | set -- "$@" --turn-server-shared-secret="$turn_server_shared_secret" 54 | fi 55 | 56 | if [ -n "${turn_uris:-}" ]; then 57 | for uri in $turn_uris; do 58 | set -- "$@" --turn-uri="$uri" 59 | done 60 | fi 61 | 62 | # kwmserver guest 63 | if [ "${allow_guest_only_channels:-}" = "yes" ]; then 64 | set -- "$@" --allow-guest-only-channels 65 | fi 66 | 67 | if [ -n "${public_guest_access_regexp:-}" ]; then 68 | set -- "$@" --public-guest-access-regexp="$public_guest_access_regexp" 69 | fi 70 | 71 | # sfu functionality 72 | if [ -n "${pipeline_forced_regexp:-}" ]; then 73 | set -- "$@" --pipeline-forced-regexp="$pipeline_forced_regexp" 74 | fi 75 | 76 | if [ "${AUTOCONFIGURE}" = true ]; then 77 | if [ "$INSECURE" = "yes" ]; then 78 | dockerize \ 79 | -skip-tls-verify \ 80 | -wait "$oidc_issuer_identifier"/.well-known/openid-configuration \ 81 | -timeout 360s 82 | else 83 | dockerize \ 84 | -wait "$oidc_issuer_identifier"/.well-known/openid-configuration \ 85 | -timeout 360s 86 | fi 87 | 88 | # services need to be aware of the machine-id 89 | dockerize \ 90 | -wait file:///etc/machine-id \ 91 | -wait file:///var/lib/dbus/machine-id 92 | fi 93 | 94 | registration_conf=${registration_conf:-/etc/kopano/kwmserverd-registration.yaml} 95 | 96 | exec /usr/local/bin/docker-entrypoint.sh serve \ 97 | --registration-conf "$registration_conf" \ 98 | "$@" 99 | -------------------------------------------------------------------------------- /ldap-extras/README.md: -------------------------------------------------------------------------------- 1 | # LDAP extras for kopano-docker 2 | 3 | This directory contains a compose file including optional containers. 4 | 5 | ## How to use this compose file? 6 | 7 | 1. Add the `ldap-extras.yml` to the `COMPOSE_FILE` variable in your `.env` file. 8 | 9 | Example: 10 | 11 | ```bash 12 | COMPOSE_FILE=docker-compose.yml:docker-compose.ports.yml:ldap-extras/ldap-extras.yml 13 | ``` 14 | 15 | 2. Run `docker-compose up -d`. 16 | 17 | ## ldap-admin 18 | 19 | After startup you can access phpLDAPadmin by going to `https://kopano.demo/ldap-admin` 20 | 21 | To login use the `cn=admin,$LDAP_BASE_DN` and `LDAP_BIND_PW` from the `.env` file. 22 | 23 | Check https://documentation.kopano.io/kopanocore_administrator_manual/user_management.html#user-management-from-openldap to learn more about Kopanos LDAP possibilities. 24 | 25 | ## password-self-service 26 | 27 | After startup you can access [Self Service Password](https://ltb-project.org/documentation/self-service-password) by visiting `https://kopano.demo/password-reset/`. 28 | -------------------------------------------------------------------------------- /ldap-extras/ldap-account-manager.yml: -------------------------------------------------------------------------------- 1 | # Depends on https://github.com/LDAPAccountManager/lam/pull/76 2 | version: "3.5" 3 | 4 | services: 5 | ldap-account-manager: 6 | image: ldapaccountmanager/lam:7.0.RC1 # newer releases may exist, this tag was the first one with the required changes 7 | restart: unless-stopped 8 | #ports: 9 | # - "8080:80" 10 | depends_on: 11 | - ldap 12 | - web 13 | volumes: 14 | - lametc/:/etc/ldap-account-manager 15 | - lamconfig/:/var/lib/ldap-account-manager/config 16 | - lamsession/:/var/lib/ldap-account-manager/sess 17 | environment: 18 | - LAM_PASSWORD=${LDAP_ADMIN_PASSWORD} 19 | - LAM_LANG=en_US 20 | - LAM_TIMEZONE=Europe/Berlin 21 | - LDAP_SERVER=${LDAP_SERVER} 22 | - LDAP_DOMAIN=${LDAP_DOMAIN} 23 | - LDAP_BASE_DN=${LDAP_BASE_DN} 24 | - ADMIN_USER=cn=admin,${LDAP_BASE_DN} 25 | #- DEBUG=true 26 | networks: 27 | - ldap-net 28 | - web-net 29 | volumes: 30 | lametc: 31 | lamconfig: 32 | lamsession: 33 | -------------------------------------------------------------------------------- /ldap-extras/ldap-extras.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | ldap-admin: 5 | image: osixia/phpldapadmin:0.7.2 6 | restart: unless-stopped 7 | depends_on: 8 | - ldap 9 | environment: 10 | - PHPLDAPADMIN_LDAP_HOSTS=ldap 11 | - PHPLDAPADMIN_HTTPS=false 12 | networks: 13 | - ldap-net 14 | - web-net 15 | 16 | password-self-service: 17 | image: tiredofit/self-service-password:3.0 18 | restart: unless-stopped 19 | domainname: ${LDAP_DOMAIN} 20 | depends_on: 21 | - ldap 22 | - mail 23 | environment: 24 | - SSP_VERSION=1.3 25 | - LDAP_SERVER=ldap://ldap:389 26 | - LDAP_BINDDN=cn=admin,${LDAP_BASE_DN} 27 | - LDAP_BINDPASS=${LDAP_ADMIN_PASSWORD} 28 | - LDAP_BASE_SEARCH=${LDAP_BASE_DN} 29 | - MAIL_FROM=noreply@${LDAP_DOMAIN} 30 | - SMTP_HOST=mail 31 | - SMTP_PORT=25 32 | - SMTP_SECURE_TYPE=false 33 | - SMTP_AUTOTLS=false 34 | - QUESTIONS_ENABLED=false 35 | - PASSWORD_NO_REUSE=true 36 | - WHO_CAN_CHANGE_PASSWORD=user 37 | - SECRETEKEY=${SELF_SERVICE_SECRETEKEY} 38 | - BACKGROUND=. 39 | - PASSWORD_MIN_LENGTH=${SELF_SERVICE_PASSWORD_MIN_LENGTH} 40 | - PASSWORD_MAX_LENGTH=${SELF_SERVICE_PASSWORD_MAX_LENGTH} 41 | - PASSWORD_MIN_LOWERCASE=${SELF_SERVICE_PASSWORD_MIN_LOWERCASE} 42 | - PASSWORD_MIN_UPPERCASE=${SELF_SERVICE_PASSWORD_MIN_UPPERCASE} 43 | - PASSWORD_MIN_DIGIT=${SELF_SERVICE_PASSWORD_MIN_DIGIT} 44 | - PASSWORD_MIN_SPECIAL=${SELF_SERVICE_PASSWORD_MIN_SPECIAL} 45 | - PASSWORD_HASH=CRYPT 46 | env_file: 47 | - password-self-service.env 48 | expose: 49 | - "80" 50 | networks: 51 | - web-net # provide web-frontend 52 | - ldap-net # access ldap user base and write passwords 53 | - kopano-net # send mail directly to mailstack 54 | -------------------------------------------------------------------------------- /ldap/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG CODE_VERSION=1.3.0 2 | FROM osixia/openldap:${CODE_VERSION} 3 | 4 | ARG CODE_VERSION 5 | ENV CODE_VERSION="${CODE_VERSION}" 6 | 7 | LABEL maintainer=az@zok.xyz \ 8 | org.label-schema.name="Kopano LDAP container" \ 9 | org.label-schema.description="Container for running OpenLDAP, which already has the Kopano schema included." \ 10 | org.label-schema.url="https://kopano.io" \ 11 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 12 | org.label-schema.version=$CODE_VERSION \ 13 | org.label-schema.schema-version="1.0" 14 | 15 | COPY bootstrap /container/service/slapd/assets/config/bootstrap 16 | RUN rm /container/service/slapd/assets/config/bootstrap/schema/mmc/mail.schema 17 | RUN touch /etc/ldap/slapd.conf 18 | 19 | ARG VCS_REF 20 | LABEL org.label-schema.vcs-ref=$VCS_REF -------------------------------------------------------------------------------- /ldap/README.md: -------------------------------------------------------------------------------- 1 | # Kopano LDAP image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_ldap.svg)](https://microbadger.com/images/zokradonh/kopano_ldap "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_ldap.svg)](https://microbadger.com/images/zokradonh/kopano_ldap "Microbadger version") 4 | 5 | Image to for an OpenLDAP server that already includes the Kopano LDAP schema. Based on https://github.com/osixia/docker-openldap. 6 | -------------------------------------------------------------------------------- /ldap/bootstrap/ldif/optimize-index.ldif: -------------------------------------------------------------------------------- 1 | dn: olcDatabase={1}mdb,cn=config 2 | changetype: modify 3 | replace: olcDbIndex 4 | olcDbIndex: memberOf eq 5 | olcDbIndex: entryCSN eq 6 | olcDbIndex: entryUUID eq 7 | olcDbIndex: objectClass eq 8 | olcDbIndex: cn pres,eq,sub 9 | olcDbIndex: gidNumber eq 10 | olcDbIndex: mail pres,eq,sub 11 | olcDbIndex: memberUid eq 12 | olcDbIndex: ou eq 13 | olcDbIndex: uid eq 14 | olcDbIndex: uidNumber eq 15 | olcDbIndex: uniqueMember eq 16 | olcDbIndex: kopanoAccount eq,pres 17 | olcDbIndex: kopanoAliases eq 18 | olcDbIndex: kopanoViewPrivilege eq 19 | olcDbIndex: sn pres,eq,sub 20 | olcDbIndex: givenName pres,eq,sub 21 | -------------------------------------------------------------------------------- /ldap_demo/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG docker_repo=zokradonh 2 | FROM ${docker_repo}/kopano_ldap 3 | 4 | LABEL org.label-schema.description="Container for running OpenLDAP, which already has the Kopano schema included as well as users to easily demo the environment." 5 | 6 | COPY bootstrap /container/service/slapd/assets/config/bootstrap 7 | -------------------------------------------------------------------------------- /ldap_demo/README.md: -------------------------------------------------------------------------------- 1 | # Kopano LDAP demo image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_ldap_demo.svg)](https://microbadger.com/images/zokradonh/kopano_ldap_demo "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_ldap_demo.svg)](https://microbadger.com/images/zokradonh/kopano_ldap_demo "Microbadger version") 4 | 5 | Image to for an OpenLDAP server to provide some demo users for Kopano. Based on https://github.com/osixia/docker-openldap. 6 | 7 | The LDAP tree is prepared for both single tenant setups (the default in Kopano) and multi tenant setups. To configure the multi tenant mode (also referred to as "hosted") of `kopano-server` the following values need to be added to `kopano_server.env`: 8 | 9 | ```bash 10 | KCCONF_SERVER_ENABLE_HOSTED_KOPANO=YES 11 | KCCONF_LDAP_LDAP_COMPANY_TYPE_ATTRIBUTE_VALUE=kopano-company 12 | ``` 13 | 14 | Additionally the ldap tree is also prepared for multiserver installations (also referred to as "distributed"), where multiple `kopano-server` processes share the total amount of mailboxes (controlled through a manual mapping in LDAP). See [Multiserver Example](../examples/kopano-multiserver) for more information. 15 | 16 | ```bash 17 | $ docker-compose -f examples/kopano-multiserver.yml up 18 | ``` 19 | 20 | Demo users created in the demo ldap all have a password that is identical to the username, e.g. the password for `user1` user `user1`. The user `user23 is setup to be an admin within Kopano.` 21 | -------------------------------------------------------------------------------- /meet/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1.0-experimental 2 | ARG docker_repo=zokradonh 3 | FROM ${docker_repo}/kopano_base:latest 4 | 5 | ARG ADDITIONAL_KOPANO_PACKAGES="" 6 | ARG DOWNLOAD_COMMUNITY_PACKAGES=1 7 | ARG KOPANO_REPOSITORY_FLAGS="trusted=yes" 8 | ARG DEBIAN_FRONTEND=noninteractive 9 | ARG KOPANO_CORE_REPOSITORY_URL="file:/kopano/repo/core" 10 | ARG KOPANO_CORE_VERSION=newest 11 | ARG KOPANO_MEET_REPOSITORY_URL="file:/kopano/repo/meet" 12 | ARG KOPANO_MEET_VERSION=newest 13 | ENV KOPANO_MEET_VERSION=$KOPANO_MEET_VERSION 14 | 15 | ENV \ 16 | ADDITIONAL_KOPANO_PACKAGES=$ADDITIONAL_KOPANO_PACKAGES \ 17 | DOWNLOAD_COMMUNITY_PACKAGES=$DOWNLOAD_COMMUNITY_PACKAGES \ 18 | KOPANO_CORE_REPOSITORY_URL=$KOPANO_CORE_REPOSITORY_URL \ 19 | KOPANO_CORE_VERSION=$KOPANO_CORE_VERSION \ 20 | KOPANO_REPOSITORY_FLAGS=$KOPANO_REPOSITORY_FLAGS \ 21 | SERVICE_TO_START=meet 22 | 23 | LABEL maintainer=az@zok.xyz \ 24 | org.label-schema.name="Kopano Meet container" \ 25 | org.label-schema.description="Container for running Kopano Meet" \ 26 | org.label-schema.url="https://kopano.io" \ 27 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 28 | org.label-schema.version=$KOPANO_MEET_VERSION \ 29 | org.label-schema.schema-version="1.0" 30 | 31 | SHELL ["/bin/bash", "-o", "pipefail", "-c"] 32 | 33 | RUN --mount=type=secret,id=repocred,target=/etc/apt/auth.conf.d/kopano.conf \ 34 | # apt key for this repo has already been installed in base 35 | # community download and package as apt source repository 36 | . /kopano/helper/create-kopano-repo.sh && \ 37 | if [ ${DOWNLOAD_COMMUNITY_PACKAGES} -eq 1 ]; then \ 38 | dl_and_package_community "meet"; \ 39 | fi; \ 40 | echo "deb [${KOPANO_REPOSITORY_FLAGS}] ${KOPANO_MEET_REPOSITORY_URL} ./" > /etc/apt/sources.list.d/kopano.list; \ 41 | # install 42 | apt-get update && \ 43 | # TODO mime-support could be remove once its an official dependency of kopano-kwebd 44 | apt-get install --no-install-recommends -y \ 45 | mime-support \ 46 | kopano-kwebd \ 47 | kopano-meet kopano-meet-webapp \ 48 | ${ADDITIONAL_KOPANO_PACKAGES} \ 49 | && \ 50 | rm -rf /var/cache/apt /var/lib/apt/lists && \ 51 | # make configuration a symlink to prevent overwriting it 52 | # TODO better would be to override its configuration in kweb.cfg 53 | mkdir -p /etc/kopano/kweb/overrides.d/config/kopano/ && \ 54 | ln -s /tmp/meet.json /etc/kopano/kweb/overrides.d/config/kopano/meet.json 55 | 56 | COPY start-service.sh /kopano/ 57 | COPY goss.yaml /goss/ 58 | CMD [ "/kopano/start-service.sh" ] 59 | 60 | HEALTHCHECK --interval=1m --timeout=10s \ 61 | CMD goss -g /goss/goss.yaml validate 62 | 63 | ARG VCS_REF 64 | LABEL org.label-schema.vcs-ref=$VCS_REF -------------------------------------------------------------------------------- /meet/README.md: -------------------------------------------------------------------------------- 1 | # Kopano Meet image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_meet.svg)](https://microbadger.com/images/zokradonh/kopano_meet "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_meet.svg)](https://microbadger.com/images/zokradonh/kopano_meet "Microbadger version") 4 | 5 | Image to run [Kopano Meet](https://github.com/Kopano-dev/meet). 6 | 7 | ## Configuration through environment variables 8 | 9 | Any additional configuration should be done through environment variables and not done in the actual container. The images working with configuration files (e.g. `kopano_core`, `kopano_webapp`, `kopano_meet`) have a mechanism built in to translate env variables into configuration files. For services that can directly work with env variables (e.g. `kopano_konnect`, ´kopano_kwmserver´) these can be specified directly. Please check the individual `README.md` files for further instructions. 10 | 11 | Examples of env variables: 12 | 13 | ```bash 14 | KCCONF_KWEBD_TLS=no 15 | ^ ^ ^ ^ 16 | | | | | 17 | General prefix | 18 | | | | 19 | Name of the relevant configuration file (kwebd.cfg in this case) 20 | | | 21 | Name of the configuration option in the configuration file 22 | | 23 | Value of the configuration option 24 | ``` 25 | -------------------------------------------------------------------------------- /meet/goss.yaml: -------------------------------------------------------------------------------- 1 | file: 2 | /tmp/meet.json: 3 | exists: true 4 | mode: "0644" 5 | owner: root 6 | group: root 7 | filetype: file 8 | contains: [] 9 | process: 10 | kwebd: 11 | running: true 12 | http: 13 | http://localhost:9080/meet: 14 | status: 200 15 | allow-insecure: false 16 | no-follow-redirects: false 17 | timeout: 5000 18 | body: [] 19 | -------------------------------------------------------------------------------- /meet/start-service.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ADDITIONAL_KOPANO_PACKAGES=${ADDITIONAL_KOPANO_PACKAGES:-""} 4 | 5 | set -eu # unset variables are errors & non-zero return values exit the whole script 6 | [ "$DEBUG" ] && set -x 7 | 8 | if [ "${AUTOCONFIGURE}" == true ]; then 9 | # copy configuration files to /tmp/kopano to prevent modification of mounted config files 10 | mkdir -p /tmp/kopano 11 | cp /etc/kopano/*.cfg /tmp/kopano 12 | 13 | echo "Applying cfg changes from env" 14 | /usr/bin/python3 /kopano/cfg-from-env.py 15 | fi 16 | 17 | meetversion=$(dpkg-query --showformat='${Version}' --show kopano-meet-webapp) 18 | echo "Using Kopano Meet: $meetversion" 19 | 20 | # allow helper commands given by "docker-compose run" 21 | if [ $# -gt 0 ]; then 22 | exec "$@" 23 | exit 24 | fi 25 | 26 | if [ "${AUTOCONFIGURE}" == true ]; then 27 | cp /usr/share/doc/kopano-meet-webapp/config.json.in /tmp/meet.json 28 | CONFIG_JSON="/tmp/meet.json" 29 | echo "Updating $CONFIG_JSON" 30 | for setting in $(compgen -A variable KCCONF_MEET); do 31 | setting2=${setting#KCCONF_MEET_} 32 | # dots in setting2 need to be escaped to not be handled as separate entities in the json file 33 | case ${!setting} in 34 | true|TRUE|false|FALSE|[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]) 35 | jq ".\"${setting2//_/\".\"}\" = ${!setting}" $CONFIG_JSON | sponge $CONFIG_JSON 36 | ;; 37 | *) 38 | jq ".\"${setting2//_/\".\"}\" = \"${!setting}\"" $CONFIG_JSON | sponge $CONFIG_JSON 39 | ;; 40 | esac 41 | done 42 | 43 | # Populate app grid 44 | # Note: if below variables are set to "no" kpop will fall back to its default behaviour and show all known apps. 45 | # enable Kopano Konnect in the app grid 46 | if [ "${GRID_KONNECT:-yes}" = "yes" ]; then 47 | jq '.apps.enabled += ["kopano-konnect"]' $CONFIG_JSON | sponge $CONFIG_JSON 48 | fi 49 | 50 | # enable Kopano Meet in the app grid 51 | if [ "${GRID_MEET:-yes}" = "yes" ]; then 52 | jq '.apps.enabled += ["kopano-meet"]' $CONFIG_JSON | sponge $CONFIG_JSON 53 | fi 54 | 55 | # enable Kopano WebApp in the app grid 56 | if [ "${GRID_WEBAPP:-yes}" = "yes" ]; then 57 | jq '.apps.enabled += ["kopano-webapp"]' $CONFIG_JSON | sponge $CONFIG_JSON 58 | fi 59 | 60 | # enable Kopano WebApp in the app grid 61 | if [ "${GRID_CALENDAR:-yes}" = "yes" ]; then 62 | jq '.apps.enabled += ["kopano-calendar"]' $CONFIG_JSON | sponge $CONFIG_JSON 63 | fi 64 | 65 | sed s/\ *=\ */=/g /tmp/kopano/kwebd.cfg > /tmp/kweb-env 66 | # always disable tls 67 | export tls=no 68 | # shellcheck disable=SC2046 69 | export $(grep -v '^#' /tmp/kweb-env | xargs -d '\n') 70 | 71 | # services need to be aware of the machine-id 72 | dockerize \ 73 | -wait file:///etc/machine-id \ 74 | -wait file:///var/lib/dbus/machine-id 75 | fi 76 | 77 | # cleaning up env variables 78 | unset "${!KCCONF_@}" 79 | exec kopano-kwebd serve 80 | -------------------------------------------------------------------------------- /owncloud/.gitignore: -------------------------------------------------------------------------------- 1 | openidconnect 2 | phoenix 3 | -------------------------------------------------------------------------------- /owncloud/99-ldap.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "Configuring LDAP for kopano-docker" 4 | 5 | set -x 6 | 7 | occ app:enable user_ldap 8 | occ ldap:show-config 9 | 10 | if [[ "$(occ ldap:show-config)" == "" ]]; then 11 | su -c "php occ ldap:create-empty-config" www-data 12 | fi 13 | 14 | ldapHost=${LDAP_SERVER%:*} 15 | ldapPort=${LDAP_SERVER##*:} 16 | 17 | occ ldap:set-config s01 ldapHost ${ldapHost} 18 | occ ldap:set-config s01 ldapPort ${ldapPort} 19 | occ ldap:set-config s01 ldapAgentName ${LDAP_BIND_DN} 20 | occ ldap:set-config s01 ldapAgentPassword ${LDAP_BIND_PW} 21 | occ ldap:set-config s01 ldapBase ${LDAP_SEARCH_BASE} 22 | occ ldap:set-config s01 ldapUserFilter "(|(objectclass=kopano-user))" 23 | occ ldap:set-config s01 ldapLoginFilter "(&(|(objectclass=kopano-user))(uid=%uid))" 24 | occ ldap:set-config s01 ldapGroupFilter "(&(|(objectclass=kopano-group)))" 25 | occ ldap:set-config s01 ldapEmailAttribute "mail" 26 | occ ldap:set-config s01 ldapExpertUUIDUserAttr "entryuuid" 27 | occ ldap:set-config s01 ldapUserDisplayName "cn" 28 | occ ldap:set-config s01 ldapUserFilter "(|(objectclass=posixAccount))" 29 | occ ldap:set-config s01 ldapConfigurationActive 1 30 | 31 | /usr/bin/occ user:sync -m disable "OCA\User_LDAP\User_Proxy" 32 | 33 | cat << EOF >| /etc/cron.d/sync 34 | */10 * * * * root /usr/bin/occ user:sync -m disable 'OCA\User_LDAP\User_Proxy' 35 | EOF 36 | 37 | true 38 | -------------------------------------------------------------------------------- /owncloud/99-oidc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "Configuring OIDC for kopano-docker" 4 | 5 | set -x 6 | 7 | occ app:enable openidconnect 8 | 9 | TODAY=$(date) 10 | cat </mnt/data/config/konnectd.config.php 11 | 0, 15 | 'debug' => true, 16 | 'openid-connect' => [ 17 | 'provider-url' => 'https://$OWNCLOUD_DOMAIN', 18 | 'client-id' => 'ownCloud', 19 | 'client-secret' => 'ownCloud', 20 | 'loginButtonName' => 'kopano', 21 | 'autoRedirectOnLoginPage' => false, 22 | 'redirect-url' => 'https://$OWNCLOUD_DOMAIN/owncloud/index.php/apps/openidconnect/redirect', 23 | 'mode' => 'email', 24 | 'search-attribute' => 'email', 25 | 'use-token-introspection-endpoint' => false 26 | ], 27 | ]; 28 | EOF 29 | 30 | true 31 | -------------------------------------------------------------------------------- /owncloud/README.md: -------------------------------------------------------------------------------- 1 | # Running kopano-docker together with Owncloud 2 | 3 | To have a demo environment that runs both Kopano and Owncloud perform the following modifications. This setup uses the official images from https://hub.docker.com/r/owncloud/server. 4 | 5 | 1. Add the `owncloud.yml` to the `COMPOSE_FILE` variable in your `.env` file. 6 | 7 | Example: 8 | 9 | ```bash 10 | COMPOSE_FILE=docker-compose.yml:docker-compose.ports.yml:owncloud/owncloud.yml 11 | ``` 12 | 13 | 2. change into the owncloud folder and run `owncloud.sh` to create the required runtime variables in your `.env` file. 14 | 15 | 3. change back into the root of the checkout and run `docker-compose up -d` and you will be able to log into `https://your-fqdn/owncloud`. 16 | 17 | ## Further tweaks 18 | 19 | Add the following to `kopano_webapp.env` to have the intranet plugin display both Kopano Meet as well as Owncloud (replace `kopano.demo with your own` FQDN): 20 | 21 | ```bash 22 | KCCONF_WEBAPPPLUGIN_INTRANET_PLUGIN_INTRANET_USER_DEFAULT_ENABLE=true 23 | KCCONF_WEBAPPPLUGIN_INTRANET_PLUGIN_INTRANET_BUTTON_TITLE=Kopano Meet 24 | KCCONF_WEBAPPPLUGIN_INTRANET_PLUGIN_INTRANET_URL=https://kopano.demo/meet/ 25 | KCCONF_WEBAPPPLUGIN_INTRANET_PLUGIN_INTRANET_AUTOSTART=true 26 | KCCONF_WEBAPPPLUGIN_INTRANET_PLUGIN_INTRANET_ICON=resources/icons/icon_default.png 27 | 28 | KCCONF_WEBAPPPLUGIN_INTRANET_PLUGIN_INTRANET_AUTOSTART_1=true 29 | KCCONF_WEBAPPPLUGIN_INTRANET_PLUGIN_INTRANET_URL_1=https://kopano.demo/owncloud/ 30 | KCCONF_WEBAPPPLUGIN_INTRANET_PLUGIN_INTRANET_BUTTON_TITLE_1=Owncloud 31 | ``` 32 | 33 | Add/extend the following line in your `.env`: 34 | 35 | ```bash 36 | ADDITIONAL_KOPANO_WEBAPP_PLUGINS="kopano-webapp-plugin-intranet kopano-webapp-plugin-files kopano-webapp-plugin-filesbackend-owncloud" 37 | ``` 38 | -------------------------------------------------------------------------------- /owncloud/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "server": "https://kopano.demo:2015/owncloud/", 3 | "theme": "owncloud", 4 | "version": "0.1.0", 5 | "openIdConnect": { 6 | "authority": "https://kopano.demo:2015/", 7 | "client_id": "owncloud", 8 | "client_secret": "owncloud", 9 | "response_type": "id_token token", 10 | "scope": "openid profile email", 11 | "automaticSilentRenew": true 12 | }, 13 | "apps": [ 14 | "files" 15 | ], 16 | "menu": { 17 | "items": [ 18 | { 19 | "name": "Kopano Meet", 20 | "url": "https://kopano.demo:2015/meet", 21 | "iconMaterial": "hearing" 22 | }, 23 | { 24 | "name": "Kopano Webapp", 25 | "url": "https://kopano.demo:2015/webapp/", 26 | "iconMaterial": "transform" 27 | } 28 | ] 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /owncloud/kopano/README.md: -------------------------------------------------------------------------------- 1 | # A Theme for ownCloud to make look more in line with Kopano WebApp 2 | 3 | ## TODO 4 | 5 | - [ ] needs signing for owncloud integrity check to not complain about it 6 | - https://doc.owncloud.org/server/10.1/developer_manual/app/advanced/code_signing.html -------------------------------------------------------------------------------- /owncloud/kopano/appinfo/info.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | kopano 4 | Kopano Theme for ownCloud 5 | Make your ownCloud look more integrated with the Intranet Plugin of Kopano WebApp 6 | AGPL 7 | Felix Bartels 8 | 0.0.1 9 | 10 | 11 | 12 | 13 | 14 | 15 | Theme 16 | 17 | -------------------------------------------------------------------------------- /owncloud/kopano/core/css/styles.css: -------------------------------------------------------------------------------- 1 | /** 2 | * @author Jan-Christoph Borchardt, http://jancborchardt.net 3 | * @copyright Copyright (c) 2018, ownCloud GmbH 4 | * @license AGPL-3.0 5 | * 6 | * This code is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Affero General Public License, version 3, 8 | * as published by the Free Software Foundation. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU Affero General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Affero General Public License, version 3, 16 | * along with this program. If not, see 17 | */ 18 | 19 | 20 | /* header color */ 21 | /* this is the main brand color */ 22 | #body-user #header, 23 | #body-settings #header, 24 | #body-public #header { 25 | background-color: #0f70bd; 26 | } 27 | 28 | /* log in screen background color */ 29 | /* gradient of the header color and a brighter shade */ 30 | /* can also be a flat color or an image */ 31 | #body-login { 32 | background: #0f70bd; /* Old browsers */ 33 | background: -moz-linear-gradient(top, #0f70bd 0%, #666768 100%); /* FF3.6+ */ 34 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#0f70bd), color-stop(100%,#666768)); /* Chrome,Safari4+ */ 35 | background: -webkit-linear-gradient(top, #0f70bd 0%,#666768 100%); /* Chrome10+,Safari5.1+ */ 36 | background: -o-linear-gradient(top, #0f70bd 0%,#666768 100%); /* Opera11.10+ */ 37 | background: -ms-linear-gradient(top, #0f70bd 0%,#666768 100%); /* IE10+ */ 38 | background: linear-gradient(top, #0f70bd 0%,#666768 100%); /* W3C */ 39 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#0f70bd', endColorstr='#666768',GradientType=0 ); /* IE6-9 */ 40 | } 41 | 42 | /* hide on small screens */ 43 | @media only screen and (max-width: 767px) { 44 | #body-user #logo-claim { 45 | display: none !important; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /owncloud/kopano/core/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kopano-dev/kopano-docker/9c5e0c9c2f250c3a02423946712671069318fefe/owncloud/kopano/core/img/favicon.ico -------------------------------------------------------------------------------- /owncloud/kopano/defaults.php: -------------------------------------------------------------------------------- 1 | 4 | * @author Jan-Christoph Borchardt, http://jancborchardt.net 5 | * @copyright Copyright (c) 2018, ownCloud GmbH 6 | * @license AGPL-3.0 7 | * 8 | * This code is free software: you can redistribute it and/or modify 9 | * it under the terms of the GNU Affero General Public License, version 3, 10 | * as published by the Free Software Foundation. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Affero General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Affero General Public License, version 3, 18 | * along with this program. If not, see 19 | */ 20 | 21 | class OC_Theme { 22 | 23 | /** 24 | * Returns the title 25 | * @return string title 26 | */ 27 | public function getTitle() { 28 | return 'ownCloud powered by Kopano'; 29 | } 30 | 31 | /** 32 | * Returns mail header color 33 | * @return string 34 | */ 35 | public function getMailHeaderColor() { 36 | return '#0f70bd'; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /owncloud/owncloud-phoenix.yml: -------------------------------------------------------------------------------- 1 | # This is for the moment only for testing purposes. Starts owncloud with the phoenix ui (available from /files) and the owncloud openid component (not yet public). 2 | # Both parts need to be extracted into the owncloud directory 3 | # TODO when this is final, these parts should be part of the owncloud docker image (maybe just need to be enabled as apps) 4 | version: "3.5" 5 | services: 6 | owncloud: 7 | depends_on: 8 | - kopano_konnect 9 | volumes: 10 | - ./owncloud/99-oidc.sh:/etc/owncloud.d/99-oidc.sh 11 | - ./owncloud/openidconnect/:/mnt/data/apps/openidconnect/ 12 | - ./owncloud/phoenix/:/mnt/data/apps/phoenix/ 13 | - ./owncloud/config.json:/mnt/data/apps/phoenix/config.json 14 | web: 15 | volumes: 16 | - ./owncloud/phoenix/:/var/www/files/ 17 | - ./owncloud/config.json:/var/www/files/config.json 18 | -------------------------------------------------------------------------------- /owncloud/owncloud.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -euo pipefail 4 | IFS=$'\n\t' 5 | 6 | if ! command -v reg > /dev/null; then 7 | echo "Please install reg to list available tags. You can only press enter when being asked for a tag." 8 | fi 9 | 10 | if [ ! -e ../.env ]; then 11 | echo "please run setup.sh first" 12 | exit 1 13 | fi 14 | 15 | # this is a kind of ugly hack to be able to source the env file 16 | # this is sadly needed since postfix in https://github.com/tomav/docker-mailserver/ cannot deal with quoted values 17 | tmpfile=$(mktemp /tmp/kopano-docker-env.XXXXXX) 18 | cp ../.env "$tmpfile" 19 | sed -i '/LDAP_QUERY_FILTER/s/^/#/g' "$tmpfile" 20 | sed -i '/SASLAUTHD_LDAP_FILTER/s/^/#/g' "$tmpfile" 21 | sed -i '/KCUNCOMMENT_LDAP_1/s/^/#/g' "$tmpfile" 22 | sed -i '/KCCOMMENT_LDAP_1/s/^/#/g' "$tmpfile" 23 | 24 | # shellcheck disable=SC1090 25 | source "$tmpfile" 26 | 27 | fqdn_to_dn() { 28 | printf 'dc=%s' "$1" | sed -E 's/\./,dc=/g' 29 | } 30 | 31 | random_string() { 32 | hexdump -n 16 -v -e '/1 "%02X"' /dev/urandom 33 | } 34 | 35 | docker_tag_search() { 36 | image="$1" 37 | results=$(reg tags "$image" 2> /dev/null) 38 | echo "$results" | xargs -n1 | sort --version-sort -ru 39 | } 40 | 41 | # function from https://stackoverflow.com/a/42790579/4754613 42 | selectWithDefault() { 43 | 44 | local item i=0 numItems=$# 45 | 46 | # Print numbered menu items, based on the arguments passed. 47 | for item; do # Short for: for item in "$@"; do 48 | printf '%s\n' "$((++i))) $item" 49 | done >&2 # Print to stderr, as `select` does. 50 | 51 | # Prompt the user for the index of the desired item. 52 | while :; do 53 | printf %s "${PS3-#? }" >&2 # Print the prompt string to stderr, as `select` does. 54 | read -r index 55 | # Make sure that the input is either empty or that a valid index was entered. 56 | [[ -z $index ]] && break # empty input 57 | (( index >= 1 && index <= numItems )) 2>/dev/null || { echo "Invalid selection. Please try again." >&2; continue; } 58 | break 59 | done 60 | 61 | # Output the selected item, if any. 62 | [[ -n $index ]] && printf %s "${@: index:1}" 63 | } 64 | 65 | update_env_file() { 66 | varname="$1" 67 | varvalue="$2" 68 | if ! grep -q "$varname" ../.env; then 69 | echo "$varname=$varvalue" >> ../.env 70 | else 71 | sed -i "/$varname/c $varname=$varvalue" ../.env 72 | fi 73 | } 74 | 75 | tag_question() { 76 | containername="$1" 77 | value_default="$2" 78 | description="$3" 79 | echo "Which tag do you want to use for $description? [$value_default]" 80 | echo "Available tags in $containername: " 81 | set +e # do not exit when new_value is empty 82 | # shellcheck disable=SC2046 83 | new_value=$(selectWithDefault $(docker_tag_search "$containername")) 84 | set -e 85 | return_value=${new_value:-$value_default} 86 | } 87 | 88 | tag_question owncloud/server "${OWNCLOUD_VERSION:-latest}" "Owncloud" 89 | update_env_file OWNCLOUD_VERSION "$return_value" 90 | update_env_file OWNCLOUD_DB_USERNAME owncloud 91 | update_env_file OWNCLOUD_DB_PASSWORD "$(random_string)" 92 | update_env_file OWNCLOUD_ADMIN_USERNAME admin 93 | update_env_file OWNCLOUD_ADMIN_PASSWORD "$(random_string)" 94 | update_env_file MARIADB_ROOT_PASSWORD "$(random_string)" 95 | 96 | echo "Setup complete" 97 | 98 | if [ -e "$tmpfile" ]; then 99 | rm "$tmpfile" 100 | fi 101 | -------------------------------------------------------------------------------- /owncloud/owncloud.yml: -------------------------------------------------------------------------------- 1 | # based on https://github.com/owncloud/docs/blob/4a04cd16a10a853bfab630e8a6450f722ac6ea86/modules/admin_manual/examples/installation/docker/docker-compose.yml 2 | version: "3.5" 3 | 4 | volumes: 5 | oc_files: 6 | oc_mysql: 7 | oc_backup: 8 | oc_redis: 9 | 10 | services: 11 | owncloud: 12 | image: owncloud/server:${OWNCLOUD_VERSION:-latest} 13 | restart: always 14 | depends_on: 15 | - oc_db 16 | - oc_redis 17 | - ldap 18 | - web 19 | environment: 20 | - OWNCLOUD_DOMAIN=${FQDN} 21 | - OWNCLOUD_DB_TYPE=mysql 22 | - OWNCLOUD_DB_NAME=owncloud 23 | - OWNCLOUD_DB_USERNAME=${OWNCLOUD_DB_USERNAME} 24 | - OWNCLOUD_DB_PASSWORD=${OWNCLOUD_DB_PASSWORD} 25 | - OWNCLOUD_DB_HOST=oc_db 26 | - OWNCLOUD_ADMIN_USERNAME=${OWNCLOUD_ADMIN_USERNAME} 27 | - OWNCLOUD_ADMIN_PASSWORD=${OWNCLOUD_ADMIN_PASSWORD} 28 | - OWNCLOUD_MYSQL_UTF8MB4=true 29 | - OWNCLOUD_REDIS_ENABLED=true 30 | - OWNCLOUD_REDIS_HOST=oc_redis 31 | - OWNCLOUD_SUB_URL=/owncloud 32 | - LDAP_SERVER=${LDAP_SERVER} 33 | - LDAP_SEARCH_BASE=${LDAP_SEARCH_BASE} 34 | - LDAP_BIND_DN=${LDAP_BIND_DN} 35 | - LDAP_BIND_PW=${LDAP_BIND_PW} 36 | healthcheck: 37 | test: ["CMD", "/usr/bin/healthcheck"] 38 | interval: 30s 39 | timeout: 10s 40 | retries: 5 41 | volumes: 42 | - oc_files:/mnt/data 43 | - ./owncloud/99-ldap.sh:/etc/owncloud.d/99-ldap.sh 44 | - ./owncloud/kopano/:/mnt/data/apps/kopano/ 45 | networks: 46 | - web-net 47 | - owncloud-net 48 | - ldap-net 49 | 50 | oc_db: 51 | image: webhippie/mariadb:latest 52 | restart: always 53 | environment: 54 | - MARIADB_ROOT_PASSWORD=${MARIADB_ROOT_PASSWORD} 55 | - MARIADB_USERNAME=${OWNCLOUD_DB_USERNAME} 56 | - MARIADB_PASSWORD=${OWNCLOUD_DB_PASSWORD} 57 | - MARIADB_DATABASE=owncloud 58 | - MARIADB_MAX_ALLOWED_PACKET=128M 59 | - MARIADB_INNODB_LOG_FILE_SIZE=64M 60 | healthcheck: 61 | test: ["CMD", "/usr/bin/healthcheck"] 62 | interval: 30s 63 | timeout: 10s 64 | retries: 5 65 | volumes: 66 | - oc_mysql:/var/lib/mysql 67 | - oc_backup:/var/lib/backup 68 | networks: 69 | - owncloud-net 70 | 71 | oc_redis: 72 | image: webhippie/redis:latest 73 | restart: always 74 | environment: 75 | - REDIS_DATABASES=1 76 | healthcheck: 77 | test: ["CMD", "/usr/bin/healthcheck"] 78 | interval: 30s 79 | timeout: 10s 80 | retries: 5 81 | volumes: 82 | - oc_redis:/var/lib/redis 83 | networks: 84 | - owncloud-net 85 | 86 | networks: 87 | owncloud-net: 88 | driver: bridge 89 | -------------------------------------------------------------------------------- /php/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1.0-experimental 2 | ARG docker_repo=zokradonh 3 | FROM ${docker_repo}/kopano_base 4 | 5 | ARG ADDITIONAL_KOPANO_PACKAGES="" 6 | ARG DOWNLOAD_COMMUNITY_PACKAGES=1 7 | ARG KOPANO_REPOSITORY_FLAGS="trusted=yes" 8 | ARG DEBIAN_FRONTEND=noninteractive 9 | ARG KOPANO_CORE_REPOSITORY_URL="file:/kopano/repo/core" 10 | ARG KOPANO_CORE_VERSION=newest 11 | ARG KOPANO_KAPPS_REPOSITORY_URL="file:/kopano/repo/kapps" 12 | ARG KOPANO_KAPPS_VERSION=newest 13 | 14 | ENV \ 15 | ADDITIONAL_KOPANO_PACKAGES=$ADDITIONAL_KOPANO_PACKAGES \ 16 | DOWNLOAD_COMMUNITY_PACKAGES=$DOWNLOAD_COMMUNITY_PACKAGES \ 17 | KOPANO_CORE_REPOSITORY_URL=$KOPANO_CORE_REPOSITORY_URL \ 18 | KOPANO_CORE_VERSION=$KOPANO_CORE_VERSION \ 19 | KOPANO_REPOSITORY_FLAGS=$KOPANO_REPOSITORY_FLAGS 20 | 21 | LABEL maintainer=az@zok.xyz \ 22 | org.label-schema.name="Kopano php container" \ 23 | org.label-schema.description="Base container for running php based applications based on Kopano Groupware Core" \ 24 | org.label-schema.url="https://kopano.io" \ 25 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 26 | org.label-schema.version=$KOPANO_CORE_VERSION \ 27 | org.label-schema.schema-version="1.0" 28 | 29 | SHELL ["/bin/bash", "-o", "pipefail", "-c"] 30 | 31 | # add install common php dependencies 32 | RUN --mount=type=secret,id=repocred,target=/etc/apt/auth.conf.d/kopano.conf \ 33 | # apt key for this repo has already been installed in base 34 | echo "deb [${KOPANO_REPOSITORY_FLAGS}] ${KOPANO_CORE_REPOSITORY_URL} ./" > /etc/apt/sources.list.d/kopano.list; \ 35 | echo "deb [${KOPANO_REPOSITORY_FLAGS}] ${KOPANO_KAPPS_REPOSITORY_URL} ./" >> /etc/apt/sources.list.d/kopano.list; \ 36 | # install 37 | set -x && \ 38 | apt-get update && apt-get install -y --no-install-recommends \ 39 | ca-certificates \ 40 | crudini \ 41 | kopano-kwebd \ 42 | php-fpm \ 43 | php7-mapi \ 44 | ${ADDITIONAL_KOPANO_PACKAGES} \ 45 | && rm -rf /var/cache/apt /var/lib/apt/lists 46 | 47 | # configure php-fpm 48 | RUN \ 49 | mkdir -p /run/php && chown www-data:www-data /run/php && \ 50 | crudini --set /etc/php/7.3/fpm/php.ini Session session.save_path /run/sessions 51 | 52 | EXPOSE 9080/tcp 53 | 54 | COPY php-fpm.conf /etc/php/7.3/fpm/pool.d/ 55 | COPY start-helper.sh /kopano/start-helper.sh 56 | COPY kweb.cfg /etc/kweb.cfg 57 | 58 | ARG VCS_REF 59 | LABEL org.label-schema.vcs-ref=$VCS_REF -------------------------------------------------------------------------------- /php/README.md: -------------------------------------------------------------------------------- 1 | # Kopano PHP image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_php.svg)](https://microbadger.com/images/zokradonh/kopano_php "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_php.svg)](https://microbadger.com/images/zokradonh/kopano_php "Microbadger version") 4 | 5 | Common base image for php based Kopano containers. 6 | 7 | ## Configuration through environment variables 8 | 9 | Any additional configuration should be done through environment variables and not done in the actual container. The images working with configuration files (e.g. `kopano_core`, `kopano_webapp`, `kopano_meet`) have a mechanism built in to translate env variables into configuration files. For services that can directly work with env variables (e.g. `kopano_konnect`, ´kopano_kwmserver´) these can be specified directly. Please check the individual `README.md` files for further instructions. 10 | 11 | Examples of env variables: 12 | 13 | ```bash 14 | KCCONF_WEBAPP_CLIENT_TIMEOUT=3600 15 | ^ ^ ^ ^ 16 | | | | | 17 | General prefix| | 18 | | | | 19 | Special value to signal the change should go into config.php belonging to WebApp 20 | | | 21 | Name of the configuration option in the configuration file 22 | | 23 | Value of the configuration option 24 | 25 | KCCONF_WEBAPPPLUGIN_MDM_PLUGIN_MDM_USER_DEFAULT_ENABLE_MDM=true 26 | ^ ^ ^ ^ ^ 27 | | | | | | 28 | General prefix | | | 29 | | | | | 30 | Special value to signal the change should go into config-$identifier.php (located in /etc/kopano/webapp) 31 | | | | 32 | Identifier for the configuration file (config-$identifier.php) 33 | | | 34 | Name of the configuration option in the configuration file 35 | | 36 | Value of the configuration option 37 | ``` 38 | -------------------------------------------------------------------------------- /php/kweb.cfg: -------------------------------------------------------------------------------- 1 | :9080 { 2 | log stdout 3 | errors stderr 4 | 5 | # healthcheck 6 | status 200 /status 7 | } 8 | -------------------------------------------------------------------------------- /php/php-fpm.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | ;output errors on stderr 3 | error_log = /proc/self/fd/2 4 | -------------------------------------------------------------------------------- /php/start-helper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | php_cfg_gen() { 4 | local cfg_file="$1" 5 | local cfg_setting="$2" 6 | local cfg_value="$3" 7 | if [ -e "$cfg_file" ]; then 8 | echo "Setting $cfg_setting = $cfg_value in $cfg_file" 9 | if ! grep -q "$cfg_setting" "$cfg_file"; then 10 | echo "WARNING: Config option $cfg_setting not found in $cfg_file! You may have misspelled the confing setting." 11 | echo "define('$cfg_setting', '$cfg_value');" >> "$cfg_file" 12 | cat "$cfg_file" 13 | return 14 | fi 15 | case $cfg_value in 16 | # TODO stop after the first match (currently matching incl. closing quote) 17 | true|TRUE|false|FALSE) 18 | sed -ri "s#(\s*define).+(${cfg_setting}\x22|${cfg_setting}\x27).+#\tdefine(\x22${cfg_setting}\x22, ${cfg_value}\);#g" "$cfg_file" 19 | ;; 20 | *) 21 | sed -ri "s#(\s*define).+(${cfg_setting}\x22|${cfg_setting}\x27).+#\tdefine(\x22${cfg_setting}\x22, \x22${cfg_value}\x22\);#g" "$cfg_file" 22 | ;; 23 | esac 24 | else 25 | echo "Error: Config file $cfg_file not found. Plugin not installed?" 26 | local dir 27 | dir=$(dirname "$cfg_file") 28 | ls -la "$dir" 29 | exit 1 30 | fi 31 | } 32 | -------------------------------------------------------------------------------- /playground/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.11 as builder 2 | 3 | RUN apk add --no-cache \ 4 | git make 5 | RUN mkdir -p /web/oidc-playground /web/kapi-playground 6 | RUN git clone https://stash.kopano.io/scm/~seisenmann/oidc-playground.git 7 | RUN mv oidc-playground/www/* /web/oidc-playground 8 | RUN git clone https://stash.kopano.io/scm/kc/kapi.git 9 | RUN mv kapi/examples/* /web/kapi-playground 10 | WORKDIR /web/kapi-playground 11 | RUN rm Makefile && ln -s oidc-client-example.html index.html 12 | 13 | FROM halverneus/static-file-server:v1.8.0 14 | 15 | ARG CODE_VERSION 16 | 17 | ENV PORT 8888 18 | 19 | LABEL maintainer=az@zok.xyz \ 20 | org.label-schema.name="Kopano Playground" \ 21 | org.label-schema.description="Container for running Kopano playground applications for Kapi and OIDC" \ 22 | org.label-schema.url="https://kopano.io" \ 23 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 24 | org.label-schema.schema-version="1.0" 25 | 26 | COPY --from=builder /web /web 27 | 28 | ARG VCS_REF 29 | LABEL org.label-schema.vcs-ref=$VCS_REF 30 | -------------------------------------------------------------------------------- /playground/README.md: -------------------------------------------------------------------------------- 1 | # Kopano Kapi Playground and OIDC Playground image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_playground.svg)](https://microbadger.com/images/zokradonh/kopano_playground "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_playground.svg)](https://microbadger.com/images/zokradonh/kopano_playground "Microbadger version") 4 | 5 | This project includes a Docker container to easily inspect the data returned by the Kopano Rest API (Kapi), as well as the OpenID (Connect) Service Provider. 6 | 7 | ## How to use the Kopano Playground? 8 | 9 | 1. Add the `playground.yml` to the `COMPOSE_FILE` variable in your `.env` file. 10 | 11 | Example: 12 | 13 | ```bash 14 | COMPOSE_FILE=docker-compose.yml:docker-compose.ports.yml:playground/playground.yml 15 | ``` 16 | 17 | 2. Run `docker-compose up -d`. 18 | 19 | To explore these applications you need to pass the URL of the "Issuer" when opening these. For the Kapi Playground this would for example be `https://kopano.demo/kapi-playground/?iss=https://kopano.demo`. For the OIDC Playground it would be `https://kopano.demo/oidc-playground/?discovery_uri=https://kopano.demo/.well-known/openid-configuration&discovery=auto`. 20 | -------------------------------------------------------------------------------- /playground/playground.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | kopano_playground: 5 | image: ${docker_repo:-zokradonh}/kopano_playground 6 | restart: unless-stopped 7 | depends_on: 8 | - kopano_kapi 9 | - kopano_konnect 10 | networks: 11 | - kopano-net 12 | - web-net 13 | -------------------------------------------------------------------------------- /python/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1.0-experimental 2 | ARG docker_repo=zokradonh 3 | FROM ${docker_repo}/kopano_base 4 | 5 | ARG ADDITIONAL_KOPANO_PACKAGES="" 6 | ARG DOWNLOAD_COMMUNITY_PACKAGES=1 7 | ARG KOPANO_REPOSITORY_FLAGS="trusted=yes" 8 | ARG DEBIAN_FRONTEND=noninteractive 9 | ARG KOPANO_CORE_REPOSITORY_URL="file:/kopano/repo/core" 10 | ARG KOPANO_CORE_VERSION=newest 11 | 12 | ENV \ 13 | ADDITIONAL_KOPANO_PACKAGES=$ADDITIONAL_KOPANO_PACKAGES \ 14 | DOWNLOAD_COMMUNITY_PACKAGES=$DOWNLOAD_COMMUNITY_PACKAGES \ 15 | KOPANO_CORE_REPOSITORY_URL=$KOPANO_CORE_REPOSITORY_URL \ 16 | KOPANO_CORE_VERSION=$KOPANO_CORE_VERSION \ 17 | KOPANO_REPOSITORY_FLAGS=$KOPANO_REPOSITORY_FLAGS 18 | 19 | LABEL maintainer=az@zok.xyz \ 20 | org.label-schema.name="Kopano Python container" \ 21 | org.label-schema.description="Container for running python based applications for Kopano Groupware Core" \ 22 | org.label-schema.url="https://kopano.io" \ 23 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 24 | org.label-schema.version=$KOPANO_CORE_VERSION \ 25 | org.label-schema.schema-version="1.0" 26 | 27 | SHELL ["/bin/bash", "-o", "pipefail", "-c"] 28 | 29 | RUN --mount=type=secret,id=repocred,target=/etc/apt/auth.conf.d/kopano.conf \ 30 | echo "deb [${KOPANO_REPOSITORY_FLAGS}] ${KOPANO_CORE_REPOSITORY_URL} ./" > /etc/apt/sources.list.d/kopano.list; \ 31 | # install 32 | set -x && \ 33 | apt-get update && apt-get install -y --no-install-recommends \ 34 | python3-kopano \ 35 | ${ADDITIONAL_KOPANO_PACKAGES} \ 36 | && rm -rf /var/cache/apt /var/lib/apt/lists 37 | 38 | ARG VCS_REF 39 | LABEL org.label-schema.vcs-ref=$VCS_REF -------------------------------------------------------------------------------- /python/README.md: -------------------------------------------------------------------------------- 1 | # Kopano Python image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_python.svg)](https://microbadger.com/images/zokradonh/kopano_python "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_python.svg)](https://microbadger.com/images/zokradonh/kopano_python "Microbadger version") 4 | 5 | Small image for components based on python-kopano. 6 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /scheduler/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker:19.03 2 | 3 | ENV \ 4 | DOCKERIZE_VERSION=v0.6.1 \ 5 | GOSS_VERSION=v0.3.11 \ 6 | SUPERCRONIC_VERSION=0.1.9 7 | 8 | LABEL maintainer=az@zok.xyz \ 9 | org.label-schema.name="Kopano scheduler container" \ 10 | org.label-schema.description="Helper container for running tasks within the Kopano stack" \ 11 | org.label-schema.url="https://kopano.io" \ 12 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 13 | org.label-schema.version=$SUPERCRONIC_VERSION \ 14 | org.label-schema.schema-version="1.0" 15 | 16 | RUN apk --no-cache add bash curl ca-certificates 17 | 18 | RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 19 | && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 20 | && rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz 21 | 22 | RUN wget https://github.com/aelsabbahy/goss/releases/download/$GOSS_VERSION/goss-linux-amd64 -O /usr/local/bin/goss \ 23 | && chmod +x /usr/local/bin/goss \ 24 | && goss --version 25 | 26 | RUN wget https://github.com/aptible/supercronic/releases/download/v${SUPERCRONIC_VERSION}/supercronic-linux-amd64 \ 27 | -O /usr/local/bin/supercronic \ 28 | && chmod +x /usr/local/bin/supercronic 29 | 30 | # Setup timezone 31 | ENV TZ=UTC 32 | RUN ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime 33 | RUN printf '%s\n' "$TZ" > /etc/timezone 34 | 35 | COPY start.sh /usr/local/bin/ 36 | COPY goss.yaml /goss/ 37 | 38 | CMD ["start.sh"] 39 | 40 | # TODO interval does not only define how often the healtcheck is run, but also how long to wait for the first check after startup 41 | HEALTHCHECK --interval=60m --timeout=15s \ 42 | CMD goss -g /goss/goss.yaml validate 43 | 44 | ARG VCS_REF 45 | LABEL org.label-schema.vcs-ref=$VCS_REF -------------------------------------------------------------------------------- /scheduler/README.md: -------------------------------------------------------------------------------- 1 | # Kopano Scheduler image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_scheduler.svg)](https://microbadger.com/images/zokradonh/kopano_scheduler "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_scheduler.svg)](https://microbadger.com/images/zokradonh/kopano_scheduler "Microbadger version") 4 | 5 | Service to carry out repeating tasks within the Kopano environment. Takes care of initial user sync on startup and creating the public store. 6 | 7 | ## Recurring tasks and maintenance tasks within Kopano 8 | 9 | There are certain tasks within Kopano that either need to be executed once (like creating the public store when starting a new environment for the first time) or on a regular base (like syncing the internal user list with and external ldap tree). For convenience this project includes a "scheduler" container that will take care of this and that can be dynamically configured through env variables. 10 | 11 | The container knows two kinds of cron jobs (the crontab syntax is used for actual jobs): 12 | 13 | - `CRON_ZPUSHGAB=0 22 * * * docker exec kopano_zpush z-push-gabsync -a sync` 14 | - Jobs prefixed with `CRON_` are executed once at container startup (and container startup will fail if one of the jobs fail) and then at the scheduled time. 15 | - `CRONDELAYED_KBACKUP=30 1 * * * docker run --rm -it zokradonh/kopano_utils kopano-backup -h` 16 | - Jobs prefixed with `CRONDELAYED_` are only executed at the scheduled time. 17 | 18 | Instead of using the internal scheduler one can also just use an existing scheduler (cron on the docker host for example) to execute these tasks. 19 | -------------------------------------------------------------------------------- /scheduler/commander.yaml: -------------------------------------------------------------------------------- 1 | tests: 2 | check mailbox language: # this needs a running kopano-server and can can therefore not be executed in that container directly 3 | command: "docker exec kopano_server kopano-storeadm -C -n user10; docker exec kopano_server show-folders.py --user user10" 4 | exit-code: 0 5 | stdout: 6 | contains: 7 | - "Inbox" 8 | - "Drafts" 9 | check if store exists: 10 | command: "docker exec kopano_server kopano-admin --details user10" 11 | exit-code: 0 12 | stdout: 13 | not-contains: 14 | - "WARNING: Unable to get user store entry id. User possibly has no store." 15 | check mailbox language german: # this needs a running kopano-server and can can therefore not be executed in that container directly 16 | command: "docker exec kopano_server kopano-storeadm -D -n user11; docker exec kopano_server kopano-storeadm -C -l de_DE -n user11; docker exec kopano_server show-folders.py --user user11" 17 | exit-code: 0 18 | stdout: 19 | not-contains: 20 | - "Inbox" 21 | - "Drafts" 22 | contains: 23 | - "Posteingang" 24 | check mailbox language dutch: # this needs a running kopano-server and can can therefore not be executed in that container directly 25 | command: "docker exec kopano_server kopano-storeadm -D -n user12; docker exec kopano_server kopano-storeadm -C -l nl_NL -n user12; docker exec kopano_server show-folders.py --user user12" 26 | exit-code: 0 27 | stdout: 28 | not-contains: 29 | - "Inbox" 30 | - "Drafts" 31 | contains: 32 | - "Postvak IN" 33 | test renaming of folders: 34 | command: docker exec kopano_server env KCCONF_ADMIN_DEFAULT_STORE_LOCALE=de_DE.UTF-8 /usr/bin/python3 /kopano/server.py && docker exec kopano_server kopano-storeadm -Y -n user13 35 | exit-code: 0 36 | stdout: 37 | not-contains: 38 | - "Inbox" 39 | - "Drafts" 40 | contains: 41 | - "Posteingang" 42 | stderr: 43 | contains: 44 | - The -l option was not specified; "de_DE.UTF-8" will be used as language 45 | config: 46 | env: 47 | PATH: ${PATH} 48 | -------------------------------------------------------------------------------- /scheduler/goss.yaml: -------------------------------------------------------------------------------- 1 | command: 2 | kill -SIGUSR2 $(pidof supercronic): 3 | exit-status: 0 4 | stdout: [] 5 | stderr: [] 6 | timeout: 10000 7 | process: 8 | supercronic: 9 | running: true 10 | -------------------------------------------------------------------------------- /scheduler/goss_wait.yaml: -------------------------------------------------------------------------------- 1 | process: 2 | supercronic: 3 | running: true 4 | -------------------------------------------------------------------------------- /scheduler/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eo pipefail 4 | 5 | cronfile=/tmp/crontab 6 | 7 | # purge existing entries from crontab 8 | true > "$cronfile" 9 | 10 | for cronvar in ${!CRON_*}; do 11 | cronvalue=${!cronvar} 12 | echo "Adding $cronvalue to crontab" 13 | echo "$cronvalue" >> "$cronfile" 14 | done 15 | 16 | for cronvar in ${!CRONDELAYED_*}; do 17 | cronvalue=${!cronvar} 18 | echo "Adding $cronvalue to crontab (delayed)" 19 | echo "$cronvalue" >> "$cronfile" 20 | done 21 | 22 | # wait for kopano_server statup to run one-off commands 23 | dockerize \ 24 | -wait tcp://kopano_server:236 \ 25 | -timeout 360s 26 | 27 | echo "Creating public store" 28 | docker exec kopano_server kopano-storeadm -h default: -P || true 29 | 30 | echo "Running sheduled cron jobs once" 31 | for cronvar in ${!CRON_*}; do 32 | cronvalue=${!cronvar} 33 | croncommand=$(echo "$cronvalue" | cut -d ' ' -f 6-) 34 | echo "Running: $croncommand" 35 | $croncommand 36 | done 37 | 38 | supercronic -test $cronfile 39 | exec supercronic $cronfile 40 | -------------------------------------------------------------------------------- /spamd-extras/README.md: -------------------------------------------------------------------------------- 1 | # kopano-spamd extras for kopano-docker 2 | 3 | This directory contains a compose file including optional containers to enable learning spam to be used with the [SpamAssassin](https://spamassassin.apache.org/) bayes filter. 4 | 5 | ## How to use this compose file? 6 | 7 | 1. Add the `spamd-extras.yml` to the `COMPOSE_FILE` variable in your `.env` file. 8 | 9 | Example: 10 | 11 | ```bash 12 | COMPOSE_FILE=docker-compose.yml:docker-compose.ports.yml:spamd-extras/spamd-extras.yml 13 | ``` 14 | 15 | 2. Run `docker-compose up -d`. 16 | 17 | 18 | ## kopano-spamd 19 | 20 | After startup there will be a new service `kopano-spamd` which will persist mails that are moved to `Junk` to a folder named `spam` inside the `kopanospamd` volume. 21 | Likewise mails that are moved from the `Junk` back to `Inbox` are persisted in `ham`. Both folders indicate mails that should be trained as either being ham or spam. 22 | 23 | The `kopano-scheduler` container is extended to run the training inside the `mail` docker container at about 4am with training results being picked up by SpamAssassin 24 | automatically. You can check the docker logs of the scheduler for the results of each run. 25 | 26 | While already trained files can be deleted immediately after each training run, there is no cleanup provided here. The `kopanospamd` volume will therefore grow over time. 27 | 28 | For the bayes filter to start working you will need to train at least 200 mails of each ham and spam. To create a set of initial data you can use the Kopano WebApp 29 | by selecting mails and using the `Export as` function to create a zip file of those mails and put them into the appropriate folder. 30 | 31 | Read more about how to create effective training data here: https://spamassassin.apache.org/full/3.4.x/doc/sa-learn.html#EFFECTIVE-TRAINING 32 | -------------------------------------------------------------------------------- /spamd-extras/spamd-extras.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | kopano_spamd: 5 | image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest} 6 | read_only: true 7 | restart: unless-stopped 8 | container_name: ${COMPOSE_PROJECT_NAME}_spamd 9 | depends_on: 10 | - kopano_server 11 | - mail 12 | volumes: 13 | - /etc/machine-id:/etc/machine-id 14 | - /etc/machine-id:/var/lib/dbus/machine-id 15 | - kopanosocket/:/run/kopano 16 | - kopanossl/:/kopano/ssl 17 | - kopanospamd/:/var/lib/kopano/spamd 18 | environment: 19 | - SERVICE_TO_START=spamd 20 | - TZ=${TZ} 21 | - KCCONF_SPAMD_SA_GROUP=kopano 22 | networks: 23 | - kopano-net 24 | tmpfs: 25 | - /tmp 26 | 27 | mail: 28 | volumes: 29 | - kopanospamd/:/var/lib/kopano/spamd 30 | 31 | kopano_scheduler: 32 | environment: 33 | - CRONDELAYED_LEARN_HAM=0 4 * * * docker exec kopano_mail sa-learn --spam /var/lib/kopano/spamd/spam --dbpath /var/mail-state/lib-amavis/.spamassassin 34 | - CRONDELAYED_LEARN_SPAM=15 4 * * * docker exec kopano_mail sa-learn --ham /var/lib/kopano/spamd/ham --dbpath /var/mail-state/lib-amavis/.spamassassin 35 | 36 | volumes: 37 | kopanospamd: 38 | -------------------------------------------------------------------------------- /ssl/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.11 2 | 3 | ENV CODE_VERSION=1.2.0 \ 4 | PKI_ROOT=/kopano/easypki \ 5 | PKI_ORGANIZATION="Internal Kopano System" \ 6 | PKI_COUNTRY=DE 7 | 8 | LABEL maintainer=az@zok.xyz \ 9 | org.label-schema.name="Kopano SSL container" \ 10 | org.label-schema.description="Helper Container for carrying out ssl related activities for the Kopano stack." \ 11 | org.label-schema.url="https://kopano.io" \ 12 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 13 | org.label-schema.version=$CODE_VERSION \ 14 | org.label-schema.schema-version="1.0" 15 | 16 | RUN mkdir -p /kopano/easypki /kopano/ssl /kopano/ssl/clients 17 | WORKDIR /kopano/easypki 18 | 19 | RUN apk add --no-cache \ 20 | easypki \ 21 | openssl 22 | 23 | COPY start.sh /start.sh 24 | 25 | RUN chmod a+x /start.sh 26 | 27 | CMD ["/start.sh"] 28 | 29 | ARG VCS_REF 30 | LABEL org.label-schema.vcs-ref=$VCS_REF -------------------------------------------------------------------------------- /ssl/README.md: -------------------------------------------------------------------------------- 1 | # Kopano SSL image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_ssl.svg)](https://microbadger.com/images/zokradonh/kopano_ssl "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_ssl.svg)](https://microbadger.com/images/zokradonh/kopano_ssl "Microbadger version") 4 | 5 | Image to create certificates for all containers. These certificates are self signed and are used for internal Kopano component communication. 6 | -------------------------------------------------------------------------------- /ssl/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | mkdir -p /kopano/ssl/clients/ 4 | 5 | set -euo 6 | 7 | # clean out any potential port numbers 8 | FQDN=${FQDN%:*} 9 | 10 | # create files so that konnect can write to it 11 | touch /kopano/ssl/konnectd-identifier-registration.yaml /kopano/ssl/ecparam.pem /kopano/ssl/meet-kwmserver.pem 12 | # chown to the numerical representation of nobody/nogroup 13 | chown 65534:65534 /kopano/ssl/konnectd-identifier-registration.yaml /kopano/ssl/ecparam.pem /kopano/ssl/meet-kwmserver.pem 14 | 15 | 16 | if [ ! -f /kopano/ssl/ca.pem ]; then 17 | # https://github.com/google/easypki 18 | echo "Creating CA certificate..." 19 | easypki create --filename internalca --organizational-unit primary --expire 3650 --ca "Internal Kopano System" 20 | 21 | cp /kopano/easypki/internalca/certs/internalca.crt /kopano/ssl/ca.pem.tmp 22 | mv /kopano/ssl/ca.pem.tmp /kopano/ssl/ca.pem 23 | 24 | for s in kopano_server kopano_server_2 kopano_dagent kopano_monitor kopano_search kopano_spooler kopano_webapp admin; do 25 | if [ ! -f /kopano/ssl/$s.pem ]; then 26 | echo "Creating $s certificate..." 27 | easypki create --ca-name internalca --organizational-unit $s --expire 3650 --dns $s --dns "$FQDN" $s 28 | cp /kopano/easypki/internalca/keys/$s.key /kopano/ssl/$s.pem.tmp 29 | cat /kopano/easypki/internalca/certs/$s.crt >> /kopano/ssl/$s.pem.tmp 30 | openssl x509 -in /kopano/easypki/internalca/certs/$s.crt -pubkey -noout > /kopano/ssl/clients/$s-public.pem.tmp 31 | mv /kopano/ssl/$s.pem.tmp /kopano/ssl/$s.pem 32 | mv /kopano/ssl/clients/$s-public.pem.tmp /kopano/ssl/clients/$s-public.pem 33 | fi 34 | done 35 | fi 36 | 37 | # Konnect - create encryption key if not already present 38 | enckey="/kopano/ssl/konnectd-encryption.key" 39 | if [ ! -f $enckey ]; then 40 | echo "Creating Konnect encryption key..." 41 | openssl rand -out $enckey.tmp 32 42 | mv $enckey.tmp $enckey 43 | fi 44 | 45 | # Konnect - create token signing key if not already present 46 | signkey="/kopano/ssl/konnectd-tokens-signing-key.pem" 47 | if [ ! -L $signkey ] && [ ! -f $signkey ]; then 48 | echo "Creating Konnect token signing key..." 49 | openssl genpkey -algorithm RSA -out $signkey.tmp -pkeyopt rsa_keygen_bits:4096 >/dev/null 2>&1 50 | chmod go+r $signkey.tmp 51 | mv $signkey.tmp $signkey 52 | fi 53 | 54 | # Kapi 55 | secretkey="/kopano/ssl/kapid-pubs-secret.key" 56 | if [ ! -f $secretkey ]; then 57 | echo "Creating Kapi secret key..." 58 | openssl rand -out $secretkey.tmp -hex 64 59 | mv $secretkey.tmp $secretkey 60 | fi 61 | 62 | echo "SSL certs:" 63 | ls -l /kopano/ssl/*.* 64 | 65 | echo "Client public keys:" 66 | ls -l /kopano/ssl/clients/* 67 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | # Place to store tests for CI 2 | -------------------------------------------------------------------------------- /tests/commander-supported.yaml: -------------------------------------------------------------------------------- 1 | tests: 2 | ./version.sh core Debian_9.0 supported final/tarballs/: 3 | exit-code: 0 4 | stdout: 5 | not-contains: 6 | - core- 7 | - Debian 8 | - amd64 9 | - tar.gz 10 | - tarballs 11 | ./version.sh core Debian_9.0 supported pre-final/tarballs/: 12 | exit-code: 0 13 | stdout: 14 | not-contains: 15 | - core- 16 | - Debian 17 | - amd64 18 | - tar.gz 19 | - tarballs 20 | ./version.sh core Debian_9.0 supported master/tarballs/: 21 | exit-code: 0 22 | stdout: 23 | not-contains: 24 | - core- 25 | - Debian 26 | - amd64 27 | - tar.gz 28 | - tarballs 29 | ./version.sh webapp Debian_9.0 supported final/tarballs/: 30 | exit-code: 0 31 | stdout: 32 | not-contains: 33 | - webapp- 34 | - Debian 35 | - amd64 36 | - tar.gz 37 | - tarballs -------------------------------------------------------------------------------- /tests/commander.yaml: -------------------------------------------------------------------------------- 1 | tests: 2 | setup with existing .env: 3 | command: ./setup.sh 4 | exit-code: 1 5 | stdout: |- 6 | Creating individual env files for containers (if they do not exist already) 7 | .env already exists with initial configuration 8 | If you want to change the configuration, please edit .env directly 9 | ./version.sh: 10 | exit-code: 0 11 | ./version.sh core: 12 | exit-code: 0 13 | stdout: 14 | not-contains: 15 | - core- 16 | - Debian 17 | - amd64 18 | - tar.gz 19 | ./version.sh webapp: 20 | exit-code: 0 21 | stdout: 22 | not-contains: 23 | - webapp- 24 | - Debian 25 | - amd64 26 | - tar.gz 27 | ./version.sh zpush: 28 | exit-code: 0 29 | stdout: 30 | not-contains: 31 | - Debian 32 | - amd64 33 | - tar.gz 34 | ./version.sh mdm: 35 | exit-code: 0 36 | stdout: 37 | not-contains: 38 | - Debian 39 | - amd64 40 | - tar.gz 41 | ./version.sh files: 42 | exit-code: 0 43 | stdout: 44 | not-contains: 45 | - Debian 46 | - amd64 47 | - tar.gz 48 | ./version.sh smime: 49 | exit-code: 0 50 | stdout: 51 | not-contains: 52 | - Debian 53 | - amd64 54 | - tar.gz 55 | download core nightly: 56 | command: ./base/test.sh core 57 | exit-code: 0 58 | stderr: 59 | not-contains: 60 | - "tar: This does not look like a tar archive" 61 | download webapp nightly: 62 | command: ./base/test.sh webapp 63 | exit-code: 0 64 | stderr: 65 | not-contains: 66 | - "tar: This does not look like a tar archive" 67 | -------------------------------------------------------------------------------- /tests/startup-test/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG docker_repo=zokradonh 2 | FROM ${docker_repo}/kopano_scheduler 3 | 4 | COPY test.sh /start.sh 5 | 6 | CMD ["/start.sh"] 7 | -------------------------------------------------------------------------------- /tests/startup-test/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ex 4 | 5 | # waits for key events in various containers 6 | # e.g. kopano_server:236 signals successful start of kopano-server process 7 | dockerize \ 8 | -wait http://kopano_konnect:8777/.well-known/openid-configuration \ 9 | -wait http://kopano_meet:9080/meet \ 10 | -wait tcp://"${KCCONF_SERVER_MYSQL_HOST}":3306 \ 11 | -wait tcp://kopano_dagent:2003 \ 12 | -wait tcp://kopano_gateway:143 \ 13 | -wait tcp://kopano_ical:8080 \ 14 | -wait tcp://kopano_kapi:8039 \ 15 | -wait tcp://kopano_kwmserver:8778 \ 16 | -wait tcp://kopano_server:236 \ 17 | -wait tcp://kopano_server:237 \ 18 | -wait tcp://kopano_webapp:9080 \ 19 | -wait tcp://kopano_zpush:9080 \ 20 | -wait tcp://web:2015 \ 21 | -timeout 120s 22 | 23 | # until goss is part of the general testsuite check goss for kopano-server here as well 24 | docker exec kopano_server goss -g /kopano/goss/server/goss.yaml validate 25 | 26 | # make sure the public store exists 27 | docker exec kopano_server kopano-storeadm -h default: -P || true 28 | 29 | docker exec kopano_server kopano-admin --sync 30 | docker exec kopano_server kopano-storeadm -O # list users without a store 31 | docker exec kopano_server kopano-admin -l 32 | docker exec kopano_zpush z-push-admin -a list 33 | docker exec kopano_zpush z-push-gabsync -a sync 34 | 35 | # will print nothing if store exists and fail if it doesn't 36 | docker exec kopano_server kopano-admin --details user1 | grep -q "^Store GUID:" 37 | -------------------------------------------------------------------------------- /tests/test-container.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | test: 5 | build: 6 | context: tests/startup-test 7 | args: 8 | docker_repo: ${docker_repo:-zokradonh} 9 | networks: 10 | - kopano-net 11 | - ldap-net 12 | - web-net 13 | volumes: 14 | - kopanodata/:/kopano/data 15 | - kopanossl/:/kopano/ssl 16 | - kopanosocket/:/run/kopano 17 | - /var/run/docker.sock:/var/run/docker.sock:ro 18 | environment: 19 | - KCCONF_SERVER_MYSQL_HOST=${MYSQL_HOST} 20 | ldap: 21 | tmpfs: 22 | - /var/lib/ldap 23 | - /etc/ldap/slapd.d 24 | db: 25 | tmpfs: 26 | - /var/lib/mysql 27 | kopano_server: 28 | cap_add: 29 | - LINUX_IMMUTABLE 30 | kopano_search: 31 | tmpfs: 32 | - /kopano/data 33 | -------------------------------------------------------------------------------- /tests/test.exp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/expect 2 | 3 | # uncomment to debug expect: 4 | #exp_internal 1 5 | 6 | spawn "./setup.sh" 7 | 8 | expect { 9 | "]:" { 10 | send "\r" 11 | exp_continue 12 | } 13 | "):" { 14 | send "\r" 15 | exp_continue 16 | } 17 | eof 18 | } 19 | 20 | spawn "./setup-update-tag.sh" 21 | 22 | expect { 23 | "#?" { 24 | send "\r" 25 | exp_continue 26 | } 27 | eof 28 | } 29 | -------------------------------------------------------------------------------- /utils/Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax = docker/dockerfile:1.0-experimental 2 | ARG docker_repo=zokradonh 3 | FROM ${docker_repo}/kopano_core 4 | 5 | LABEL maintainer=az@zok.xyz \ 6 | org.label-schema.name="Kopano utils container" \ 7 | org.label-schema.description="Container that bundles various cli tools from Kopano Groupware Core" \ 8 | org.label-schema.url="https://kopano.io" \ 9 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 10 | org.label-schema.version=$KOPANO_CORE_VERSION \ 11 | org.label-schema.schema-version="1.0" 12 | 13 | RUN --mount=type=secret,id=repocred,target=/etc/apt/auth.conf.d/kopano.conf \ 14 | apt-get update && apt-get install --no-install-recommends -y \ 15 | git \ 16 | iputils-ping \ 17 | kopano-backup \ 18 | kopano-migration-imap \ 19 | ldap-utils \ 20 | less \ 21 | lsof \ 22 | man \ 23 | nano \ 24 | net-tools \ 25 | vim \ 26 | && apt-get clean \ 27 | && rm -rf /var/lib/apt/lists/* 28 | 29 | CMD [ "/bin/bash" ] 30 | 31 | ARG VCS_REF 32 | LABEL org.label-schema.vcs-ref=$VCS_REF 33 | -------------------------------------------------------------------------------- /utils/README.md: -------------------------------------------------------------------------------- 1 | # Kopano Utils image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_utils.svg)](https://microbadger.com/images/zokradonh/kopano_utils "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_utils.svg)](https://microbadger.com/images/zokradonh/kopano_utils "Microbadger version") 4 | 5 | Dedicated image with utilities for Kopano environments (admin, backup, ..). 6 | -------------------------------------------------------------------------------- /version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | DEBUG=${DEBUG:-""} 4 | tmpfile=${tmpfile:-""} 5 | 6 | if ! command -v jq > /dev/null; then 7 | echo "Please install jq in order to run this build script." 8 | exit 1 9 | fi 10 | 11 | function finish { 12 | if [ -e "$tmpfile" ]; then 13 | rm "$tmpfile" 14 | fi 15 | } 16 | trap finish EXIT 17 | 18 | source base/create-kopano-repo.sh 19 | 20 | component=${1:-core} 21 | distribution=${2:-Debian_10} 22 | channel=${3:-community} 23 | branch=${4:-""} 24 | 25 | if [ -e ./.env ]; then 26 | # this is a kind of ugly hack to be able to source the env file 27 | # this is sadly needed since postfix in https://github.com/tomav/docker-mailserver/ cannot deal with quoted values 28 | tmpfile=$(mktemp /tmp/kopano-docker-env.XXXXXX) 29 | cp ./.env "$tmpfile" 30 | sed -i '/LDAP_QUERY_FILTER/s/^/#/g' "$tmpfile" 31 | sed -i '/SASLAUTHD_LDAP_FILTER/s/^/#/g' "$tmpfile" 32 | sed -i '/KCUNCOMMENT_LDAP_1/s/^/#/g' "$tmpfile" 33 | sed -i '/KCCOMMENT_LDAP_1/s/^/#/g' "$tmpfile" 34 | # shellcheck disable=SC1090 35 | source "$tmpfile" 36 | else 37 | tmpfile="undefined" 38 | fi 39 | 40 | case $component in 41 | core) 42 | KOPANO_CORE_REPOSITORY_URL=${KOPANO_CORE_REPOSITORY_URL:-""} 43 | if [[ $KOPANO_CORE_REPOSITORY_URL == http* ]]; then 44 | version=$(curl --netrc-file ./apt_auth.conf --netrc-optional -m 1 -s -S -L "$KOPANO_CORE_REPOSITORY_URL"/Packages | grep -A2 "Package: kopano-server-packages") 45 | echo "${version##* }" 46 | exit 47 | fi 48 | ;; 49 | webapp) 50 | KOPANO_WEBAPP_REPOSITORY_URL=${KOPANO_WEBAPP_REPOSITORY_URL:-""} 51 | if [[ $KOPANO_WEBAPP_REPOSITORY_URL == http* ]]; then 52 | version=$(curl --netrc-file ./apt_auth.conf --netrc-optional -m 1 -s -S -L "$KOPANO_WEBAPP_REPOSITORY_URL"/Packages | grep -m1 -A1 "Package: kopano-webapp") 53 | echo "${version##* }" 54 | exit 55 | fi 56 | ;; 57 | zpush) 58 | KOPANO_ZPUSH_REPOSITORY_URL=${KOPANO_ZPUSH_REPOSITORY_URL:-"https://download.kopano.io/zhub/z-push:/final/Debian_10/"} 59 | if [[ $KOPANO_ZPUSH_REPOSITORY_URL == http* ]]; then 60 | version=$(curl -m 1 -s -S -L "$KOPANO_ZPUSH_REPOSITORY_URL"/Packages | grep -m2 -A2 "Package: z-push-kopano") 61 | echo "${version##* }" 62 | exit 63 | fi 64 | ;; 65 | meet) 66 | KOPANO_MEET_REPOSITORY_URL=${KOPANO_MEET_REPOSITORY_URL:-""} 67 | if [[ $KOPANO_MEET_REPOSITORY_URL == http* ]]; then 68 | version=$(curl --netrc-file ./apt_auth.conf --netrc-optional -m 1 -s -S -L "$KOPANO_MEET_REPOSITORY_URL"/Packages | grep -A2 "Package: kopano-meet-packages") 69 | echo "${version##* }" 70 | exit 71 | fi 72 | ;; 73 | kdav) 74 | git ls-remote --tags https://stash.kopano.io/scm/kc/kdav.git | awk -F/ '{ print $3 }' | tail -1 | sed 's/^.//' 75 | exit 76 | esac 77 | 78 | # query community server by h5ai API 79 | filename=$(h5ai_query "$component" "$distribution" "$channel" "$branch") 80 | 81 | currentVersion=$(version_from_filename "$filename") 82 | 83 | versiontemp="${currentVersion//[^.]}" 84 | # a valid version number has at least two dots. e.g. 1.2.3 85 | if [ ${#versiontemp} -lt 2 ]; then 86 | echo "Malformed version received" 87 | exit 1 88 | fi 89 | 90 | echo "$currentVersion" 91 | -------------------------------------------------------------------------------- /web/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG CODE_VERSION=0.12.4 2 | FROM kopano/kwebd:${CODE_VERSION} 3 | 4 | ARG CODE_VERSION 5 | 6 | LABEL maintainer=az@zok.xyz \ 7 | org.label-schema.name="Kopano Web container" \ 8 | org.label-schema.description="Reverse proxy for http(s) based components of kopano-docker" \ 9 | org.label-schema.url="https://kopano.io" \ 10 | org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \ 11 | org.label-schema.version=$CODE_VERSION \ 12 | org.label-schema.schema-version="1.0" 13 | 14 | ENV \ 15 | AUTOCONFIGURE=true \ 16 | CODE_VERSION="${CODE_VERSION}" \ 17 | DEFAULTREDIRECT="/webapp" \ 18 | KONNECTPATH=kopanoid \ 19 | TLS_MODE=tls_auto 20 | # FIXME Workaround to not break backwards compatibility, 21 | # since an underscore is not a valid char in a hostname. 22 | # This causes issues when using kweb in kubernetes. 23 | # Related issue https://github.com/docker/compose/issues/229 24 | ENV \ 25 | KWEBD_DNS_GRAPI="kopano_grapi" \ 26 | KWEBD_DNS_ICAL="kopano_ical" \ 27 | KWEBD_DNS_ICAL="kopano_ical" \ 28 | KWEBD_DNS_KAPI="kopano_kapi" \ 29 | KWEBD_DNS_KAPPS="kopano_kapps" \ 30 | KWEBD_DNS_KDAV="kopano_kdav" \ 31 | KWEBD_DNS_KONNECT="kopano_konnect" \ 32 | KWEBD_DNS_KWMSERVER="kopano_kwmserver" \ 33 | KWEBD_DNS_MEET="kopano_meet" \ 34 | KWEBD_DNS_PLAYGROUND="kopano_playground" \ 35 | KWEBD_DNS_WEBAPP="kopano_webapp" \ 36 | KWEBD_DNS_ZPUSH="kopano_zpush" 37 | 38 | ENV DOCKERIZE_VERSION v0.6.1 39 | RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 40 | && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ 41 | && rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz 42 | 43 | COPY kweb.cfg tls_* /etc/ 44 | COPY wrapper.sh /usr/local/bin/ 45 | 46 | ENTRYPOINT ["wrapper.sh"] 47 | 48 | ARG VCS_REF 49 | LABEL org.label-schema.vcs-ref=$VCS_REF 50 | -------------------------------------------------------------------------------- /web/README.md: -------------------------------------------------------------------------------- 1 | # Kopano Web image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_web.svg)](https://microbadger.com/images/zokradonh/kopano_web "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_web.svg)](https://microbadger.com/images/zokradonh/kopano_web "Microbadger version") 4 | 5 | Reverse Proxy to securely and with as less configuration effort as possible expose Kopano to the public internet. 6 | 7 | In its default configuration this container will redirect requests to the root of the domain (so for example when opening https://kopano.demo/ in a browser) to https://kopano.demo/webapp. To redirect to a different path the environment variable `DEFAULTREDIRECT` needs to be configured. 8 | 9 | Example: 10 | 11 | ```bash 12 | # the following value needs to be added to .env 13 | DEFAULTREDIRECT=/meet 14 | ``` 15 | 16 | ## Serving additional files 17 | 18 | Kweb in the Web container can easily be extended to serve static content. By default it will serve all content that has been copied into `/var/www/`. To extend the built in configuration file just add an additional file into `/etc/kweb-extras/`. Kweb is using the [Caddyfile syntax](https://caddyserver.com/v1/docs/caddyfile). 19 | 20 | ## Using existing ssl certificates 21 | 22 | By default this container will use automatic tls certificates provided by Let's Encrypt. This can be influenced through the following environment variables: 23 | 24 | ```bash 25 | # 1. Automatic certificate from Let's Encrypt 26 | TLS_MODE=tls_auto 27 | EMAIL=example@example.com 28 | 29 | # 2. Custom certificate and key 30 | TLS_MODE=tls_custom 31 | TLS_CERT=/src/ssl/cert.pem 32 | TLS_KEY=/src/ssl/key.pem 33 | 34 | # 3. Self signed certificate (FOR DEBUGGING) 35 | TLS_MODE=tls_selfsigned 36 | 37 | # 4. Disable TLS entirely 38 | TLS_MODE=tls_off 39 | ``` 40 | 41 | ## Using a reverse proxy in front of this container 42 | 43 | In case there is already an ssl terminating proxy in the network this container can be switched to plain http by either setting `EMAIL=off` or `TLS_MODE=tls_off`. 44 | 45 | In addition to this the default docker-compose.yml has a tweak to [route all traffic for the configured domain through this container](https://github.com/zokradonh/kopano-docker/blob/3572fc74e7054c9774985e69aeed745f9e5d1a4f/docker-compose.yml#L19-L20). This route needs to be changed when this container is only offering http access by removing `FQDNCLEANED` from `.env`. 46 | 47 | When using an external reverse proxy it is recommended to proxy connections to port 2015 of this container. Additionally connections to `/api/kwm/v2/rtm/websocket` need to be upgraded to websocket connections. 48 | 49 | ## Information needed when not running your own reverse proxy 50 | 51 | The `kopano_webapp` container is accessible on port 9080 and serves the WebApp on `/webapp`. 52 | -------------------------------------------------------------------------------- /web/tls_auto: -------------------------------------------------------------------------------- 1 | tls {%EMAIL%} 2 | -------------------------------------------------------------------------------- /web/tls_custom: -------------------------------------------------------------------------------- 1 | tls {%TLS_CERT%} {%TLS_KEY%} 2 | -------------------------------------------------------------------------------- /web/tls_off: -------------------------------------------------------------------------------- 1 | tls off 2 | -------------------------------------------------------------------------------- /web/tls_selfsigned: -------------------------------------------------------------------------------- 1 | tls self_signed 2 | -------------------------------------------------------------------------------- /web/wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | # allow helper commands given by "docker-compose run" 6 | if [ $# -gt 0 ]; then 7 | exec "$@" 8 | exit 9 | fi 10 | 11 | export CADDYPATH="$KOPANO_KWEB_ASSETS_PATH" 12 | 13 | # remove ports from FQDN 14 | export FQDN=${FQDN%:*} 15 | 16 | # services need to be aware of the machine-id 17 | if [ "$AUTOCONFIGURE" = true ]; then 18 | dockerize \ 19 | -wait file:///etc/machine-id \ 20 | -wait file:///var/lib/dbus/machine-id 21 | fi 22 | 23 | exec "$EXE" caddy -conf /etc/kweb.cfg -agree 24 | -------------------------------------------------------------------------------- /webapp/Dockerfile.demo: -------------------------------------------------------------------------------- 1 | ARG docker_repo=zokradonh 2 | FROM ${docker_repo}/kopano_webapp 3 | 4 | # hadolint ignore=SC2016 5 | RUN sed -i '1s/^/\n/' /usr/share/kopano-webapp/server/includes/templates/login.php && \ 6 | sed -i 's/id="password"/id="password" value=""/' /usr/share/kopano-webapp/server/includes/templates/login.php 7 | -------------------------------------------------------------------------------- /webapp/Dockerfile.plugins: -------------------------------------------------------------------------------- 1 | # This Dockerfile can be built by running `make build-webapp-plugins` in the root of this project 2 | ARG docker_repo=zokradonh 3 | FROM ${docker_repo}/kopano_webapp 4 | 5 | ENV \ 6 | KCCONF_WEBAPPPLUGIN_MDM_PLUGIN_MDM_USER_DEFAULT_ENABLE_MDM=true \ 7 | KCCONF_WEBAPPPLUGIN_MDM_PLUGIN_MDM_SERVER=kopano_zpush:9080 \ 8 | KCCONF_WEBAPPPLUGIN_MDM_PLUGIN_MDM_SERVER_SSL=false 9 | 10 | SHELL ["/bin/bash", "-o", "pipefail", "-c"] 11 | 12 | RUN apt-get update && apt-get install -y --no-install-recommends \ 13 | "${ADDITIONAL_KOPANO_PACKAGES}" \ 14 | "${ADDITIONAL_KOPANO_WEBAPP_PLUGINS}" \ 15 | kopano-webapp-plugin-files \ 16 | kopano-webapp-plugin-filesbackend-owncloud \ 17 | kopano-webapp-plugin-intranet \ 18 | kopano-webapp-plugin-mdm \ 19 | kopano-webapp-plugin-pimfolder \ 20 | kopano-webapp-plugin-smime \ 21 | && rm -rf /var/cache/apt /var/lib/apt/lists 22 | 23 | # tweak to make the container read-only 24 | RUN mkdir -p /tmp/webapp/ && \ 25 | for i in /etc/kopano/webapp/* /etc/kopano/webapp/.[^.]*; do \ 26 | if [ -L "$i" ]; then \ 27 | continue; \ 28 | fi; \ 29 | if [[ "$i" = *.dist ]]; then \ 30 | continue; \ 31 | fi; \ 32 | mv -v "$i" "$i.dist"; \ 33 | ln -s /tmp/webapp/"$(basename "$i")" "$i"; \ 34 | done 35 | -------------------------------------------------------------------------------- /webapp/README.md: -------------------------------------------------------------------------------- 1 | # Kopano WebApp image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_webapp.svg)](https://microbadger.com/images/zokradonh/kopano_webapp "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_webapp.svg)](https://microbadger.com/images/zokradonh/kopano_webapp "Microbadger version") 4 | 5 | Image for Kopano WebApp and its plugins. Please check in the `kopano_php` folder for configuration instructions. 6 | 7 | ## Configuration through environment variables 8 | 9 | Any additional configuration should be done through environment variables and not done in the actual container. The images working with configuration files (e.g. `kopano_core`, `kopano_webapp`, `kopano_meet`) have a mechanism built in to translate env variables into configuration files. For services that can directly work with env variables (e.g. `kopano_konnect`, ´kopano_kwmserver´) these can be specified directly. Please check the individual `README.md` files for further instructions. 10 | 11 | Examples of env variables: 12 | 13 | ```bash 14 | KCCONF_WEBAPP_CLIENT_TIMEOUT=3600 15 | ^ ^ ^ ^ 16 | | | | | 17 | General prefix| | 18 | | | | 19 | Special value to signal the change should go into config.php belonging to WebApp 20 | | | 21 | Name of the configuration option in the configuration file 22 | | 23 | Value of the configuration option 24 | 25 | KCCONF_WEBAPPPLUGIN_MDM_PLUGIN_MDM_USER_DEFAULT_ENABLE_MDM=true 26 | ^ ^ ^ ^ ^ 27 | | | | | | 28 | General prefix | | | 29 | | | | | 30 | Special value to signal the change should go into config-$identifier.php (located in /etc/kopano/webapp) 31 | | | | 32 | Identifier for the configuration file (config-$identifier.php) 33 | | | 34 | Name of the configuration option in the configuration file 35 | | 36 | Value of the configuration option 37 | ``` 38 | -------------------------------------------------------------------------------- /webapp/commander.yaml: -------------------------------------------------------------------------------- 1 | tests: 2 | start-service script: 3 | command: bash -c "shopt -s expand_aliases; alias exec='echo exec'; alias php-fpm7.3='echo php-fpm7.3'; . /kopano/start.sh" 4 | exit-code: 0 5 | stdout: 6 | not-contains: 7 | - "Reading package lists..." 8 | start-service script (installing new package): 9 | command: bash -c "shopt -s expand_aliases; alias exec='echo exec'; alias php-fpm7.3='echo php-fpm7.3'; . /kopano/start.sh" 10 | exit-code: 0 11 | stdout: 12 | contains: 13 | - "Setting up nano" 14 | config: 15 | env: 16 | ADDITIONAL_KOPANO_PACKAGES: "nano" 17 | start-service script (installing existing package): 18 | command: bash -c "shopt -s expand_aliases; alias exec='echo exec'; alias php-fpm7.3='echo php-fpm7.3'; . /kopano/start.sh" 19 | exit-code: 0 20 | stdout: 21 | contains: 22 | - "INFO: kopano-webapp is already installed" 23 | config: 24 | env: 25 | ADDITIONAL_KOPANO_PACKAGES: "kopano-webapp" 26 | start-service script (webapp configuration): 27 | command: bash -c "shopt -s expand_aliases; alias exec='echo exec'; alias php-fpm7.3='echo php-fpm7.3'; . /kopano/start.sh" && cat /etc/kopano/webapp/config.php 28 | exit-code: 0 29 | stdout: 30 | contains: 31 | - "define('OIDC_CLIENT_ID', 'webapp');" 32 | config: 33 | env: 34 | KCCONF_WEBAPP_OIDC_CLIENT_ID: "webapp" 35 | start-service script (installing & configuring webapp mdm plugin): 36 | command: bash -c "shopt -s expand_aliases; alias exec='echo exec'; alias php-fpm7.3='echo php-fpm7.3'; . /kopano/start.sh" && cat /etc/kopano/webapp/config-mdm.php 37 | exit-code: 0 38 | stdout: 39 | contains: 40 | - "define('PLUGIN_MDM_USER_DEFAULT_ENABLE_MDM', true);" 41 | config: 42 | env: 43 | ADDITIONAL_KOPANO_WEBAPP_PLUGINS: "kopano-webapp-plugin-mdm" 44 | KCCONF_WEBAPPPLUGIN_MDM_PLUGIN_MDM_USER_DEFAULT_ENABLE_MDM: "true" 45 | config: 46 | env: 47 | DEBUG: ${DEBUG} 48 | KCCONF_WEBAPP_OIDC_ISS: ${KCCONF_WEBAPP_OIDC_ISS} 49 | KCCONF_WEBAPP_OIDC_CLIENT_ID: ${KCCONF_WEBAPP_OIDC_CLIENT_ID} 50 | LANG: ${LANG} 51 | PATH: ${PATH} 52 | TZ: ${TZ} 53 | -------------------------------------------------------------------------------- /webapp/goss.yaml: -------------------------------------------------------------------------------- 1 | file: 2 | /run/sessions: 3 | exists: true 4 | owner: www-data 5 | group: www-data 6 | filetype: directory 7 | /usr/lib/php/20180731/mapi.so: 8 | exists: true 9 | mode: "0644" 10 | owner: root 11 | group: root 12 | filetype: file 13 | contains: [] 14 | /var/lib/kopano-webapp/tmp: 15 | exists: true 16 | mode: "0755" 17 | owner: www-data 18 | group: www-data 19 | filetype: directory 20 | contains: [] 21 | process: 22 | kwebd: 23 | running: true 24 | php-fpm7.3: 25 | running: true 26 | http: 27 | http://localhost:9080/status: 28 | status: 200 29 | allow-insecure: false 30 | no-follow-redirects: false 31 | timeout: 5000 32 | body: [] 33 | -------------------------------------------------------------------------------- /webapp/goss_wait.yaml: -------------------------------------------------------------------------------- 1 | port: 2 | tcp6:9080: 3 | listening: true 4 | -------------------------------------------------------------------------------- /webapp/kopano-webapp.conf: -------------------------------------------------------------------------------- 1 | [kopano-webapp] 2 | ; Unix user/group of processes 3 | ; Note: The user is mandatory. If the group is not set, the default user's group 4 | ; will be used. 5 | user = www-data 6 | group = www-data 7 | 8 | ; Set permissions for unix socket, if one is used. In Linux, read/write 9 | ; permissions must be set in order to allow connections from a web server. Many 10 | ; BSD-derived systems allow connections regardless of permissions. 11 | ; Default Values: user and group are set as the running user 12 | ; mode is set to 0660 13 | listen.owner = www-data 14 | listen.group = www-data 15 | 16 | listen = /run/php/php-fpm-kopano-webapp.sock 17 | 18 | ; Pool configuration intended for up to 500 users. 19 | pm = dynamic 20 | pm.max_children = 100 21 | pm.start_servers = 10 22 | pm.min_spare_servers = 10 23 | pm.max_spare_servers = 50 24 | pm.process_idle_timeout = 60s 25 | pm.max_requests = 500 26 | pm.status_path = /status 27 | 28 | ping.path = /ping 29 | ping.response = pong 30 | 31 | security.limit_extensions = .php 32 | 33 | php_flag[display_errors] = off 34 | 35 | php_admin_value[max_execution_time] = 60 36 | php_admin_value[post_max_size] = 20M 37 | php_admin_value[upload_max_filesize] = 20M 38 | php_admin_value[memory_limit] = 32M 39 | 40 | php_admin_flag[log_errors] = on 41 | 42 | ; Redirect worker stdout and stderr into main error log. If not set, stdout and 43 | ; stderr will be redirected to /dev/null according to FastCGI specs. 44 | ; Note: on highloaded environement, this can cause some delay in the page 45 | ; process time (several ms). 46 | ; Default Value: no 47 | catch_workers_output = no -------------------------------------------------------------------------------- /webapp/kweb.cfg: -------------------------------------------------------------------------------- 1 | :9080 { 2 | log stdout 3 | errors stderr 4 | 5 | # healthcheck 6 | status 200 /status 7 | 8 | alias /webapp/ /usr/share/kopano-webapp/ 9 | fastcgi2 /webapp/ /run/php/php-fpm-kopano-webapp.sock php { 10 | without /webapp/ 11 | root /usr/share/kopano-webapp/ 12 | } 13 | 14 | status 403 { 15 | /webapp/config.php 16 | /webapp/debug.php 17 | /webapp/defaults.php 18 | /webapp/init.php 19 | /webapp/server 20 | /webapp/version 21 | 22 | /webapp/plugins/forbidden 23 | } 24 | 25 | rewrite /webapp/plugins/ { 26 | regexp config.php 27 | to /webapp/plugins/forbidden 28 | } 29 | 30 | folderish /webapp 31 | } 32 | -------------------------------------------------------------------------------- /zpush/README.md: -------------------------------------------------------------------------------- 1 | # Kopano Z-Push image 2 | 3 | [![](https://images.microbadger.com/badges/image/zokradonh/kopano_zpush.svg)](https://microbadger.com/images/zokradonh/kopano_zpush "Microbadger size/labels") [![](https://images.microbadger.com/badges/version/zokradonh/kopano_zpush.svg)](https://microbadger.com/images/zokradonh/kopano_zpush "Microbadger version") 4 | 5 | Image for running Z-Push with Kopano. 6 | 7 | The `kopano_zpush` container is accessible on port 80 and serves Z-Push on `/Microsoft-Server-ActiveSync` ((additional urls are needed in case auto discover should be used). 8 | -------------------------------------------------------------------------------- /zpush/commander.yaml: -------------------------------------------------------------------------------- 1 | tests: 2 | start-service script: 3 | command: bash -c "shopt -s expand_aliases; alias exec='echo exec'; alias php-fpm7.3='echo php-fpm7.3'; . /kopano/start.sh" 4 | exit-code: 0 5 | stdout: 6 | not-contains: 7 | - "Reading package lists..." 8 | start-service script (installing new package): 9 | command: bash -c "shopt -s expand_aliases; alias exec='echo exec'; alias php-fpm7.3='echo php-fpm7.3'; . /kopano/start.sh" 10 | exit-code: 0 11 | stdout: 12 | contains: 13 | - "Setting up nano" 14 | config: 15 | env: 16 | ADDITIONAL_KOPANO_PACKAGES: "nano" 17 | start-service script (installing existing package): 18 | command: bash -c "shopt -s expand_aliases; alias exec='echo exec'; alias php-fpm7.3='echo php-fpm7.3'; . /kopano/start.sh" 19 | exit-code: 0 20 | stdout: 21 | contains: 22 | - "INFO: z-push-kopano is already installed" 23 | config: 24 | env: 25 | ADDITIONAL_KOPANO_PACKAGES: "z-push-kopano" 26 | start-service script (z-push configuration): 27 | command: bash -c "shopt -s expand_aliases; alias exec='echo exec'; alias php-fpm7.3='echo php-fpm7.3'; . /kopano/start.sh" && cat /etc/z-push/z-push.conf.php 28 | exit-code: 0 29 | stdout: 30 | contains: 31 | - "define('USE_CUSTOM_REMOTE_IP_HEADER', 'HTTP_X_FORWARDED_FOR');" 32 | start-service script (configuring gabsync): 33 | command: bash -c "shopt -s expand_aliases; alias exec='echo exec'; alias php-fpm7.3='echo php-fpm7.3'; . /kopano/start.sh" && cat /etc/z-push/gabsync.conf.php 34 | exit-code: 0 35 | stdout: 36 | contains: 37 | - "define('USERNAME', 'SYSTEM');" 38 | start-service script (no additional folders): 39 | command: bash -c "shopt -s expand_aliases; alias exec='echo exec'; alias php-fpm7.3='echo php-fpm7.3'; . /kopano/start.sh" && cat /etc/z-push/z-push.conf.php 40 | exit-code: 0 41 | stdout: 42 | contains: 43 | - " $additionalFolders = array(\n );" 44 | not-contains: # default entry 45 | - "\t$additionalFolders = array(" 46 | - "\t);" 47 | start-service script (empty additional folders): 48 | command: bash -c "shopt -s expand_aliases; alias exec='echo exec'; alias php-fpm7.3='echo php-fpm7.3'; . /kopano/start.sh" && cat /etc/z-push/z-push.conf.php 49 | exit-code: 0 50 | stdout: 51 | contains: 52 | - " $additionalFolders = array(\n );" 53 | not-contains: # default entry 54 | - "\t$additionalFolders = array(" 55 | - "\t);" 56 | config: 57 | env: 58 | ZPUSH_ADDITIONAL_FOLDERS: "[]" 59 | start-service script (set additional folders): 60 | command: bash -c "shopt -s expand_aliases; alias exec='echo exec'; alias php-fpm7.3='echo php-fpm7.3'; . /kopano/start.sh" && cat /etc/z-push/z-push.conf.php 61 | exit-code: 0 62 | stdout: 63 | contains: 64 | - " $additionalFolders = array(\n array('store' => \"SYSTEM\", 'folderid' => \"42\", 'name' => \"Calendar\", 'type' => SYNC_FOLDER_TYPE_USER_APPOINTMENT, 'flags' => 4),\n array('store' => \"SYSTEM\", 'folderid' => \"21\", 'name' => \"Mail\", 'type' => SYNC_FOLDER_TYPE_USER_MAIL, 'flags' => 0),\n );" 65 | not-contains: # default entry 66 | - "\t$additionalFolders = array(" 67 | - "\t);" 68 | config: 69 | env: 70 | ZPUSH_ADDITIONAL_FOLDERS: "[{\"name\":\"Calendar\",\"id\":\"42\",\"type\":\"SYNC_FOLDER_TYPE_USER_APPOINTMENT\",\"flags\":\"4\"},{\"name\":\"Mail\",\"id\":\"21\",\"type\":\"SYNC_FOLDER_TYPE_USER_MAIL\",\"flags\":\"0\"}]" 71 | 72 | 73 | config: 74 | env: 75 | DEBUG: ${DEBUG} 76 | LANG: ${LANG} 77 | PATH: ${PATH} 78 | TZ: ${TZ} 79 | -------------------------------------------------------------------------------- /zpush/kopano-z-push.conf: -------------------------------------------------------------------------------- 1 | [kopano-z-push] 2 | ; Unix user/group of processes 3 | ; Note: The user is mandatory. If the group is not set, the default user's group 4 | ; will be used. 5 | user = www-data 6 | group = www-data 7 | 8 | ; Set permissions for unix socket, if one is used. In Linux, read/write 9 | ; permissions must be set in order to allow connections from a web server. Many 10 | ; BSD-derived systems allow connections regardless of permissions. 11 | ; Default Values: user and group are set as the running user 12 | ; mode is set to 0660 13 | listen.owner = www-data 14 | listen.group = www-data 15 | 16 | listen = /run/php/php-fpm-kopano-z-push.sock 17 | 18 | ; Pool configuration intended for up to 500 users. 19 | pm = dynamic 20 | pm.max_children = 200 21 | pm.start_servers = 10 22 | pm.min_spare_servers = 10 23 | pm.max_spare_servers = 200 24 | pm.process_idle_timeout = 3540s 25 | pm.max_requests = 200 26 | pm.status_path = /status 27 | 28 | ping.path = /ping 29 | ping.response = pong 30 | 31 | security.limit_extensions = .php 32 | 33 | php_flag[display_errors] = off 34 | 35 | php_admin_value[max_execution_time] = 3540 36 | php_admin_value[post_max_size] = 20M 37 | php_admin_value[upload_max_filesize] = 20M 38 | php_admin_value[memory_limit] = 25M 39 | 40 | php_admin_flag[log_errors] = on 41 | 42 | ; Redirect worker stdout and stderr into main error log. If not set, stdout and 43 | ; stderr will be redirected to /dev/null according to FastCGI specs. 44 | ; Note: on highloaded environement, this can cause some delay in the page 45 | ; process time (several ms). 46 | ; Default Value: no 47 | catch_workers_output = no -------------------------------------------------------------------------------- /zpush/kweb.cfg: -------------------------------------------------------------------------------- 1 | :9080 { 2 | log stdout 3 | errors stderr 4 | 5 | # healthcheck 6 | status 200 /status 7 | 8 | rewrite /Microsoft-Server-ActiveSync { 9 | regexp ^$ 10 | to /z-push/index.php 11 | } 12 | 13 | fastcgi2 /z-push/ /run/php/php-fpm-kopano-z-push.sock php { 14 | without /z-push/ 15 | root /usr/share/z-push 16 | read_timeout 3605s 17 | } 18 | 19 | status 403 { 20 | /z-push/autodiscover 21 | /z-push/backend 22 | /z-push/config.php 23 | /z-push/include 24 | /z-push/lib 25 | /z-push/vendor 26 | /z-push/version.php 27 | /z-push/z-push-admin.php 28 | /z-push/z-push-top.php 29 | } 30 | 31 | rewrite / { 32 | regexp (?i)^/Autodiscover/Autodiscover.xml 33 | to /z-push-autodiscover/autodiscover.php 34 | } 35 | 36 | fastcgi2 /z-push-autodiscover/ /run/php/php-fpm-kopano-z-push.sock php { 37 | without /z-push-autodiscover/ 38 | root /usr/share/z-push/autodiscover 39 | } 40 | 41 | status 403 { 42 | /z-push-autodiscover/config.php 43 | } 44 | } 45 | --------------------------------------------------------------------------------