1
0
mirror of https://github.com/zokradonh/kopano-docker synced 2025-06-18 13:26:24 +00:00

Compare commits

..

20 Commits

Author SHA1 Message Date
Felix Bartels
c8096b9a8f make it possible to install additional packages at runtime and not only during build
Signed-off-by: Felix Bartels <felix@host-consultants.de>
2018-11-01 08:37:50 +01:00
Felix Bartels
2043b94062 update todo
Signed-off-by: Felix Bartels <felix@host-consultants.de>
2018-10-23 09:45:54 +02:00
Felix Bartels
098ff5208c add a link to the project into gencerts.sh
Signed-off-by: Felix Bartels <felix@host-consultants.de>
2018-10-23 09:45:21 +02:00
Felix Bartels
8db1dc5488 make webapp container start
first start with caddyfile

Signed-off-by: Felix Bartels <felix@host-consultants.de>
2018-10-22 12:13:10 +02:00
Felix Bartels
51af427dce add demo ldap data from https://github.com/tomav/docker-mailserver/tree/master/test/docker-openldap 2018-10-22 10:06:42 +02:00
Felix Bartels
6773927116 reolace until loop with dockerize as well
Signed-off-by: Felix Bartels <felix@host-consultants.de>
2018-10-20 09:07:21 +02:00
Felix Bartels
92b6e0da10 update docker-file
while it did not work out to depend in the health status of mysql for the start of kopano-server, its nevertheless an interesting value. since the dockerfile does not include an automatic healcheak, add it to the compose file.

Signed-off-by: Felix Bartels <felix@host-consultants.de>
2018-10-19 16:48:19 +02:00
Felix Bartels
0bd6886b47 use dockerize to wait for mysql to start up
Signed-off-by: Felix Bartels <felix@host-consultants.de>
2018-10-19 16:47:51 +02:00
Felix Bartels
b381a29859 add dockerize to base image 2018-10-19 16:47:32 +02:00
Felix Bartels
d08b00375c tuning of ssl settings
Signed-off-by: Felix Bartels <felix@host-consultants.de>
2018-10-19 15:19:04 +02:00
Felix Bartels
5d838d2194 wait with kopano-server startup until ssl certificates are present
Signed-off-by: Felix Bartels <felix@host-consultants.de>
2018-10-19 15:18:29 +02:00
Felix Bartels
b608aa59f5 also build ssl helper container
fix creation of folders when ssl helper is run with mounted dirs
2018-10-19 15:17:59 +02:00
Felix Bartels
a3315f61c9 do not ignore ssl dir 2018-10-19 15:17:07 +02:00
Felix Bartels
a183ac1f8d make committing of components always succeed
Signed-off-by: Felix Bartels <felix@host-consultants.de>
2018-10-18 18:18:40 +02:00
Felix Bartels
a656ddb8f5 refine tagging a bit
Signed-off-by: Felix Bartels <felix@host-consultants.de>
2018-10-18 18:10:59 +02:00
Felix Bartels
a2511f4f44 ci: commit changes before tagging 2018-10-18 14:33:48 +02:00
Felix Bartels
0b686587c2 Merge branch 'master' into compose 2018-10-18 14:32:58 +02:00
Felix Bartels
c44017b3e3 Merge branch 'master' into compose 2018-10-18 14:28:03 +02:00
Felix Bartels
c08bdfc6a9 docker-compose
Signed-off-by: Felix Bartels <felix@host-consultants.de>
2018-10-17 22:55:12 +02:00
Felix Bartels
5523f4c984 wip: try to get some inspiration from https://www.davd.eu/byecloud-building-a-mailserver-with-modern-webmail/ for the compose example
Signed-off-by: Felix Bartels <felix@host-consultants.de>
2018-10-17 08:46:58 +02:00
226 changed files with 1606 additions and 14217 deletions

View File

@ -1,99 +0,0 @@
#!/bin/bash
# bash .travis/docker-hub-helper.sh base
set -euo pipefail
IFS=$'\n\t'
# this is a kind of ugly hack to be able to source the env file
# this is sadly needed since postfix in https://github.com/tomav/docker-mailserver/ cannot deal with quoted values
tmpfile=$(mktemp /tmp/kopano-docker-env.XXXXXX)
cp ./.env "$tmpfile"
sed -i '/LDAP_QUERY_FILTER/s/^/#/g' "$tmpfile"
sed -i '/SASLAUTHD_LDAP_FILTER/s/^/#/g' "$tmpfile"
sed -i '/KCUNCOMMENT_LDAP_1/s/^/#/g' "$tmpfile"
sed -i '/KCCOMMENT_LDAP_1/s/^/#/g' "$tmpfile"
# shellcheck disable=SC1090
source "$tmpfile"
docker_repo=${docker_repo:-zokradonh}
docker_login=${docker_login:-""}
docker_pwd=${docker_pwd:-""}
if [ -z "$docker_login" ]; then
docker_login="$(<~/.docker-account-user)"
fi
if [ -z "$docker_pwd" ]; then
docker_pwd="$(<~/.docker-account-pwd)"
fi
image=${1:-""}
if [ -z "$image" ]; then
echo "ERROR: You must specify an image to modify."
exit 1
fi
# below code is based on https://github.com/moikot/golang-dep/blob/aab3ea8462a19407544f1ce9daa11c3f0924394c/.travis/push.sh
# code has since then moved to https://github.com/moikot/docker-tools.git
#
# Pushes README.md content to Docker Hub.
#
# $1 - The image name.
# $2 - The JWT.
#
# Examples:
#
# push_readme "foo/bar" "token"
#
push_readme() {
declare -r image="${1}"
declare -r token="${2}"
declare -r readme="${3}"
local code
code=$(jq -n --arg msg "$(<"${readme}")" \
'{"registry":"registry-1.docker.io","full_description": $msg }' | \
curl -s -o /dev/null -L -w "%{http_code}" \
https://hub.docker.com/v2/repositories/"${image}"/ \
-d @- -X PATCH \
-H "Content-Type: application/json" \
-H "Authorization: JWT ${token}")
if [[ "${code}" = "200" ]]; then
printf "Successfully pushed README to Docker Hub"
else
printf "Unable to push README to Docker Hub, response code: %s\n" "${code}"
exit 1
fi
local code
code=$(jq -n --arg msg "$(head -n 1 "${readme}" | cut -d' ' -f2-)" \
'{"registry":"registry-1.docker.io","description": $msg }' | \
curl -s -o /dev/null -L -w "%{http_code}" \
https://hub.docker.com/v2/repositories/"${image}"/ \
-d @- -X PATCH \
-H "Content-Type: application/json" \
-H "Authorization: JWT ${token}")
if [[ "${code}" = "200" ]]; then
printf "Successfully pushed description to Docker Hub"
else
printf "Unable to push description to Docker Hub, response code: %s\n" "${code}"
exit 1
fi
}
# Login into Docker repository
#echo "$docker_pwd" | docker login -u "$docker_login" --password-stdin
token=$(curl -s -X POST \
-H "Content-Type: application/json" \
-d '{"username": "'"$docker_login"'", "password": "'"$docker_pwd"'"}' \
https://hub.docker.com/v2/users/login/ | jq -r .token)
push_readme "${docker_repo}"/kopano_"${image}" "${token}" "${image}"/README.md
if [ -e "$tmpfile" ]; then
rm "$tmpfile"
fi

View File

@ -1,87 +0,0 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
COMMANDER_VERSION=2.1.0
DOCKER_COMPOSE_VERSION=1.25.5
GOSS_VERSION=0.3.11
HADOLINT_VERSION=1.23.0
REG_VERSION=0.16.1
SHELLCHECK_VERSION=0.7.1
progname=$(basename "$0")
tempdir=$(mktemp -d "/tmp/$progname.XXXXXX")
function cleanup() {
rm -rf "$tempdir"
}
trap cleanup INT EXIT
cd "$tempdir"
if ! command -v hadolint > /dev/null; then
sudo curl -L "https://github.com/hadolint/hadolint/releases/download/v$HADOLINT_VERSION/hadolint-$(uname -s)-$(uname -m)" -o /usr/local/bin/hadolint
sudo chmod +rx /usr/local/bin/hadolint
fi
if ! command -v docker-compose > /dev/null; then
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
sudo chmod +rx /usr/local/bin/docker-compose
fi
if ! command -v goss > /dev/null; then
sudo curl -L https://github.com/aelsabbahy/goss/releases/download/v$GOSS_VERSION/goss-linux-amd64 -o /usr/local/bin/goss
sudo chmod +rx /usr/local/bin/goss
fi
if ! command -v dcgoss > /dev/null; then
sudo curl -L https://raw.githubusercontent.com/fbartels/goss/dcgoss-v2/extras/dcgoss/dcgoss -o /usr/local/bin/dcgoss
sudo chmod +rx /usr/local/bin/dcgoss
fi
if ! command -v commander > /dev/null; then
sudo curl -L https://github.com/SimonBaeumer/commander/releases/download/v$COMMANDER_VERSION/commander-linux-amd64 -o /usr/local/bin/commander
sudo chmod +rx /usr/local/bin/commander
fi
if ! command -v dccommander > /dev/null; then
sudo curl -L https://raw.githubusercontent.com/fbartels/dccommander/master/dccommander -o /usr/local/bin/dccommander
sudo chmod +rx /usr/local/bin/dccommander
fi
if ! command -v reg > /dev/null; then
sudo curl -L https://github.com/genuinetools/reg/releases/download/v$REG_VERSION/reg-linux-amd64 -o /usr/local/bin/reg
sudo chmod +rx /usr/local/bin/reg
fi
if ! command -v expect > /dev/null; then
sudo apt update && sudo apt install -y expect
fi
if ! command -v pip > /dev/null; then
sudo apt install -y python-pip
fi
if ! command -v yamllint > /dev/null; then
sudo pip install --upgrade pip && sudo pip install yamllint
fi
if ! command -v npm > /dev/null; then
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt install -y nodejs
npm config set prefix ~
fi
if ! command -v eclint > /dev/null; then
npm install eclint -g
fi
if ! command -v shellcheck > /dev/null; then
wget "https://github.com/koalaman/shellcheck/releases/download/v$SHELLCHECK_VERSION/shellcheck-v$SHELLCHECK_VERSION.linux.x86_64.tar.xz"
tar -xf shellcheck-v*.linux.x86_64.tar.xz
sudo mv shellcheck-v*/shellcheck /usr/local/bin/
fi
if ! command -v jq > /dev/null; then
sudo apt install -y jq
fi

View File

@ -1,16 +0,0 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
# update to latest docker for buildkit support
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
# get base images to pull, as it will otherwise fail in travis
# git ls-files | xargs awk -F' ' '/^FROM/ { print $2 }' | sort -n | uniq | xargs --max-lines=1 docker pull
docker pull docker/dockerfile:1.0-experimental
docker pull docker.io/docker/dockerfile-copy:v0.1.9

View File

@ -1,38 +0,0 @@
# editorconfig tool configuration
# see http://editorconfig.org for docs
root = true
[*]
charset = utf-8
indent_style = tab
end_of_line = lf
trim_trailing_whitespaces = true
[{*.{yml,yaml,yml-off},.yamllint}]
indent_style = space
indent_size = 2
[*.{md,txt}]
indent_style = space
trim_trailing_whitespace = false
[Dockerfile*]
indent_style = space
indent_size = 4
[*.py]
indent_style = space
indent_size = 4
[*.ldif]
indent_style = space
[*.json]
indent_style = space
[LICENSE]
indent_style = space
[Vagrantfile]
indent_style = space

View File

@ -1,28 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem. Please don't post screenshots text blocks such as logfiles or general console output.
**Additional context**
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.

View File

@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -1,10 +0,0 @@
---
name: Question
about: Select this if you have a question
title: ''
labels: question
assignees: ''
---
# For general questions about Kopano please consider posting them on the [Kopano Forum](https://forum.kopano.io) instead.

View File

@ -1,7 +0,0 @@
Fixes #
## Proposed Changes
-
-
-

View File

@ -1,24 +0,0 @@
name: Weekly Goss check
on:
schedule:
- cron: "5 8 * * 1"
#on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: install expect
run: sudo apt-get update && sudo apt-get install -y expect
- name: create .env
run: ./tests/test.exp
- name: install goss
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
- name: install dcgoss
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
- name: Run goss tests
run: make test-goss

View File

@ -1,29 +0,0 @@
name: Linting checks via Reviewdog
on: [pull_request]
jobs:
reviewdog:
runs-on: ubuntu-latest
steps:
- name: Check out code.
uses: actions/checkout@v1
- name: misspell
uses: reviewdog/action-misspell@v1
with:
github_token: ${{ secrets.github_token }}
locale: "US"
- name: eclint
uses: fbartels/action-eclint@master
with:
github_token: ${{ secrets.github_token }}
- name: yamllint
uses: fbartels/action-yamllint@master
with:
github_token: ${{ secrets.github_token }}
- name: shellcheck
uses: fbartels/action-shellcheck@master
with:
github_token: ${{ secrets.github_token }}
- name: hadolint
uses: mgrachev/action-hadolint@v1.0.1
with:
github_token: ${{ secrets.github_token }}

View File

@ -1,21 +0,0 @@
name: Mark stale issues and pull requests
on:
schedule:
- cron: "0 0 * * *"
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v4.1.0
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
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'
days-before-stale: 30
days-before-close: 5
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'
stale-issue-label: 'no-issue-activity'
stale-pr-label: 'no-pr-activity'

12
.gitignore vendored
View File

@ -1,13 +1,5 @@
!.travis.yml
.env
.travis/config.yml
.vagrant
.vscode/settings.json
*.env
*.pem
**/.vscode
apt_auth.conf
build.tags
*.yml
docker-compose.yml
data/*
dive.log
docker-compose.override.yml

0
.gitmodules vendored
View File

View File

@ -1,13 +0,0 @@
ignored:
# disable following sourced files
- SC1091
# disable check for versioned upstream image
- DL3006
# disable don't use :latest
- DL3007
# disable explicit version for apt install
- DL3008
# disable explicit version for apk install
- DL3018
trustedRegistries:
- docker.io

View File

@ -1,5 +0,0 @@
{
"MD013": false,
"MD026": false,
"MD034": false
}

View File

@ -1,3 +0,0 @@
[MASTER]
init-hook='import sys; sys.path.append("base")'
disable=C0114, # missing-module-docstring

View File

@ -1,45 +0,0 @@
sudo: required
dist: bionic
language: node_js
node_js:
- stable
services:
- docker
before_install:
- sudo rm /usr/local/bin/docker-compose # remove pre-installed docker-compose (too old)
- bash -x .ci/setup-tools.sh
- .ci/travis-buildkit.sh # upgrade docker for buildkit support
install:
- "./version.sh"
- make lint
- "./tests/test.exp"
- "./version.sh"
- commander test tests/commander.yaml
- make lint # rerun lint to see if output is different with .env in place
- echo "docker_repo=$docker_repo" >> .env
- echo "DOCKERREADME=yes" >> .env # add DOCKERREADME env var so that make publish also updates readme files on docker hub
- echo "KCCONF_SERVER_SURVEYCLIENT_INTERVAL=0" >> kopano_server.env
- echo "KOPANO_SURVEYCLIENT_ENABLED=false" >> kopano_konnect.env
- echo "KOPANO_SURVEYCLIENT_ENABLED=false" >> kopano_kwmserver.env
- travis_retry make build-all
script:
- make test-ci
- docker-compose down -v
- make test-startup-meet-demo
deploy:
# login to docker hub
- provider: script
skip-cleanup: true
script: echo "$docker_pwd" | docker login -u "$docker_login" --password-stdin
on:
branch: master
# push images
- provider: script
skip-cleanup: true
script: make publish
on:
branch: master
#cache: # uncomment to not load/upload trivy files each time
# directories:
# - $HOME/.cache/trivy

View File

@ -1,8 +0,0 @@
# we're not using systemd
CVE-2017-1000082
# tar setuid issue
CVE-2005-2541
# libssh2 issue not relevant since not using ssh
CVE-2019-3855

View File

@ -1,7 +0,0 @@
extends: default
rules:
# 80 chars should be enough, but don't fail if a line is longer
line-length:
max: 80
level: warning

View File

@ -1,103 +0,0 @@
# Architecture Overview
Aka "How do the containers connect/relate/interact with each other?"
## web
- external entry point for users accessing Kopano
- reverse proxy for containers exposing a web interface
- can retrieve ssl certificate from Let's Encrypt
- redirects all requests to /webapp by default
- recommended to use as it makes web configuration easy and secure (manual configuration will be tedious and potentially less secure)
## ldap
- (optional) bundles OpenLDAP service
- kopano_server is using LDAP to manage users
## ldap-admin and password-self-service
- optional containers to manage users in ldap and let users change their password
## mail
- MTA stack with anti-spam and anti-virus
- connects against the ldap to verify users
## db
- (optional) bundles MariaDB for the Kopano database
## kopano_ssl
- helper container to generate ssl certificates for internal usage
- will create required files and then stop
## kopano_server
- main process of the Kopano deployment
- connects towards LDAP to get a list of users and verify user logins via bind
## kopano_webapp
- provides Kopano WebApp, so users can interact with their mailboxes via their browser
## kopano_zpush
- provides Z-Push, so users can sync their mailboxes to phones and tablets
## kopano_grapi
- groupware backend of the Kopano RestAPI
## kopano_kapi
- http endpoint of the Kopano RestAPI
- stores recent calls for the user in a key value stores (queried over Rest)
## kopano_kdav
- provides KDav, so users can sync their calendars and contacts via CalDAV and CardDAV
## kopano_dagent
- mail delivery part for kopano_server
- mta delivers mail to it, dagent delivers the mail into the desired inbox
## kopano_spooler
- mail sending part for kopano_server
- monitors outboxes of users, submits mails to the mta
## kopano_gateway
- provides Pop3 and IMAP access for users
## kopano_ical
- provides iCAL and CalDAV access for users (will be replaced with KDav in the future)
## kopano_monitor
- monitors mailbox usage and sends quota mails (by directly delivering a mail into the users inbox)
## kopano_search
- provides full text indexing for mailboxes
## kopano_konnect
- authentication component (OpenID Connect)
- required for apps interacting with the Kopano RestAPI (e.g. Kopano Meet)
## kopano_kwmserver
- WebRTC signalling server
## kopano_meet
- provides the Meet web application/frontend
## kopano_scheduler
- helper container to execute scheduled tasks within Kopano

View File

@ -1,129 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
contributing@kopano.io.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

View File

@ -1,27 +0,0 @@
# Contributing
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.
## General architecture of containers
To get an impression how the containers interact/relate with each other have a look at the [architecture](ARCHITECTURE.md) description.
## Helping others help you
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.
## Testing
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`.
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.
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!
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.
## Tricks
To speed up testing rebuilds you can override the git hash that is passed as a build argument.
Example: `make vcs_ref=invalid build-web` or `make vcs_ref=invalid build-all`

491
Makefile
View File

@ -1,501 +1,74 @@
# define some defaults https://tech.davis-hansson.com/p/make/
SHELL := bash
.ONESHELL:
.SHELLFLAGS := -eu -o pipefail -c
.DELETE_ON_ERROR:
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules
docker_repo := zokradonh
docker_login := `cat ~/.docker-account-user`
docker_pwd := `cat ~/.docker-account-pwd`
base_download_version := $(shell ./version.sh core)
core_download_version := $(shell ./version.sh core)
kapps_download_version := $(shell ./version.sh kapps)
meet_download_version := $(shell ./version.sh meet)
webapp_download_version := $(shell ./version.sh webapp)
zpush_download_version := $(shell ./version.sh zpush)
vcs_ref := $(shell git rev-parse --short HEAD)
base_version = $(shell docker run --rm $(docker_repo)/kopano_base cat /kopano/buildversion)
base_download_version = $(shell ./version.sh core)
core_version = $(shell docker run --rm $(docker_repo)/kopano_core cat /kopano/buildversion | grep -o -P '(?<=-).*(?=_)')
core_download_version = $(shell ./version.sh core)
webapp_version = $(shell docker run --rm $(docker_repo)/kopano_webapp cat /kopano/buildversion | tail -n 1 | grep -o -P '(?<=-).*(?=\+)')
webapp_download_version = $(shell ./version.sh webapp)
KOPANO_CORE_REPOSITORY_URL := file:/kopano/repo/core
KOPANO_KAPPS_REPOSITORY_URL := file:/kopano/repo/kapps
KOPANO_MEET_REPOSITORY_URL := file:/kopano/repo/meet
KOPANO_WEBAPP_FILES_REPOSITORY_URL := file:/kopano/repo/files
KOPANO_WEBAPP_MDM_REPOSITORY_URL := file:/kopano/repo/mdm
KOPANO_WEBAPP_REPOSITORY_URL := file:/kopano/repo/webapp
KOPANO_WEBAPP_SMIME_REPOSITORY_URL := file:/kopano/repo/smime
KOPANO_ZPUSH_REPOSITORY_URL := https://download.kopano.io/zhub/z-push:/final/Debian_10/
DOWNLOAD_COMMUNITY_PACKAGES := 1
KOPANO_UID := 999
KOPANO_GID := 999
DOCKERCOMPOSE_FILE := docker-compose.yml -f docker-compose.db.yml -f docker-compose.ldap.yml -f docker-compose.mail.yml
TAG_FILE := build.tags
-include .env
export
# convert lowercase componentname to uppercase
component ?= base
COMPONENT = $(shell echo $(component) | tr a-z A-Z)
.PHONY: default
default: help
build-all: build-ssl build-base build-core build-webapp
.PHONY: help
help: ## Show this help
@egrep -h '\s##\s' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}'
.PHONY: build-all
all: build-all
build-all:
make $(shell grep -o ^build-.*: Makefile | grep -Ev 'build-all|build-simple|build-builder|build-webapp-demo|build-webapp-plugins' | uniq | sed s/://g | xargs)
.PHONY: build
build: component ?= base
build: ## Helper target to build a given image. Defaults to the "base" image.
ifdef TRAVIS
@echo "fetching previous build to warm up build cache (only on travis)"
docker pull $(docker_repo)/kopano_$(component):builder || true
endif
ifeq (,$(wildcard ./apt_auth.conf))
touch apt_auth.conf
endif
BUILDKIT_PROGRESS=plain DOCKER_BUILDKIT=1 docker build --rm \
--build-arg VCS_REF=$(vcs_ref) \
--build-arg docker_repo=${docker_repo} \
--build-arg KOPANO_CORE_VERSION=${core_download_version} \
--build-arg KOPANO_$(COMPONENT)_VERSION=${$(component)_download_version} \
--build-arg KOPANO_CORE_REPOSITORY_URL=$(KOPANO_CORE_REPOSITORY_URL) \
--build-arg KOPANO_KAPPS_REPOSITORY_URL=$(KOPANO_KAPPS_REPOSITORY_URL) \
--build-arg KOPANO_MEET_REPOSITORY_URL=$(KOPANO_MEET_REPOSITORY_URL) \
--build-arg KOPANO_WEBAPP_FILES_REPOSITORY_URL=$(KOPANO_WEBAPP_FILES_REPOSITORY_URL) \
--build-arg KOPANO_WEBAPP_MDM_REPOSITORY_URL=$(KOPANO_WEBAPP_MDM_REPOSITORY_URL) \
--build-arg KOPANO_WEBAPP_REPOSITORY_URL=$(KOPANO_WEBAPP_REPOSITORY_URL) \
--build-arg KOPANO_WEBAPP_SMIME_REPOSITORY_URL=$(KOPANO_WEBAPP_SMIME_REPOSITORY_URL) \
--build-arg KOPANO_ZPUSH_REPOSITORY_URL=$(KOPANO_ZPUSH_REPOSITORY_URL) \
--build-arg DOWNLOAD_COMMUNITY_PACKAGES=$(DOWNLOAD_COMMUNITY_PACKAGES) \
--build-arg ADDITIONAL_KOPANO_PACKAGES=$(ADDITIONAL_KOPANO_PACKAGES) \
--build-arg ADDITIONAL_KOPANO_WEBAPP_PLUGINS=$(ADDITIONAL_KOPANO_WEBAPP_PLUGINS) \
--build-arg KOPANO_UID=$(KOPANO_UID) \
--build-arg KOPANO_GID=$(KOPANO_GID) \
--cache-from $(docker_repo)/kopano_$(component):builder \
--cache-from $(docker_repo)/kopano_$(component):latest \
--secret id=repocred,src=apt_auth.conf --progress=plain \
-t $(docker_repo)/kopano_$(component) $(component)/
build:
docker build --build-arg KOPANO_$(COMPONENT)_VERSION=${$(component)_download_version} -t $(docker_repo)/kopano_$(component) $(component)/
.PHONY: build-simple
build-simple: component ?= ssl
build-simple: ## Helper target to build a simplified image (no Kopano repo integration).
docker build --rm \
--build-arg VCS_REF=$(vcs_ref) \
--build-arg docker_repo=$(docker_repo) \
--cache-from $(docker_repo)/kopano_$(component):latest \
-t $(docker_repo)/kopano_$(component) $(component)/
.PHONY: build-builder
build-builder: component ?= kdav
build-builder: ## Helper target for images with a build stage.
ifdef TRAVIS
@echo "fetching previous build to warm up build cache (only on travis)"
docker pull $(docker_repo)/kopano_$(component):builder || true
endif
BUILDKIT_PROGRESS=plain DOCKER_BUILDKIT=1 docker build --rm \
--target builder \
--build-arg VCS_REF=$(vcf_ref) \
--build-arg docker_repo=${docker_repo} \
--build-arg KOPANO_CORE_VERSION=${core_download_version} \
--build-arg KOPANO_$(COMPONENT)_VERSION=${$(component)_download_version} \
--build-arg KOPANO_CORE_REPOSITORY_URL=$(KOPANO_CORE_REPOSITORY_URL) \
--build-arg KOPANO_MEET_REPOSITORY_URL=$(KOPANO_MEET_REPOSITORY_URL) \
--build-arg KOPANO_WEBAPP_REPOSITORY_URL=$(KOPANO_WEBAPP_REPOSITORY_URL) \
--build-arg KOPANO_WEBAPP_FILES_REPOSITORY_URL=$(KOPANO_WEBAPP_FILES_REPOSITORY_URL) \
--build-arg KOPANO_WEBAPP_MDM_REPOSITORY_URL=$(KOPANO_WEBAPP_MDM_REPOSITORY_URL) \
--build-arg KOPANO_WEBAPP_SMIME_REPOSITORY_URL=$(KOPANO_WEBAPP_SMIME_REPOSITORY_URL) \
--build-arg KOPANO_ZPUSH_REPOSITORY_URL=$(KOPANO_ZPUSH_REPOSITORY_URL) \
--build-arg DOWNLOAD_COMMUNITY_PACKAGES=$(DOWNLOAD_COMMUNITY_PACKAGES) \
--cache-from $(docker_repo)/kopano_$(component):builder \
-t $(docker_repo)/kopano_$(component):builder $(component)/
build-base: ## Build new base image.
docker pull debian:buster
build-base:
component=base make build
build-core: build-base
build-core:
component=core make build
build-core-dagent: build-core
docker build --rm \
-f core/Dockerfile.dagent \
--build-arg docker_repo=$(docker_repo) \
-t $(docker_repo)/kopano_dagent core/
build-helper:
component=build make build-simple
build-kapps: build-base
component=kapps make build
build-konnect:
component=konnect make build-simple
build-kwmbridge:
component=kwmbridge make build-simple
build-kwmserver:
component=kwmserver make build-simple
build-ldap:
component=ldap make build-simple
build-ldap-demo: build-ldap
component=ldap_demo make build-simple
build-meet: build-base
component=meet make build
build-php: build-base
component=php make build
build-playground:
component=playground make build-builder
component=playground make build-simple
build-python: build-base
component=python make build
build-kdav: build-php
docker pull composer:1.9
component=kdav make build-builder
component=kdav make build
build-scheduler:
docker pull docker:19.03
component=scheduler make build-simple
build-ssl:
docker pull alpine:3.11
component=ssl make build-simple
build-utils: build-core
component=utils make build
build-web:
component=web make build-simple
build-webapp: build-php
build-webapp:
component=webapp make build
build-webapp-demo: build-webapp ## Replaces the actual kopano_webapp container with one that has login hints for demo.kopano.com.
docker build --rm \
--build-arg docker_repo=$(docker_repo) \
-f webapp/Dockerfile.demo \
-t $(docker_repo)/kopano_webapp webapp/
build-ssl:
docker build -t $(docker_repo)/kopano_ssl ssl/
build-webapp-plugins: ## Example for a custom image to install Kopano WebApp plugins
docker build --rm \
--build-arg docker_repo=$(docker_repo) \
-f webapp/Dockerfile.plugins \
-t $(docker_repo)/kopano_webapp webapp/
build-zpush: build-php
component=zpush make build
tag-all: build-all ## Helper target to create tags for all images.
make $(shell grep -o ^tag-.*: Makefile | grep -Ev 'tag-all|tag-container' | uniq | sed s/://g | xargs)
tag-container: component ?= base
tag-container: ## Helper target to tag a given image. Defaults to the base image.
tag: component ?= base
tag:
@echo 'create tag $($(component)_version)'
docker tag $(docker_repo)/kopano_$(component) $(docker_repo)/kopano_$(component):${$(component)_version}
@version=$($(component)_version); while [[ $$version == *.* ]]; do \
version=$${version%.*} ; \
docker tag $(docker_repo)/kopano_$(component) $(docker_repo)/kopano_$(component):$$version ; \
done
@echo $(docker_repo)/kopano_$(component):${$(component)_version} >> $(TAG_FILE)
@echo 'create tag latest'
docker tag $(docker_repo)/kopano_$(component) $(docker_repo)/kopano_$(component):latest
git commit -m 'ci: committing changes for $(component)' -- $(component) || true
git tag $(component)/${$(component)_version} || true
tag-base:
$(eval base_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_base))
component=base make tag-container
component=base make tag
tag-core:
$(eval core_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_core | cut -d+ -f1))
component=core make tag-container
tag-dagent:
$(eval dagent_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_dagent | cut -d+ -f1))
component=dagent make tag-container
tag-kapps:
$(eval kapps_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_kapps | cut -d+ -f1))
component=kapps make tag-container
tag-konnect:
$(eval konnect_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_konnect))
component=konnect make tag-container
tag-kwmbridge:
$(eval kwmbridge_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_kwmbridge))
component=kwmbridge make tag-container
tag-kwmserver:
$(eval kwmserver_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_kwmserver))
component=kwmserver make tag-container
tag-ldap:
$(eval ldap_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_ldap))
component=ldap make tag-container
$(eval ldap_demo_version := $(ldap_version))
component=ldap_demo make tag-container
tag-meet:
$(eval meet_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_meet | cut -d+ -f1))
component=meet make tag-container
tag-php:
$(eval php_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_php | cut -d- -f1))
component=php make tag-container
tag-python:
$(eval python_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_python | cut -d- -f1))
component=python make tag-container
tag-scheduler:
$(eval scheduler_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_scheduler))
component=scheduler make tag-container
tag-ssl:
$(eval ssl_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_ssl))
component=ssl make tag-container
tag-utils:
$(eval utils_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_utils | cut -d- -f1))
component=utils make tag-container
tag-web:
$(eval web_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_web))
component=web make tag-container
component=core make tag
tag-webapp:
$(eval webapp_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_webapp | cut -d+ -f1))
component=webapp make tag-container
tag-zpush:
$(eval zpush_version := \
$(shell docker inspect --format '{{ index .Config.Labels "org.label-schema.version"}}' $(docker_repo)/kopano_zpush | cut -d+ -f1))
component=zpush make tag-container
component=webapp make tag
# Docker publish
repo-login:
docker login -u $(docker_login) -p $(docker_pwd)
.PHONY: publish
publish:
make $(shell grep -o ^publish-.*: Makefile | grep -Ev 'publish-container' | uniq | sed s/://g | xargs)
publish: repo-login publish-ssl publish-base publish-core publish-webapp
git push
git push origin --tags
publish-container: component ?= base
publish-container: ## Helper target to push a given image to a registry. Defaults to the base image.
publish-container:
@echo 'publish latest to $(docker_repo)/kopano_$(component)'
docker push $(docker_repo)/kopano_$(component):${$(component)_version}
@version=$($(component)_version); while [[ $$version == *.* ]]; do \
version=$${version%.*} ; \
docker push $(docker_repo)/kopano_$(component):$$version ; \
done
ifdef PUBLISHLATEST
docker push $(docker_repo)/kopano_$(component):latest
endif
#ifdef DOCKERREADME
# bash .ci/docker-hub-helper.sh $(component)
#endif
publish-base: tag-base
publish-base: build-base tag-base
component=base make publish-container
publish-core: tag-core
publish-core: build-core tag-core
component=core make publish-container
publish-dagent: tag-dagent
component=dagent make publish-container
publish-helper:
docker push $(docker_repo)/kopano_build:latest
publish-kapps: tag-kapps
component=kapps make publish-container
publish-konnect: tag-konnect
component=konnect make publish-container
publish-kwmbridge: tag-kwmbridge
component=kwmbridge make publish-container
publish-kwmserver: tag-kwmserver
component=kwmserver make publish-container
publish-ldap: tag-ldap
component=ldap make publish-container
publish-ldap-demo: tag-ldap
component=ldap_demo make publish-container
publish-meet: tag-meet
component=meet make publish-container
publish-php: tag-php
component=php make publish-container
publish-playground:
docker push $(docker_repo)/kopano_playground:latest
docker push $(docker_repo)/kopano_playground:builder
publish-python: tag-python
component=python make publish-container
publish-kdav: #tag-kdav
docker push $(docker_repo)/kopano_kdav:latest
docker push $(docker_repo)/kopano_kdav:builder
publish-scheduler: tag-scheduler
component=scheduler make publish-container
publish-ssl: tag-ssl
component=ssl make publish-container
publish-utils: tag-utils
component=utils make publish-container
publish-web: tag-web
component=web make publish-container
publish-webapp: tag-webapp
publish-webapp: build-webapp tag-webapp
component=webapp make publish-container
publish-zpush: tag-zpush
component=zpush make publish-container
lint:
git ls-files | xargs eclint check
grep -rIl '^#![[:blank:]]*/bin/\(bash\|sh\|zsh\)' \
--exclude-dir=.git --exclude=*.sw? \
| xargs shellcheck -x
git ls-files --exclude='*.yml' --ignored | xargs --max-lines=1 yamllint
# List files which name starts with 'Dockerfile'
# eg. Dockerfile, Dockerfile.build, etc.
git ls-files --exclude='Dockerfile*' --ignored | xargs --max-lines=1 hadolint
.PHONY: clean
clean:
docker ps --filter name=kopano_test* -aq | xargs docker rm -f || true
docker-compose -f $(DOCKERCOMPOSE_FILE) down -v --remove-orphans || true
.PHONY: clean-all-images
clean-all-images:
docker rmi $$(docker images --format '{{.Repository}}:{{.Tag}}' | grep '${docker_repo}/kopano_') | grep -v '<none>'
.PHONY: clean-all-containers
clean-all-containers:
docker ps -a | awk '{ print $$1,$$2 }' | grep '$(docker_repo)/kopano_' | awk '{print $$1 }' | xargs -I {} docker rm {}
.PHONY: test
test: ## Build and start new containers for testing (also deletes existing data volumes).
docker-compose -f $(DOCKERCOMPOSE_FILE) down -v --remove-orphans || true
make build-all
docker-compose -f $(DOCKERCOMPOSE_FILE) build
docker-compose -f $(DOCKERCOMPOSE_FILE) up -d
docker-compose -f $(DOCKERCOMPOSE_FILE) ps
test-update-env: ## Recreate containers based on updated .env.
docker-compose -f $(DOCKERCOMPOSE_FILE) up -d
.PHONY: test-ci
test-ci: test-startup
.PHONY: test-startup
test-startup: clean ## Test if all containers start up
docker-compose -f $(DOCKERCOMPOSE_FILE) -f tests/test-container.yml build
docker-compose -f $(DOCKERCOMPOSE_FILE) up -d
docker-compose -f $(DOCKERCOMPOSE_FILE) ps
docker-compose -f $(DOCKERCOMPOSE_FILE) -f tests/test-container.yml run test || \
(docker-compose -f $(DOCKERCOMPOSE_FILE) -f tests/test-container.yml ps; \
docker-compose -f $(DOCKERCOMPOSE_FILE) -f tests/test-container.yml logs -t --tail=50; \
docker-compose -f $(DOCKERCOMPOSE_FILE) -f tests/test-container.yml stop; \
docker ps --filter name=kopano_test* -aq | xargs docker rm -f; \
exit 1)
docker-compose -f $(DOCKERCOMPOSE_FILE) -f tests/test-container.yml stop 2>/dev/null
docker ps --filter name=kopano_test* -aq | xargs docker rm -f
.PHONY: test-startup-meet-demo
test-startup-meet-demo: ## Test if the Meet demo setup starts up
docker-compose -f examples/meet/docker-compose.yml -f examples/meet/tests/test-container.yml build
docker-compose -f examples/meet/docker-compose.yml up -d
docker-compose -f examples/meet/docker-compose.yml ps
docker-compose -f examples/meet/docker-compose.yml -f examples/meet/tests/test-container.yml run test || \
(docker-compose -f examples/meet/docker-compose.yml -f examples/meet/tests/test-container.yml ps; \
docker-compose -f examples/meet/docker-compose.yml -f examples/meet/tests/test-container.yml logs -t --tail=20; \
docker-compose -f examples/meet/docker-compose.yml -f examples/meet/tests/test-container.yml stop; \
docker ps --filter name=kopano_test* -aq | xargs docker rm -f; \
exit 1)
docker-compose -f examples/meet/docker-compose.yml -f examples/meet/tests/test-container.yml stop 2>/dev/null
docker ps --filter name=kopano_test* -aq | xargs docker rm -f
.PHONY: test-startup-individual
test-startup-individual:
docker run -it --rm -e DEBUG=true -v /etc/machine-id:/etc/machine-id -v /etc/machine-id:/var/lib/dbus/machine-id kopano/kopano_konnect
# TODO this needs goss added to travis and dcgoss pulled from my own git repo
.PHONY: test-goss
test-goss: ## Test configuration of containers with goss
GOSS_FILES_PATH=core/goss/server dcgoss run kopano_server
GOSS_FILES_PATH=core/goss/dagent dcgoss run kopano_dagent
GOSS_FILES_PATH=core/goss/gateway dcgoss run kopano_gateway
GOSS_FILES_PATH=core/goss/ical dcgoss run kopano_ical
GOSS_FILES_PATH=core/goss/grapi dcgoss run kopano_grapi
GOSS_FILES_PATH=core/goss/kapi dcgoss run kopano_kapi
GOSS_FILES_PATH=core/goss/monitor dcgoss run kopano_monitor
GOSS_FILES_PATH=core/goss/search dcgoss run kopano_search
GOSS_FILES_PATH=core/goss/spooler dcgoss run kopano_spooler
GOSS_FILES_PATH=meet dcgoss run kopano_meet
GOSS_FILES_PATH=scheduler dcgoss run kopano_scheduler
GOSS_FILES_PATH=webapp dcgoss run kopano_webapp
test-commander: ## Test scripts with commander
commander test tests/commander.yaml
COMMANDER_OPTS="--concurrent 1" COMMANDER_FILES_PATH=core/commander/server dccommander run kopano_server
COMMANDER_OPTS="--concurrent 1" COMMANDER_FILES_PATH=core/commander/spooler dccommander run kopano_spooler
COMMANDER_OPTS="--concurrent 1" COMMANDER_FILES_PATH=core/commander/grapi dccommander run kopano_grapi
COMMANDER_OPTS="--concurrent 1" COMMANDER_FILES_PATH=webapp dccommander run kopano_webapp
COMMANDER_OPTS="--concurrent 1" COMMANDER_FILES_PATH=zpush dccommander run kopano_zpush
COMMANDER_OPTS="--concurrent 1" COMMANDER_FILES_PATH=konnect dccommander run kopano_konnect
COMMANDER_OPTS="--concurrent 1" COMMANDER_FILES_PATH=scheduler dccommander run kopano_scheduler
# this test will fail if you are not on a whitelisted ip
commander test tests/commander-supported.yaml || true
test-security: ## Scan containers with Trivy for known security risks (not part of CI workflow for now).
cat $(TAG_FILE) | xargs -I % sh -c 'trivy --exit-code 0 --severity HIGH --quiet --auto-refresh %'
cat $(TAG_FILE) | xargs -I % sh -c 'trivy --exit-code 1 --severity CRITICAL --quiet --auto-refresh %'
rm $(TAG_FILE)
test-quick: ## Similar to test target, but does not delete existing data volumes and does not rebuild images.
docker-compose -f $(DOCKERCOMPOSE_FILE) stop || true
docker-compose -f $(DOCKERCOMPOSE_FILE) up -d
docker-compose -f $(DOCKERCOMPOSE_FILE) ps
test-stop:
docker-compose -f $(DOCKERCOMPOSE_FILE) stop || true
publish-ssl: build-ssl
docker push $(docker_repo)/kopano_ssl:latest

443
README.md
View File

@ -1,196 +1,321 @@
# (unofficial) Kopano Docker Images
# Kopano Docker Image
Unofficial kopano docker images for all kopano services.
Use kopano_core image for server/spooler/dagent/search/monitor/ical/gateway services.
Use kopano_webapp for web service.
[![Build Status](https://travis-ci.com/zokradonh/kopano-docker.svg?branch=master)](https://travis-ci.com/zokradonh/kopano-docker)
Building
=======
You may use `build.sh` script but you can also invoke `docker build` directly to build community or supported kopano components.
Currently there are the following components implemented by this project:
- core (server/spooler/dagent/search/monitor/ical/gateway services)
- webapp (apache server for kopano webapp and z-push)
This repository contains an easy to replicate recipe to spin up a [Kopano](https://kopano.com/) demo environment, which can (through modification of `.env` and possibly `docker-compose.yml`/`docker-compose.override.yml`) also be used for production environments.
### Building community Kopano
Example:
## How to get started?
`docker build https://github.com/zokradonh/kopano-docker.git#:core`
- make sure that you are running at least Docker 17.06.0 and [Docker Compose](https://docs.docker.com/compose/install/) 1.19.0.
- clone this repository to your local disk
- run `setup.sh`:
- this script will ask you a few questions about your environment
- If you are just interested in the demo environment you can accept the default values by pressing `Enter` on each question
- now run `docker-compose up` and you will see how the remaining Docker images are pulled and then everything is started
- after startup has succeeded you can access the Kopano WebApp by going to `https://kopano.demo/webapp`
- there are already some users created in the demo LDAP
- these users all have a password that is identical to the username, e.g. the password for `user1` user `user1`
- to build own containers at least Docker 19.03 is required
- this is due to the usage of build-time secrets
Or use the build.sh script:
If you want to get an impression how the containers interact/relate with each other have a look at the [architecture](ARCHITECTURE.md) description.
`build.sh -c core`
**Note:** There have been reports about the LDAP demo not starting up on MacOS. It is recommended to use a Linux OS if you want to use the bundled LDAP image.
### Building supported Kopano
If you have an active Kopano subscription you need specify the following build time arguments:
- KOPANO_CORE_REPOSITORY_URL to `https://serial:<YOURSERIAL>@download.kopano.io/supported/core:/final/Debian_9.0`
- RELEASE_KEY_DOWNLOAD to 1
- DOWNLOAD_COMMUNITY_PACKAGES to 0
The `docker-compose.yml` file by default pulls Docker containers from for example https://hub.docker.com/r/zokradonh/kopano_core/ and https://hub.docker.com/r/zokradonh/kopano_webapp/. These images are based on the [Kopano nightly builds](https://download.kopano.io/community/) and will contain the latest version available from the time the image was built.
Example:
## Troubleshooting
`docker build --build-arg KOPANO_CORE_REPOSITORY_URL=https://serial:ABC123456789@download.kopano.io/supported/core:/final/Debian_9.0 --build-arg RELEASE_KEY_DOWNLOAD=1 --build-arg DOWNLOAD_COMMUNITY_PACKAGES=0 https://github.com/zokradonh/kopano-docker.git#:core`
If you are running into a problem please include the following issues in the description of your report:
Or use the build.sh script:
- the error message produced when running `docker-compose up`
- or the output of `docker-compose ps`
- for failed containers the output of `docker-compose logs $containername`
- the contents of your `.env`
- either the output of `docker-compose config` (only useful when `docker-compose up` succeeds) or your `docker-compose.yml`
- the output of `docker -v` and `docker-compose -v`
`build.sh -c core -s ABC123456789 -b final`
Please make sure to remove sensitive data (for example your real hostname or passwords for accounts) when posting these information publicly.
If you have problems or questions about Kopano in general then either get in contact with the [Kopano support](https://kopano.com/support-info/) (if you have a valid subscription) or start a topic on the [Kopano forum](https://forum.kopano.io/).
## Updating
The used `docker-compose.yml` is part of the git versioning. Which mean all changes in this repository will also be applied to your local data once you pull in the latest version. If you need to configure additional env variables, this can now be done in the additional env files (more details further below, for example for `kopano_server` this file is called `kopano_server.env`). If you only want to run a subset of containers it is recommended to create a copy of `docker-compose.yml` and specify your copy when running. e.g. like `docker-compose -f my-setup.yml up -d`.
## Is this project also interesting for me when I already have a (non-Docker) Kopano environment?
Yes, indeed. You could for example use this to easily try out newer Kopano WebApp or Z-Push releases, without touching your production environment. Through the `zokradonh/kopano_core` image you could even try out newer version of e.g. `kopano-gateway` without jumping into a dependency mess in your production environment.
And last but not least this project also offers a `zokradonh/kopano_utils` image to easily run tools such as `kopano-backup`, `kopano-migration-pst`, `kopano-migration-imap` and all the other utilities that are bundles with Kopano. See [below](#some-more-commands-for-those-unfamiliar-with-docker-compose) to see how to run `zokradonh/kopano_utils`.
### Additional configuration / Need to adjust any values after the initial run of `setup.sh`?
If you want to modify some of the values from the `setup.sh` run you can simply edit `.env` in your favorite editor. Repeated runs of `setup.sh` will neither modify `docker-compose.yml` nor `.env`. In the ´.env´ file you will also find some given defaults like LDAP query filters and the local ports for the reverse proxy.
Additionally a dedicated env file is created for each container (at least where that would make sense). The env file has the container name as part of the file name. For example for the `kopano_server` container the filename is named `kopano_server.env`. These additional env files are auto created when running `setup.sh`.
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.
The compose file itself is part of the git repository and should not be edited directly. Instead a `docker-compose.override.yml` file (will be ignored by git) can be created to override and extend the default one. See https://docs.docker.com/compose/extends/ for more information.
#### Why is my compose override file ignored?
This project uses the `COMPOSE_FILE` environment variable to allow users to override the ports exposed by each container (for example when using a different front facing proxy). When using a `docker-compose.override.yml` file make sure this is included in this variable in the `.env` file. For example like this:
```bash
COMPOSE_FILE=docker-compose.yml:docker-compose.portmapping.yml:docker-compose.override.yml
```
#### I've pulled in the latest version, but now I cannot reach Kopano over the network any longer!
This project switched to specifying `COMPOSE_FILE` in `.env` to allow users to easily disable individual ports exposed. Please rerun `setup.sh` to add this variable to your `.env` file or add it manually.
### How to use a newer version than the one available from the Docker Hub?
In this repository you can also find a Makefile that automates the process of building newer images.
You can easily rebuild all images based on the currently available Kopano version by running `make build-all`. To just rebuild a certain image you can also run `make build-core` or `make build-webapp`. Please check the `Makefile` to see other possible targets. (depending on your environment you may also be able to autocomplete with the `Tab` key)
To be able to easily go back to a previous version you can also "tag" you Docker images by running e.g. `make tag-core`.
### Recurring tasks and maintenance tasks within Kopano
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.
Please check the `README.md` of the scheduler image for further instructions.
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.
### How to use the project with the official and supported Kopano releases?
This project also makes it possible to build Docker images based on the official Kopano releases. For this the following section needs to be modified in `.env`:
```bash
# Docker Repository to push to/pull from
docker_repo=zokradonh
COMPOSE_PROJECT_NAME=kopano
COMPOSE_FILE=docker-compose.yml:docker-compose.ports.yml:docker-compose.db.yml:docker-compose.ldap.yml:docker-compose.mail.yml
# Modify below to build a different version, than the Kopano nightly release
# credentials for repositories are handled through a file called apt_auth.conf (which will be created through setup.sh or Makefile)
#KOPANO_CORE_REPOSITORY_URL=https://download.kopano.io/supported/core:/8.7/Debian_10/
#KOPANO_MEET_REPOSITORY_URL=https://download.kopano.io/supported/meet:/final/Debian_10/
#KOPANO_WEBAPP_REPOSITORY_URL=https://download.kopano.io/supported/webapp:/final/Debian_10/
#KOPANO_WEBAPP_FILES_REPOSITORY_URL=https://download.kopano.io/supported/files:/final/Debian_10/
#KOPANO_WEBAPP_MDM_REPOSITORY_URL=https://download.kopano.io/supported/mdm:/final/Debian_10/
#KOPANO_WEBAPP_SMIME_REPOSITORY_URL=https://download.kopano.io/supported/smime:/final/Debian_10/
#KOPANO_ZPUSH_REPOSITORY_URL=https://download.kopano.io/zhub/z-push:/final/Debian_10/
#DOWNLOAD_COMMUNITY_PACKAGES=0
```
The credentials for the Kopano package repositories can either be defined through the url itself, e.g. like `https://serial:REPLACE-ME@download.kopano.io/supported/core:/final/Debian_10/` or through an `apt_auth.conf` file. Using `apt_auth.conf` is preferred, since it does not "leak" credentials into the final image.
With the above lines uncommented and credentials in place running `make build-all` will rebuild the images based on the latest available Kopano release (don't forget to `make tag-core` and `make tag-webapp` your images after building them).
If you are running a private Docker Registry then you have to change `docker_repo` to reference your internal registry. Afterward you can run for example `make publish-core` to push the image to your registry.
Replace `ABC123456789` with your serial.
---
***WARNING***
When storing the credentials in the url the built image will include your subscription key! Do not push this image to any public registry like e.g. https://hub.docker.com!
The built image now includes your serial. Do not push this image to any public registry like `hub.docker.com`.
### When building my own containers, how can I make sure my build works as expected?
---
Please check the [contributing information](CONTRIBUTING.md).
Example
=======
### What if I want to use a different front facing proxy than the one in docker-compose? Or just some part of the compose file?
docker-compose.yml
```YAML
version: '3'
While using kweb is recommended, this is of course possible.
services:
Please check the individual web containers (kDAV, WebApp and Z-Push for individual instructions).
kserver:
image: zokradonh/kopano_core:${CORE_VERSION}
hostname: kserver
container_name: kopano_server
links:
- db
depends_on:
- "kssl"
environment:
- SERVICE_TO_START=server
- TZ=Europe/Berlin
- KCCONF_SERVER_COREDUMP_ENABLED=no
- KCCONF_SERVER_LOG_LEVEL=4
- KCCONF_SERVER_MYSQL_HOST=db
- KCCONF_SERVER_MYSQL_PORT=3306
- KCCONF_SERVER_MYSQL_DATABASE=kopano
- KCCONF_SERVER_MYSQL_USER=root
- KCCONF_SERVER_MYSQL_PASSWORD=YOUR_MYSQL_ROOT_PASSWORD #change here
- KCCONF_SERVER_SERVER_SSL_KEY_FILE=/kopano/ssl/kserver.pem
- KCCONF_SERVER_SERVER_SSL_CA_FILE=/kopano/ssl/ca.pem
- KCCONF_SERVER_SSLKEYS_PATH=/kopano/ssl/clients
- KCCONF_SERVER_PROXY_HEADER=* # delete line if webapp is not behind reverse proxy
- KCCONF_SERVER_SYSTEM_EMAIL_ADDRESS=hostmaster@domain.tld #change here
- KCCONF_SERVER_DISABLED_FEATURES=pop3
- KCCONF_SERVER_SEARCH_SOCKET=http://ksearch:2380/
- KCCONF_LDAP_LDAP_URI=ldaps://ldapserver:ldapport #change here
- KCCONF_LDAP_LDAP_BIND_USER=cn=SOME_STANDARD_USER,OU=MyUsers,DC=domain,DC=tld #change here
- KCCONF_LDAP_LDAP_BIND_PASSWD=PASSWORD_OF_STANDARD_USER #change here
- KCCONF_LDAP_LDAP_SEARCH_BASE=OU=MyUsers,dc=domain,dc=tld #change here
- KCCOMMENT_LDAP_1=!include /usr/share/kopano/ldap.openldap.cfg #delete if you want openldap
- KCUNCOMMENT_LDAP_1=!include /usr/share/kopano/ldap.active-directory.cfg #delete if you want openldap
networks:
- kopanonet
volumes:
- data:/kopano/data
- sslcerts:/kopano/ssl
### How can I prevent e.g. `kopano-gateway` to be reachable from the network?
kdagent:
image: zokradonh/kopano_core:${CORE_VERSION}
container_name: kopano_dagent
links:
- kserver
volumes:
- sslcerts:/kopano/ssl
environment:
- SERVICE_TO_START=dagent
- TZ=Europe/Berlin
- KCCONF_DAGENT_LOG_LEVEL=6
- KCCONF_DAGENT_SERVER_SOCKET=https://kserver:237/
- KCCONF_DAGENT_SSLKEY_FILE=/kopano/ssl/kdagent.pem
networks:
- kopanonet
The exposed ports of each container are defined in `docker-compose.ports.yml`. If you do not want to expose some of the containers to the network, it is recommended to copy this file to `docker-compose.override.yml`and just remove all entries that you do not want to have exposed.
kgateway:
image: zokradonh/kopano_core:${CORE_VERSION}
container_name: kopano_gateway
links:
- kserver
volumes:
- ./gatewaycerts/:/kopano/certs/
environment:
- SERVICE_TO_START=gateway
- TZ=Europe/Berlin
- KCCONF_GATEWAY_SERVER_SOCKET=http://kserver:236/
- KCCONF_GATEWAY_SSL_PRIVATE_KEY_FILE=/kopano/certs/yourcert.key # change here
- KCCONF_GATEWAY_SSL_CERTIFICATE_FILE=/kopano/certs/yourcert.pem # change here
networks:
- kopanonet
### I want to use these Docker images outside of an evaluation environment. What do I need to adjust to make this possible?
kical:
image: zokradonh/kopano_core:${CORE_VERSION}
container_name: kopano_ical
links:
- kserver
environment:
- SERVICE_TO_START=ical
- TZ=Europe/Berlin
- KCCONF_ICAL_SERVER_SOCKET=http://kserver:236/
networks:
- kopanonet
To get a quick impression of Kopano this git repository bundles a locally build LDAP image with some example users. When using the docker-compose.yml in a production environment make sure to:
kmonitor:
image: zokradonh/kopano_core:${CORE_VERSION}
container_name: kopano_monitor
links:
- kserver
volumes:
- sslcerts:/kopano/ssl
environment:
- SERVICE_TO_START=monitor
- TZ=Europe/Berlin
- KCCONF_MONITOR_SERVER_SOCKET=https://kserver:237/
- KCCONF_MONITOR_SSLKEY_FILE=/kopano/ssl/kmonitor.pem
networks:
- kopanonet
- switch to the non-demo ldap tree or completely remove the local LDAP from the compose file
- adapt LDAP queries in .env to match you actual LDAP server and users
- all additional configuration of the Kopano components should be specified in the compose file/the env file/an override and **not within the running container**
- make sure that there is a unique machine-id for your deployment
- the default setup mounts the file from the host, if your host is running multiple installations of Kopano make sure to generate a unique value for each installation.
ksearch:
image: zokradonh/kopano_core:${CORE_VERSION}
container_name: kopano_search
links:
- kserver
volumes:
- sslcerts:/kopano/ssl
environment:
- SERVICE_TO_START=search
- TZ=Europe/Berlin
- KCCONF_SEARCH_SERVER_BIND_NAME=http://ksearch:2380
- KCCONF_SEARCH_SERVER_SOCKET=https://kserver:237/
- KCCONF_SEARCH_SSLKEY_FILE=/kopano/ssl/ksearch.pem
networks:
- kopanonet
#### Can I combine these Docker images with my existing environment?
kspooler:
image: zokradonh/kopano_core:${CORE_VERSION}
container_name: kopano_spooler
links:
- kserver
volumes:
- sslcerts:/kopano/ssl
environment:
- SERVICE_TO_START=spooler
- TZ=Europe/Berlin
- KCCONF_SPOOLER_SERVER_SOCKET=https://kserver:237/
- KCCONF_SPOOLER_LOG_LEVEL=4
- KCCONF_SPOOLER_SMTP_SERVER=kmta
- KCCONF_SPOOLER_SSLKEY_FILE=/kopano/ssl/kspooler.pem
networks:
- kopanonet
Yes, that is certainly a possibility. Within the `examples/` directory you can find some ready to run examples that can be run in the following way:
kwebapp:
image: zokradonh/kopano_webapp:${WEBAPP_VERSION}
hostname: kwebapp
container_name: kopano_webapp
links:
- kserver
#ports:
# - "8236:80"
# - "8237:443"
volumes:
- syncstates:/var/lib/z-push/
- sslcerts:/kopano/ssl
environment:
- TZ=Europe/Berlin
- KCCONF_SERVERHOSTNAME=kserver
- KCCONF_SERVERPORT=237
networks:
- web
- kopanonet
- `docker-compose -f examples/webapp.yml up -d`
kssl:
image: zokradonh/kopano_ssl
container_name: kopano_ssl
volumes:
- sslcerts:/kopano/ssl
### Some more commands for those unfamiliar with docker-compose
kmta:
image: tvial/docker-mailserver:latest
hostname: myhost #change here
domainname: domain.tld #change here
#dns: 127.0.0.1
container_name: kopano_mta
#links:
# - adtunnel
ports:
- "25:25"
# - "143:143"
# - "587:587"
# - "993:993"
volumes:
- tmpmaildata:/var/mail
- tmpmailstate:/var/mail-state
- ./mtaconfig/:/tmp/docker-mailserver/ # create this dir
environment:
- TZ=Europe/Berlin
- ENABLE_SPAMASSASSIN=1
- ENABLE_CLAMAV=1
- ENABLE_FAIL2BAN=1
- ENABLE_POSTGREY=1
- TLS_LEVEL=intermediate
- POSTGREY_DELAY=10
- ONE_DIR=1
- DMS_DEBUG=0
- ENABLE_LDAP=1
- LDAP_SERVER_HOST=ldaps://ldapserver:ldapport #change here
- LDAP_SEARCH_BASE=OU=MyUsers,DC=domain,DC=tld #change here
- LDAP_BIND_DN=cn=SOME_STANDARD_USER,OU=MyUsers,DC=domain,DC=tld #change here
- LDAP_BIND_PW=PASSWORD_OF_SOME_STANDARD_USER #change here
- LDAP_QUERY_FILTER_USER=(&(objectClass=user)(|(mail=%s)(otherMailbox=%s)))
- LDAP_QUERY_FILTER_GROUP=(&(objectclass=group)(mail=%s))
- LDAP_QUERY_FILTER_ALIAS=(&(objectClass=user)(otherMailbox=%s))
- LDAP_QUERY_FILTER_DOMAIN=(&(|(mail=*@%s)(otherMailbox=*@%s)(mailGroupMember=*@%s))(kopanoAccount=1)(|(objectClass=user)(objectclass=group)))
- ENABLE_SASLAUTHD=1
- SASLAUTHD_LDAP_SERVER=ldaps://ldapserver:ldapport #change here
- SASLAUTHD_LDAP_BIND_DN=cn=SOME_STANDARD_USER,OU=MyUsers,DC=domain,DC=tld #change here
- SASLAUTHD_LDAP_PASSWORD=PASSWORD_OF_SOME_STANDARD_USER #change here
- SASLAUTHD_LDAP_SEARCH_BASE=OU=MyUsers,DC=domain,DC=tld #change here
- SASLAUTHD_LDAP_FILTER=(&(sAMAccountName=%U)(objectClass=person))
- SASLAUTHD_MECHANISMS=ldap
- POSTMASTER_ADDRESS=postmaster@domain.tld #change here
- SMTP_ONLY=1
- PERMIT_DOCKER=network
- ENABLE_POSTFIX_VIRTUAL_TRANSPORT=1
- POSTFIX_DAGENT=lmtp:kdagent:2003
- REPORT_RECIPIENT=1
networks:
- kopanonet
cap_add:
- NET_ADMIN
- SYS_PTRACE
- Start ``docker-compose.yml`` file in the background: `docker-compose up -d`
- Get a status overview of the running containers: `docker-compose ps`
- Stop compose running in the background: `docker-compose stop`
- Destroy local containers and network interfaces: `docker-compose down`
- Destroy volumes as well (will completely reset the containers, **deletes all data**): `docker-compose down -v`
- Run commands in a running container: `docker-compose exec kopano_server kopano-admin -l`
- Get logs of a in the background running container: `docker-compose logs -f kopano_server`
- Run a `kopano-backup`: `docker run --rm -it -v /var/run/kopano/:/var/run/kopano -v $(pwd):/kopano/path zokradonh/kopano_utils kopano-backup`
- Same command but getting volumes from the existing `kopano_server` container: `docker run --rm -it --volumes-from kopano_server -v /root/kopano-backup:/kopano/path zokradonh/kopano_utils kopano-backup -h`
- Get a shell in a new container to (for example) run `kopano-migration-pst`: `docker run --rm -it -v /var/run/kopano/:/var/run/kopano -v $(pwd):/kopano/path zokradonh/kopano_utils` (to directly run kopano-migration-pst just append it to the command)
db:
image: mariadb
restart: always
container_name: kopano_db
volumes:
- db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=YOUR_MYSQL_ROOT_PASSWORD #change here
- MYSQL_PASSWORD=YOUR_PASSWORD #change here
- MYSQL_DATABASE=kopano
- MYSQL_USER=kopano
networks:
- kopanonet
### Try this project without installing Docker locally
volumes:
db:
data:
syncstates:
sslcerts:
tmpmaildata:
tmpmailstate:
This project includes a configuration file for [Vagrant](https://www.vagrantup.com/) to easily try kopano-docker locally. All that is required is Vagrant itself and Virtualbox.
Steps to start kopano-docker in Vagrant:
```bash
# run setup.sh
$ ./setup.sh
# provision virtual machine
$ vagrant up
# alternatively "vagrant up --provider hyperv" when running on Windows
# in case you want to connect into the machine
$ vagrant ssh
networks:
web: # this requires an external docker container that is a http reverse proxy (e.g. haproxy)
external:
name: haproxy_webrproxynet
kopanonet:
driver: bridge
```
After the machine has started it will be reachable from the local system through the IP `10.16.73.20`, please make sure that your chosen hostname resolves to this IP. The project files are mounted to `/vagrant` in the machine. To interact with the containers just change into this directory first.
Requires haproxy network for http reverse proxy.
Change all lines which are commented especially those with #change here
## Third party docker images
This is just a quick example docker-compose.yml made in some minutes to provide a better start.
The example `docker-compose.yml` uses the following components for the MTA (mail delivery, including anti-spam & anti-virus) and openLDAP. Please consult their documentation for further configuration advice.
Requires `.env` file next to docker-compose.yml with content like this
```INI
CORE_VERSION=8.6.80.1055-0plus156.1
WEBAPP_VERSION=3.4.17.1565plus895.1
```
- https://github.com/tomav/docker-mailserver/
- https://github.com/osixia/docker-openldap
- https://github.com/osixia/docker-phpLDAPadmin
Requires `ldap-groups.cf` in ./mtaconfig directory next to docker-compose.yml
```INI
bind = yes
bind_dn = cn=admin,dc=domain,dc=com
bind_pw = admin
query_filter = (&(mailGroupMember=%s)(mailEnabled=TRUE))
result_attribute = mail
search_base = ou=people,dc=domain,dc=com
server_host = mail.domain.com
start_tls = no
version = 3
leaf_result_attribute = mail
special_result_attribute = member
```
Now group members of Active Directory groups can be found by postfix.
## Further reading
The following (blog) articles have been written about this project:
- https://kopano.com/blog/building-docker-containers-for-kopano/
- https://kopano.com/blog/using-docker-to-spin-up-a-kopano-environment/
Furthermore you can use this directory for opendkim - see kmta's image for details.

33
Vagrantfile vendored
View File

@ -1,33 +0,0 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
if !Vagrant.has_plugin?("vagrant-docker-compose")
print " WARN: Missing plugin 'vagrant-docker-compose'.\n"
print " Use 'vagrant plugin install vagrant-docker-compose' to install.\n"
end
config.vm.box = "hashicorp/bionic64"
config.vm.provider "virtualbox" do |v|
v.memory = 4096
v.cpus = 2
end
config.vm.network "private_network", ip: "10.16.73.20"
config.vm.provision :docker
config.vm.provision :docker_compose
config.vm.provision :shell, :path => "./.ci/setup-tools.sh"
config.vm.provision "app",
type: "shell",
keep_color: true,
privileged: false,
run: "always",
inline: <<-SCRIPT
cd /vagrant
docker-compose up --detach
SCRIPT
end

View File

@ -1,36 +1,17 @@
FROM debian:buster
ARG ADDITIONAL_KOPANO_PACKAGES=""
ARG DOWNLOAD_COMMUNITY_PACKAGES=1
ARG KOPANO_CORE_REPOSITORY_URL="file:/kopano/repo/core"
ARG KOPANO_CORE_VERSION=newest
ARG KOPANO_REPOSITORY_FLAGS=""
# Both UID and GID should not be set to values above 999
ARG KOPANO_UID=999
ARG KOPANO_GID=999
ENV \
AUTOCONFIGURE=true \
BASE_VERSION=2.2.0 \
DEBIAN_FRONTEND=noninteractive \
DEBUG=""
FROM debian:stretch
LABEL maintainer=az@zok.xyz \
org.label-schema.name="Kopano base container" \
org.label-schema.description="Base image for containers running the Kopano groupware stack" \
org.label-schema.url="https://kopano.io" \
org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \
org.label-schema.version=$BASE_VERSION \
org.label-schema.schema-version="1.0"
version="2.0"
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
RUN mkdir -p /kopano/repo /kopano/data /kopano/helper /kopano/path
RUN mkdir -p /kopano/repo /kopano/data /kopano/helper
WORKDIR /kopano/repo
ARG DEBIAN_FRONTEND=noninteractive
# install basics
# TODO require python3 or python3-minimal?
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install --no-install-recommends -y \
apt-transport-https \
apt-utils \
@ -38,54 +19,32 @@ RUN apt-get update && \
curl \
dumb-init \
gpg \
gpg-agent \
jq \
locales \
moreutils \
python3-minimal \
python3 \
&& \
rm -rf /var/cache/apt /var/lib/apt/lists/*
rm -rf /var/cache/apt /var/lib/apt/lists
# Create kopano user and group
RUN groupadd --system --gid ${KOPANO_GID} kopano
RUN useradd --system --shell /usr/sbin/nologin --home /var/lib/kopano --gid ${KOPANO_GID} --uid ${KOPANO_UID} kopano
ENV DOCKERIZE_VERSION v0.11.6
RUN curl -sfL https://github.com/powerman/dockerize/releases/download/"$DOCKERIZE_VERSION"/dockerize-"$(uname -s)"-"$(uname -m)" \
| install /dev/stdin /usr/local/bin/dockerize && \
dockerize --version
ENV GOSS_VERSION v0.3.11
RUN curl -L https://github.com/aelsabbahy/goss/releases/download/$GOSS_VERSION/goss-linux-amd64 -o /usr/local/bin/goss && \
chmod +rx /usr/local/bin/goss && \
goss --version
# if additional locales are required this should be adjusted here
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
sed -i -e 's/# de_DE.UTF-8 UTF-8/de_DE.UTF-8 UTF-8/' /etc/locale.gen && \
sed -i -e 's/# nl_NL.UTF-8 UTF-8/nl_NL.UTF-8 UTF-8/' /etc/locale.gen && \
dpkg-reconfigure --frontend=noninteractive locales && \
update-locale LANG=en_US.UTF-8
ENV DOCKERIZE_VERSION v0.6.1
RUN curl -L https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz | tar xzvf - -C /usr/local/bin
ARG ADDITIONAL_KOPANO_PACKAGES=""
ARG DOWNLOAD_COMMUNITY_PACKAGES=1
ARG KOPANO_CORE_REPOSITORY_URL="file:/kopano/repo/core"
ARG KOPANO_CORE_VERSION=newest
ARG KOPANO_REPOSITORY_FLAGS="trusted=yes"
ARG KOPANO_WEBAPP_REPOSITORY_URL="file:/kopano/repo/webapp"
ARG KOPANO_WEBAPP_VERSION=newest
ARG RELEASE_KEY_DOWNLOAD=0
# get common utilities
COPY create-kopano-repo.sh /kopano/helper/
COPY kcconf.py Release.key defaultconfigs/ /kopano/
RUN apt-key add /kopano/Release.key
RUN date +%s > /kopano/buildversion
SHELL [ "/bin/bash", "-c"]
ONBUILD ARG DOWNLOAD_COMMUNITY_PACKAGES=1
ONBUILD ARG DOWNLOAD_DISTRIBUTION="Debian_10"
ONBUILD ARG DOWNLOAD_CHANNEL="community"
ONBUILD ARG DOWNLOAD_BRANCH=""
ONBUILD WORKDIR /kopano/repo
ONBUILD RUN \
# community download and package as apt source repository
. /kopano/helper/create-kopano-repo.sh && \
if [ ${DOWNLOAD_COMMUNITY_PACKAGES} -eq 1 ]; then \
dl_and_package_community "core" "$DOWNLOAD_DISTRIBUTION" "$DOWNLOAD_CHANNEL" "$DOWNLOAD_BRANCH"; \
dl_and_package_community "kapps" "$DOWNLOAD_DISTRIBUTION" "$DOWNLOAD_CHANNEL" "$DOWNLOAD_BRANCH"; \
fi
ARG VCS_REF
LABEL org.label-schema.vcs-ref=$VCS_REF

View File

@ -1,5 +0,0 @@
# Kopano base image
[![](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")
Common base for Kopano images. Predefines arguments and prepares fetching of Kopano packages and building of a local repository (when using nightly downloads).

View File

@ -1,51 +0,0 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBFcjak8BEACl/9+3+hgGmkIgn/G8dzfo4BY8gRtLdQkFPw/dhvZWGznvFkdY
GbSdIbcFNp8uMKva8P75rIq5XSYAU8o21gjoGuVSi55MB/JNnR22whpXHnx3Os2i
pkoFZEWqGoW/7CWAk6QVOpVK+0UXEaXTkuEKVsB+hRL9wRQNpcWN8M894/I5egGB
b1gPD9OFMTlHEVjLYFLUwGeMCSpcTU4kHu93g7S/s2xVng31xlZ2FqUgUT2GWTrR
YfPuNib0srIZXwsqmVMJdu4qx3FoIJeAd3KH11fbb2oZEmwGKYfULoATGQ6s9/nG
wVR2aJPPgZJv2YIpoE4CqKixj8ll6yc6DWzp2dOOj/4JJvpdpeO3Vu3dMy+8qBsR
VlsCRKAFJLkmnliaUxtGM3oH3URb8LSnLXWPrvDB3sEq4o5mRxooqcwzi5FQ8bvG
jzoqdw4NWIuH24Y7cC80X7o28qmN+DxySkeOtMQ9hVxYhK+bab3kw9Q9KCIT70r6
YsCPX2+5RSBDpWI4bmP/3xMD2EUsdZBZYx79Qccai9+Syhw+GgIC/Yj9tdK8++5D
XJWxTZLhYBAfoI3RsOmx38Yg9Z8fFF2l43jgveFORrv0EMcWBrJTtvLEXBPdCjBi
AYBhAsuku/Kc6/zXrbWOYnmtxiYqjiqsyOXFdXat9Vw163rup2UoGjw8sQARAQAB
tCpLb3Bhbm8gRGV2ZWxvcG1lbnQgPGRldmVsb3BtZW50QGtvcGFuby5pbz6JAlYE
EwEKAEACGwMHCwkIBwMCAQYVCAIJCgsEFgIDAQIeAQIXgBYhBN83ibzrIZneCNdD
pVyyfhNY4vKnBQJginN3BQkLSDyoAAoJEFyyfhNY4vKn3r0P/jgOS9vhQKR9a633
D/Ydmbc9vGNb8802SCbVdH5IhHWeVzthrJ2tHwtYoCknpfAu+K1F2OZ0upFcTvxn
qJbGnvd9UGq37o7boWic2RdLywOm5iru3YqFZXAfvtIMpGsfk7rc+ZH5SnQiRxrJ
WO8b3dM8tW+rpvUKaG7UBc613Uqki8L98cUdhZrnvEl3AaaU7OjZmdu4X6+sayWG
/bvlWcvtmJF3rNtDtZCtxf4iBgWxTKa8RkVV4XErhWtqn3vigxIspErCX0t6JY+v
RCWSjBU1abeysVmW9+p4g+hxRxwQ+u2FNrsKdjMeh0nWa1517NSKuGDMT52JoPpI
nukY0UxjvJ+0NuzM+J+0NpzG1as5eL0VU88v3bOmVyzvK9Bcrqrxxy3o5bmGVUUv
P+7uo0Mmt5RO48Pv2bc+NN7RTO5lG8MqyHSBjqoRRRJnv7YIuH4Rao8GuvoVWlAW
I2y31ed29TSsUtYbBODgtyPgydrpaj+REUj97LDXt4J1a7vvsm79GN3QQUjFP9NK
Rc+uSjkUj5HR4cgonn7ABVfTSRHQ/Y5x/DbZIY8D8aGXewErfUYLk0ekN4yoOyth
i4V5nx1BhQ+vSigqkL18ZBy+esf4nLu78PpXp2+H3C3+oV1/ahyFdjFD6BqkcR7d
/MmZlaWM9tKS84biyRFUuwb+y55auQINBFcjak8BEADNzyS331yQ24nQFMRb5TzT
ZBp/NnPtXrrdLDS5UdhwZMVMWJrQuweyl2NUlePq9J8/FarGktJnKALYzvSyAbyf
v9M9Nlm8pbFJPJUkEkt93zEGFmJGAhpSnBEOXIziugtD9lZnIQ1YN861PsojGYuC
J2Pl/HMi4mQEB9zcJ9SzqxjCS2DVD0S1hIjMrxrW3kTO8roSledHV59AkK0M6WxO
IunN6Wg29ys7VwYnqg1hXCrFP2jtqQHeD9zOmW9LnZ/UDTNfipXJVqfb04+OQLUa
LbD2HdzCLQcoIjwmOr3NZkbbXW0Luklzu6PRimLJ4mucz1ksAfFJqJAhF/0TjJiD
ZRn/7rwpR+m4bba8MIMmiRf6e+WlpVgKTYL26BwuCSpyHjIxutoXTBGZ2fT1by5R
/6Sl2cgQXGKJnNHWCla3sHVFvQmVMBenFFMjGel9l2bvl6I6Nyu5kxtD0rDynHMl
9OI2OklGzOLSlhioQnWabtoyu9glmEU+ofyNBe0BJmFJxH9jqvOwW2aMHW4NEMR1
pP7LNgLbgQ6Q1Q1WehK70TiCuH4d0WVVQ+dl/OrQSWWmqo8EDy590UJTk2uLH5mr
eamO0aVuw7GkwAoXoMowzGJjHP+bBWrDudfiLwZBpIHg2Ogct5ZxKpgr9Tx0hwix
qfTj4eO0m76j070/hvgRnQARAQABiQIlBBgBAgAPBQJXI2pPAhsMBQkJZgGAAAoJ
EFyyfhNY4vKnRC8P/jy75oYazCRhOjuNI7fPr2a546bjx4TCNMZPy3qnWg9qMwBx
8zNsx9cAg3dK4aQLN4vacPRZypVt4gKoGT2yalyVq+mE3roSAykjW+56efO6JGIP
/y7HyQb3F5tzbMJb55M1D0zeQJJLvCut2U0M9T8s9zii2N0MybUWgSEx/IHmTxO9
MEZoRBPjJkfRBnhpJ9jSiPthEutk2E+xMtti82RqWn5antUxdvZ+AXrn9VXxM1kU
VZy0OJZL4tPf4w3S+yGYjOte7BEhDus+8PA+srfdroSSA+891fGDojo2nFzC4a4M
vIPqutxy6Mu+WksRVA4w3E8WINuwEEpmsU/sWvSmJjaNu7EuZmTiF/gPapo8r6b1
XX3vtPE6UETsvnGn2IKjsAzHcdx5KYpGpXT75g46yRqvwk4b0wsVDA2/rXCTp4N9
yvINmZ0IcDqBG1RYwRdKjSN4TX+vPtu4ciDZTvTcgf7A2u/M/bc5MxZscjex6pno
/vS6N8yV71sGaKpQJOJNNU4NvdgnajWMJ9IVchwGWJFGuY89oSzW+D9MZcYKhJKg
U7N7JgDYUknY1xJpwT+XFjWBGbBjQAEQPQPcGerTCjRG9ijCsrytl2uRMGbFXueL
YmCVCErITLjX9gvcxPH38wxMkO6MQnrvNSV8dBGwhY2E0nJfBT/amTwXoNjm
=TAfQ
-----END PGP PUBLIC KEY BLOCK-----

View File

@ -1,23 +1,18 @@
#!/bin/bash
set -eu
[ "$DEBUG" ] && set -x
function urldecode { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
function version_from_filename {
basename "$1" | awk -F"-" '{print $2}'
echo "$1" | sed -r 's#[a-z]+-([0-9_.+]+)-.*#\1#'
}
function h5ai_query {
component=${1:-core}
distribution=${2:-Debian_10}
channel=${3:-community} # could either be community, supported or limited
branch=${4:-""} # could either be empty, "master/tarballs/", "pre-final/tarballs/" or "final/tarballs/"
filename=$(curl -s -XPOST "https://download.kopano.io/$channel/?action=get&items\[href\]=/$channel/$component:/$branch&items\[what\]=1" | \
jq -r '.items[].href' | \
grep "$distribution-all\|$distribution-amd64" | sed "s#/$channel/$component:/##" | sed "s#/$channel/$component%3A/##")
component="$1"
filename=$(curl -s -S -L -d "action=get&items%5Bhref%5D=%2Fcommunity%2F$component%3A%2F&items%5Bwhat%5D=1" -H \
"Accept: application/json" https://download.kopano.io/community/ | jq '.items[].href' | \
grep 'Debian_9.0-all\|Debian_9.0-amd64' | sed 's#"##g' | sed "s#/community/$component:/##")
if [ -z "${filename// }" ]; then
echo "unknown component"
@ -31,31 +26,22 @@ function h5ai_query {
function dl_and_package_community {
# take component as first argument and fallback to core if none given
component=${1:-core}
distribution=${2:-Debian_10}
channel=${3:-community}
branch=${4:-""}
if [ -d "$component" ]; then
echo "Packages have been downloaded in a previous stage. Skipping..."
return
fi
# query community server by h5ai API
filename=$(h5ai_query "$component" "$distribution" "$channel" "$branch")
filename2=$(basename "$filename")
filename=$(h5ai_query "$component")
# download & extract packages
curl -s -S -L -o "$filename2" https://download.kopano.io/"$channel"/"$component":/"${filename}"
tar xf "$filename2"
curl -s -S -L -o "$filename" https://download.kopano.io/community/"$component":/"${filename}"
tar xf "$filename"
# save buildversion
#currentVersion=$(version_from_filename "$filename")
#echo "$component-$currentVersion" >> /kopano/buildversion
currentVersion=$(version_from_filename "$filename")
echo "$component-$currentVersion" >> /kopano/buildversion
# save disk space
rm "$filename2"
rm "$filename"
mv "${filename2%.tar.gz}" "$component"
mv "${filename%.tar.gz}" "$component"
# prepare directory to be apt source
cd "$component"

View File

@ -1,5 +0,0 @@
#!/usr/bin/env python3
import kcconf
# Override configs from environment variables
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/"))

View File

@ -1,20 +0,0 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
DEBUG=true
WORK_DIR=$(mktemp -d)
component=${1:-core}
function cleanup {
rm -rf "$WORK_DIR"
echo "Deleted temp working directory $WORK_DIR"
}
trap cleanup EXIT
cd "$WORK_DIR"
# shellcheck source=base/create-kopano-repo.sh
. "$DIR"/create-kopano-repo.sh
dl_and_package_community "$component"

137
build.sh Executable file
View File

@ -0,0 +1,137 @@
#!/bin/bash
set -eu
branch="master"
buildcontext_base="https://github.com/zokradonh/kopano-docker.git#:"
customBuildArgs=()
serial=""
component=""
nocache=""
. ./common/common.sh
function _usage()
{
echo "Usage: build.sh -c core|webapp [-s serial] [-b master|final|pre-final] [-p buildcontext] [[-a buildarg] ...] [-i]"
echo "Example: build.sh -c core -s ABC123456789DEF -b final"
echo "-c The Kopano component to be built."
echo "-s Provide serial if you want to build from supported repository."
echo "-i Do not use cache on docker build."
echo "-b If no branch is specified, 'master' will be built by default."
echo "-p If no buildcontext is specified, it will be built from git repository. Normally, you do not need to specify this."
echo "-a You can specify custom build args via e.g. -a ADDITIONAL_KOPANO_PACKAGES=kopano-migration-imap"
}
while getopts ":s:c:b:p:a:i" opt; do
case $opt in
s)
serial=$OPTARG
;;
c)
component=${OPTARG,,}
;;
b)
branch=${OPTARG,,}
;;
p)
buildcontext_base=$OPTARG
;;
a)
customBuildArgs[${#customBuildArgs[*]}]=$OPTARG
;;
i)
nocache="--no-cache"
;;
\?)
_usage
exit 1
;;
:)
echo "Option -$OPTARG requires an argument."
exit 1
;;
esac
done
case "$component" in
core)
mainpackage="kopano-server"
;;
webapp)
mainpackage="kopano-webapp"
;;
*)
_usage
exit 1
esac
customBuildString=""
# prepare custom build args
if [[ ${customBuildArgs[@]:+${customBuildArgs[@]}} ]];
then
for buildArg in "${customBuildArgs[@]}"
do
customBuildString="$customBuildString --build-arg $buildArg"
done
fi
if [ ! -z "$serial" ]
then
# start build of supported kopano
# get current version to brand and tag the image correctly
currentVersion=$(curl -s -S -L "https://serial:$serial@download.kopano.io/supported/$component:/$branch/Debian_9.0/Packages.gz" |\
gzip -d | grep -A 8 "^Package: $mainpackage$" | awk '/Version/ { print $2 }')
# webapp also needs core repository
if [ "$component" == "webapp" ]
then
customBuildString="$customBuildString --build-arg KOPANO_CORE_REPOSITORY_URL=https://serial:$serial@download.kopano.io/supported/core:/$branch/Debian_9.0"
fi
echo "Start building supported kopano $component image version ($currentVersion)..."
set -x
# build it
if docker build --pull \
--build-arg "KOPANO_${component^^}_REPOSITORY_URL=https://serial:$serial@download.kopano.io/supported/$component:/$branch/Debian_9.0" \
--build-arg RELEASE_KEY_DOWNLOAD=1 \
--build-arg "DOWNLOAD_COMMUNITY_PACKAGES=0" \
--build-arg "KOPANO_${component^^}_VERSION=$currentVersion" \
-t "zokradonh/kopano_$component:${currentVersion//+/plus}" \
-t "zokradonh/kopano_$component:latest-$branch" \
$nocache \
$customBuildString \
"${buildcontext_base}${component}"
then
set +x
echo "Please note that this image does include your serial. If you publish this image then your serial is exposed to public."
fi
else
# start build of community kopano
if ! hash jq
then
echo "Please install jq in order to run this build script."
exit 1
fi
# query community server by h5ai API
filename=$(h5ai_query "$component")
currentVersion=$(version_from_filename "$filename")
echo "Start building community kopano $component image version ($currentVersion)..."
set -x
# build it
docker build --pull \
-t "zokradonh/kopano_$component:${currentVersion//+/plus}" \
-t "zokradonh/kopano_$component:latest-$branch" \
-t "zokradonh/kopano_$component:latest" \
--build-arg "KOPANO_${component^^}_VERSION=$currentVersion" \
$nocache \
$customBuildString \
"${buildcontext_base}${component}"
set +x
fi

View File

@ -1,36 +0,0 @@
FROM koalaman/shellcheck-alpine:v0.7.1 as shellcheck
FROM docker:19.03
ENV \
COMMANDER_VERSION=2.1.0 \
COMPOSE_VERSION=1.19.0 \
GOSS_VERSION=0.3.11 \
HADOLINT_VERSION=1.17.6 \
REG_VERSION=0.16.1 \
TRIVY_VERSION=0.1.1
LABEL maintainer=az@zok.xyz \
org.label-schema.name="Kopano Container Builder" \
org.label-schema.description="Helper Container to help building and testing containers" \
org.label-schema.url="https://kopano.io" \
org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker/build/" \
org.label-schema.version=1.0.0 \
org.label-schema.schema-version="1.0"
RUN apk add --no-cache bash curl coreutils git grep expect make nano npm jq py-pip
#RUN apk add --no-cache shellcheck --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community
COPY --from=shellcheck /bin/shellcheck /bin/shellcheck
RUN curl -fSL "https://github.com/genuinetools/reg/releases/download/v$REG_VERSION/reg-linux-amd64" -o "/usr/local/bin/reg" && \
curl -fSL "https://github.com/hadolint/hadolint/releases/download/v$HADOLINT_VERSION/hadolint-$(uname -s)-$(uname -m)" -o /usr/local/bin/hadolint && \
curl -fSL "https://github.com/docker/compose/releases/download/$COMPOSE_VERSION/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \
curl -fSL "https://github.com/aelsabbahy/goss/releases/download/v$GOSS_VERSION/goss-linux-amd64" -o /usr/local/bin/goss && \
curl -L "https://raw.githubusercontent.com/fbartels/goss/dcgoss-v2/extras/dcgoss/dcgoss" -o /usr/local/bin/dcgoss && \
curl -fSL "https://github.com/SimonBaeumer/commander/releases/download/v$COMMANDER_VERSION/commander-linux-amd64" -o /usr/local/bin/commander && \
curl -fSL "https://raw.githubusercontent.com/fbartels/dccommander/master/dccommander" -o /usr/local/bin/dccommander && \
pip install --no-cache-dir yamllint==1.19.0 && \
npm config set unsafe-perm true && \
npm install -g eclint@2.8.1 && \
chmod a+x /usr/local/bin/*
WORKDIR /kopano-docker
CMD ["bash"]

View File

@ -1,70 +0,0 @@
# Minimal build environment
Helper container for systems where build requirements (bash, curl, docker-compose, jq, make) are not available (for example on Synology)
Run the following command to enter the "build environment" (command may need to be run with `sudo` to work with the `docker` command):
```bash
$ ./run.sh
This script may need to be run as root to be able to use docker/docker-compose through it.
bash-4.4$
```
(the first time it will take a moment before the bash prompt is displayed, since the container is built locally first)
Afterwards you can execute the `setup.sh` script, modify `.env` to your liking and run any make commands:
```bash
bash-4.4# ./setup.sh
Creating an .env file for you
Which tag do you want to use for Kopano Core components? [latest]:
Which tag do you want to use for Kopano WebApp? [latest]:
Which tag do you want to use for Z-Push? [latest]:
Name of the Organisation for LDAP [Kopano Demo]:
FQDN to be used (for reverse proxy) [kopano.demo]:
Email address to use for Lets Encrypt. Use 'self_signed' as your email to create self signed certificates [self_signed]:
Name of the BASE DN for LDAP [dc=kopano,dc=demo]:
LDAP server to be used (defaults to the bundled OpenLDAP) [ldap://ldap:389]:
Timezone to be used [Europe/Berlin.]:
E-Mail Address displayed for the 'postmaster' [postmaster@kopano.demo]:
Name/Address of Database server (defaults to the bundled one) [db]:
Available options:
1 ) de-at
2 ) de-ch
3 ) de-de
4 ) en
5 ) en-gb
6 ) es
7 ) fr
8 ) it
9 ) nl
10 ) pl-pl
Check language spell support (again to uncheck, ENTER when done):
Available options:
1 ) contactfax
2 ) desktopnotifications
3 ) filepreviewer
4 ) files
5 ) filesbackend-smb
6 ) filesbackend-owncloud
7 ) folderwidgets
8 ) gmaps
9 ) intranet
10 ) mattermost
11 ) mdm
12 ) pimfolder
13 ) quickitems
14 ) smime
15 ) titlecounter
16 ) webappmanual
17 ) zdeveloper
Check for additional plugins (again to uncheck, ENTER when done):
Integrate WhatsApp into DeskApp yes/no [no]:
bash-4.4# make build-all
docker build -t zokradonh/kopano_ssl ssl/
Sending build context to Docker daemon 4.608kB
[...]
```
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.

View File

@ -1,16 +0,0 @@
#!/bin/sh
if [ ! "$(id -u)" -eq 0 ]; then
echo "This script may need to be run as root to be able to use docker/docker-compose through it."
fi
cd "$(dirname "$0")" || exit
docker pull zokradonh/kopano_build:latest || true
docker build --cache-from zokradonh/kopano_build:latest .
docker run \
--rm -it \
-u "$(id -u)":"$(id -g)" \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$(pwd)"/..:/kopano-docker/ \
"$(docker build --cache-from zokradonh/kopano_build:latest -q .)" "$@"

View File

@ -1,88 +1,49 @@
# syntax = docker/dockerfile:1.0-experimental
ARG docker_repo=zokradonh
FROM ${docker_repo}/kopano_base
FROM zokradonh/kopano_base
ARG ADDITIONAL_KOPANO_PACKAGES=""
ARG DOWNLOAD_COMMUNITY_PACKAGES=1
ARG KOPANO_REPOSITORY_FLAGS="trusted=yes"
ARG DEBIAN_FRONTEND=noninteractive
ARG KOPANO_CORE_REPOSITORY_URL="file:/kopano/repo/core"
ARG KOPANO_CORE_VERSION=newest
ARG KOPANO_KAPPS_REPOSITORY_URL="file:/kopano/repo/kapps"
ARG KOPANO_KAPPS_VERSION=newest
ARG KOPANO_REPOSITORY_FLAGS="trusted=yes"
ARG RELEASE_KEY_DOWNLOAD=0
ENV \
ADDITIONAL_KOPANO_PACKAGES=$ADDITIONAL_KOPANO_PACKAGES \
DOWNLOAD_BRANCH="" \
DOWNLOAD_CHANNEL="community" \
DOWNLOAD_COMMUNITY_PACKAGES=$DOWNLOAD_COMMUNITY_PACKAGES \
DOWNLOAD_DISTRIBUTION="Debian_10" \
GRAPI_BACKEND="kopano" \
KCCONF_GRAPI_LDAP_BASEDN="" \
KCCONF_GRAPI_LDAP_BINDDN="" \
KCCONF_GRAPI_LDAP_BINDPW_FILE="" \
KCCONF_GRAPI_LDAP_URI="" \
KOPANO_CONFIG_PATH=/tmp/kopano \
KOPANO_CORE_REPOSITORY_URL=$KOPANO_CORE_REPOSITORY_URL \
KOPANO_CORE_VERSION=$KOPANO_CORE_VERSION \
KOPANO_REPOSITORY_FLAGS=$KOPANO_REPOSITORY_FLAGS \
LANG=en_US.UTF-8 \
SERVICE_TO_START=server
LABEL maintainer=az@zok.xyz \
org.label-schema.name="Kopano Groupware Core container" \
org.label-schema.description="Container for running applications out of Kopano Groupware Core" \
org.label-schema.url="https://kopano.io" \
org.label-schema.vcs-url="https://github.com/zokradonh/kopano-docker" \
org.label-schema.version=$KOPANO_CORE_VERSION \
org.label-schema.schema-version="1.0"
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# install Kopano Core and refresh ca-certificates
# hadolint currently does not understand the extended buildkit syntax https://github.com/hadolint/hadolint/issues/347
# hadolint ignore=DL3015
RUN --mount=type=secret,id=repocred,target=/etc/apt/auth.conf.d/kopano.conf \
# apt key for this repo has already been installed in base
# install Kopano WebApp and refresh ca-certificates
RUN \
# community download and package as apt source repository
. /kopano/helper/create-kopano-repo.sh && \
if [ ${DOWNLOAD_COMMUNITY_PACKAGES} -eq 1 ]; then \
dl_and_package_community "core"; \
fi; \
echo "deb [${KOPANO_REPOSITORY_FLAGS}] ${KOPANO_CORE_REPOSITORY_URL} ./" > /etc/apt/sources.list.d/kopano.list; \
echo "deb [${KOPANO_REPOSITORY_FLAGS}] ${KOPANO_KAPPS_REPOSITORY_URL} ./" >> /etc/apt/sources.list.d/kopano.list; \
# save kopano version if supported kopano
if [ ! -f /kopano/buildversion ]; then \
echo "core-${KOPANO_CORE_VERSION}" > /kopano/buildversion; \
fi; \
# install apt key if supported kopano
if [ ${RELEASE_KEY_DOWNLOAD} -eq 1 ]; then \
curl -s -S -o - "${KOPANO_CORE_REPOSITORY_URL}/Release.key" | apt-key add -; \
fi; \
# install
apt-get update && \
set -x && \
apt-get -o Debug::pkgProblemResolver=true install --no-install-recommends -y \
kopano-server-packages kopano-spamd \
apt-get install --no-install-recommends -y \
kopano-server-packages \
${ADDITIONAL_KOPANO_PACKAGES} \
&& \
coreversion=$(dpkg-query --showformat='${Version}' --show kopano-server) && \
if dpkg --compare-versions "$coreversion" "gt" "8.7.0"; then \
# For grapi also install recommended packages
apt-get -o Debug::pkgProblemResolver=true install -y \
kopano-grapi kopano-kapid; \
fi && \
if dpkg --compare-versions "$coreversion" "gt" "8.7.84"; then \
apt-get -o Debug::pkgProblemResolver=true install --no-install-recommends -y \
python3-grapi.backend.ldap; \
fi && \
php7.0-cli && \
set +x && \
rm -rf /var/cache/apt /var/lib/apt/lists && \
touch /etc/kopano/admin.cfg && \
# with 9.0 config files are once again in /etc/kopano
(cp /usr/share/doc/kopano/example-config/*.cfg /etc/kopano/ || true) && \
(cp /usr/share/doc/kopano/example-config/*.cfg.gz /etc/kopano/ || true) && \
(gzip -d -f /etc/kopano/*.gz || true)
cp /usr/share/doc/kopano/example-config/*.cfg /etc/kopano/ && \
cp /usr/share/doc/kopano/example-config/*.cfg.gz /etc/kopano/ && \
gzip -d -f /etc/kopano/*.gz
COPY defaultconfigs/ start-service.sh healthcheck.sh /kopano/
COPY bin/ /usr/local/bin/
COPY goss/ /kopano/goss
ENV KOPANO_LOCALE="de_DE.UTF-8"
ENV KOPANO_USERSCRIPT_LOCALE="de_DE.UTF-8"
ENV LANG=en_US.UTF-8
WORKDIR /kopano/path
ENV SERVICE_TO_START=server
COPY kcconf.py defaultconfigs/ start-service.sh /kopano/
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD [ "/kopano/start-service.sh" ]
HEALTHCHECK --interval=1m --timeout=10s \
CMD /kopano/healthcheck.sh
ARG VCS_REF
LABEL org.label-schema.vcs-ref=$VCS_REF

View File

@ -1,6 +0,0 @@
ARG docker_repo=zokradonh
FROM ${docker_repo}/kopano_core
ENV \
EXE=/usr/sbin/kopano-dagent \
SERVICE_TO_START=dagent

View File

@ -1,50 +1,24 @@
# Kopano Core image
E-Mail attachment directory is by default in `/kopano/data/attachments/` so bind `/kopano/data` as volume.
[![](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")
You can reconfigure by setting environment variable `KCCONF_SERVER_ATTACHMENT_PATH`.
Image for components out of the "Kopano Core" repository. Is used to start containers for e.g. `kopano-server` and `kopano-gateway`.
You can change all server.cfg settings you like prefixed with `KCCONF_SERVER_`
So specify `KCCONF_SERVER_MYSQL_HOST` for `mysql_host` setting in `server.cfg`.
Or specify `KCCONF_LDAP_LDAP_SEARCH_BASE` to set `ldap_search_base` in `ldap.cfg`.
E-Mail attachment directory is by default in `/kopano/data/attachments/` it is recommended to bind `/kopano/data` as volume.
Attachment location can be configured by setting the environment variable `KCCONF_SERVER_ATTACHMENT_PATH`.
All configuration can be adjusted dynamically through environment variables.
```bash
KCCONF_SERVER_MYSQL_HOST=127.0.0.1
^ ^ ^ ^
| | | |
General prefix |
| | |
Name of the relevant configuration file (server.cfg in this case)
| |
Name of the configuration option in the configuration file
|
Value of the configuration option
```
Examples:
- specify `KCCONF_SERVER_MYSQL_HOST` for `mysql_host` setting in `server.cfg`
- specify `KCCONF_LDAP_LDAP_SEARCH_BASE` to set `ldap_search_base` in `ldap.cfg`
Additionally it is possible to comment specific options in/out with `KCCOMMENT_filenameWithoutExtension_anystring=searchline`
You may override default settings with `KCCONF_*` options or comment specific options in/out with `KCCOMMENT_filenameWithoutExtension_anystring=searchline`
e.g. `KCCOMMENT_LDAP_1=!include /usr/share/kopano/ldap.openldap.cfg`
For core dumps on crashes kopano-server requires the `fs.suid_dumpable sysctl` to contain the value 2, not 0.
For coredumps on crashes kopano-server requires the fs.suid_dumpable sysctl to contain the value 2, not 0.
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.
The docker image kopano_ssl will create certificates for all containers. Those certificates are selfsigned and only for internal Kopano component communication.
kopano_webapp port 80 is meant to be published through a https reverse proxy. MAPI connection for Outlook is also handled over port 80.
Maybe you need to execute `kopano-cli --list-users` once after initial install in the kopano_server container.
See: https://documentation.kopano.io/kopanocore_administrator_manual/configure_kc_components.html#testing-ldap-configuration
Example:
`docker-compose exec kopano_server kopano-admin -l`
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.
See https://documentation.kopano.io/kopanocore_administrator_manual/configure_kc_components.html#testing-ldap-configuration for more information.
## Ports & Proxying
- kopano-server is configured to listen on the ports 236 (plain) and 237 (https)
- 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
- 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).
`docker-compose exec kserver kopano-cli --list-users` (This may last very long without any console output.)

View File

@ -1,3 +0,0 @@
#!/bin/bash
/usr/sbin/kopano-autorespond -C "$KOPANO_CONFIG_PATH/autorespond.cfg" "$@"

View File

@ -1,8 +0,0 @@
#!/bin/bash
if [ ! -f /usr/sbin/kopano-cli ]; then
echo "kopano-cli has been removed from Kopano Groupware Core 10 and upwards. Please use kopano-admin instead."
exit 1
fi
/usr/sbin/kopano-cli --config "$KOPANO_CONFIG_PATH/admin.cfg" "$@"

View File

@ -1,83 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
try:
import kopano
except ImportError:
import zarafa as kopano
from MAPI.Util import *
import binascii
def opt_args():
parser = kopano.parser('skpcf')
parser.add_option("--user", dest="user", action="store", help="Username")
parser.add_option("--public", dest="public", action="store_true", help="Show public folders")
parser.add_option("--delete", dest="delete", action="store", help="Delete folder based on entryid")
parser.add_option("--extend", dest="extend", action="store_true", help="show more values")
return parser.parse_args()
def printprop(typename, item):
if typename == 'PT_MV_BINARY':
listItem = []
for i in item:
listItem.append(str(binascii.hexlify(i)).upper())
return listItem
if typename == 'PT_OBJECT':
return None
if typename == 'PT_BINARY':
return str(binascii.hexlify(item)).upper()
if typename == 'PT_UNICODE':
try:
return item.encode('utf-8').decode()
except:
return item
else:
return item
def printmapiprops(folder):
props = []
for prop in folder.props():
if hex(prop.proptag) == "0x10130102L":
props.append([prop.id_, prop.idname, hex(prop.proptag), prop.typename, printprop(prop.typename, prop.value), prop.value])
else:
props.append([prop.id_, prop.idname, hex(prop.proptag), prop.typename, printprop(prop.typename, prop.value)])
return props
def main():
options, args = opt_args()
if not options.user and not options.public:
print('Please use\n' \
'%s --user <username> or\n' \
'%s --public' % (sys.argv[0], sys.argv[0]))
sys.exit(1)
if options.user:
user = kopano.server(options).user(options.user)
store = user.store
name = user.name
if options.public:
name = 'Public'
store = kopano.server(options).public_store
if not options.delete:
print('Store:', name.encode('utf-8').decode())
print('{:50} {:50} {:50}'.format('Folder name', 'Parent folder', 'Entryid'))
for folder in store.root.folders():
print('{:50} {:50} {:50}'.format(folder.name.encode('utf8').decode(), folder.parent.name.encode('utf8').decode(), folder.entryid))
if options.extend:
props = printmapiprops(folder)
f = open('%s-%s.prop' % (folder.name, folder.entryid), 'w')
for prop in props:
f.write('{0:5} {1:37} {2:8} {3:10} {4:1}\n'.format(prop[0], prop[1], prop[2], prop[3], prop[4]))
f.close()
else:
print('Not in yet')
if __name__ == "__main__":
main()

View File

@ -1,17 +0,0 @@
tests:
start-service script:
command: bash -c "shopt -s expand_aliases; alias exec='echo'; . /kopano/start-service.sh && env"
exit-code: 0
stdout:
contains:
- enable_experimental_endpoints=true
config:
env:
KCCONF_GRAPI_ENABLE_EXPERIMENTAL_ENDPOINTS: true
config:
env:
DEBUG: ${DEBUG}
GRAPI_BACKEND: ${GRAPI_BACKEND}
LANG: ${LANG}
SERVICE_TO_START: ${SERVICE_TO_START}
PATH: ${PATH}

View File

@ -1,124 +0,0 @@
tests:
start-service script:
command: bash -c "shopt -s expand_aliases; alias exec='echo'; . /kopano/start-service.sh"
exit-code: 0
stdout:
not-contains:
- "Reading package lists..."
start-service script (installing new package):
command: bash -c "shopt -s expand_aliases; alias exec='echo'; . /kopano/start-service.sh"
exit-code: 0
stdout:
contains:
- "Setting up nano"
config:
env:
ADDITIONAL_KOPANO_PACKAGES: "nano"
start-service script (installing existing package):
command: bash -c "shopt -s expand_aliases; alias exec='echo'; . /kopano/start-service.sh"
exit-code: 0
stdout:
contains:
- "INFO: kopano-server is already installed"
config:
env:
ADDITIONAL_KOPANO_PACKAGES: "kopano-server"
generate configuration for kopano-server:
command: bash -c "shopt -s expand_aliases; alias exec='echo'; . /kopano/start-service.sh" && cat /tmp/kopano/server.cfg
exit-code: 0
stdout:
contains:
- server_listen_tls = 0.0.0.0:237
- server_ssl_key_file = /kopano/ssl/kopano_server.pem
not-contains:
- #server_listen_tls = *:237
generate ldap configuration openLDAP (default):
command: bash -c "shopt -s expand_aliases; alias exec='echo'; . /kopano/start-service.sh" && cat /tmp/kopano/ldap.cfg
exit-code: 0
stdout:
contains:
- "!include /usr/share/kopano/ldap.openldap.cfg"
- "#!include /usr/share/kopano/ldap.active-directory.cfg"
not-contains:
- "#!include /usr/share/kopano/ldap.openldap.cfg"
generate ldap configuration for ADS:
command: bash -c "shopt -s expand_aliases; alias exec='echo'; . /kopano/start-service.sh" && cat /tmp/kopano/ldap.cfg
exit-code: 0
stdout:
contains:
- "#!include /usr/share/kopano/ldap.openldap.cfg"
- "!include /usr/share/kopano/ldap.active-directory.cfg"
not-contains:
- "#!include /usr/share/kopano/ldap.active-directory.cfg"
config:
env:
KCCOMMENT_LDAP_1: "!include /usr/share/kopano/ldap.openldap.cfg"
KCUNCOMMENT_LDAP_1: "!include /usr/share/kopano/ldap.active-directory.cfg"
start-service script default locale:
command: bash -c "shopt -s expand_aliases; alias exec='echo'; . /kopano/start-service.sh && locale -a"
exit-code: 0
stdout:
contains:
- C
- C.UTF-8
- de_DE.utf8
- en_US.utf8
- nl_NL.utf8
- POSIX
start-service script no dockerize:
command: bash -c "shopt -s expand_aliases; alias exec='echo'; . /kopano/start-service.sh"
exit-code: 0
stdout:
not-contains:
- dockerize
config:
env:
DISABLE_CHECKS: "true"
start-service script no config updates:
command: bash -c "shopt -s expand_aliases; alias exec='echo'; . /kopano/start-service.sh"; grep log_level /etc/kopano/server.cfg
exit-code: 0
stdout:
not-contains:
- log_level = 0x0000006
config:
env:
KCCONF_SERVER_LOG_LEVEL: "0x0000006"
DISABLE_CONFIG_CHANGES: "true"
# TODO this needs an extension to dcommander to pass tests/test-container.yml as an additional file
#start-service script write protected server.cfg:
# command: chattr +i /etc/kopano/server.cfg; bash -c "shopt -s expand_aliases; alias exec='echo'; . /kopano/start-service.sh"; chattr +i /etc/kopano/server.cfg
# exit-code: 0
# stderr:
# contains:
# - Can't open
# - ignoring file changes
config:
env:
DEBUG: ${DEBUG}
GRAPI_BACKEND: ${GRAPI_BACKEND}
KCCOMMENT_LDAP_1: ${KCCOMMENT_LDAP_1}
KCCONF_LDAP_LDAP_BIND_PASSWD: ${KCCONF_LDAP_LDAP_BIND_PASSWD}
KCCONF_LDAP_LDAP_BIND_USER: ${KCCONF_LDAP_LDAP_BIND_USER}
KCCONF_LDAP_LDAP_SEARCH_BASE: ${KCCONF_LDAP_LDAP_SEARCH_BASE}
KCCONF_LDAP_LDAP_URI: ${KCCONF_LDAP_LDAP_URI}
KCCONF_SERVER_COREDUMP_ENABLED: ${KCCONF_SERVER_COREDUMP_ENABLED}
KCCONF_SERVER_ENABLE_SSO: ${KCCONF_SERVER_ENABLE_SSO}
KCCONF_SERVER_HIDE_EVERYONE: ${KCCONF_SERVER_HIDE_EVERYONE}
KCCONF_SERVER_KCOIDC_INSECURE_SKIP_VERIFY: ${KCCONF_SERVER_KCOIDC_INSECURE_SKIP_VERIFY}
KCCONF_SERVER_KCOIDC_ISSUER_IDENTIFIER: ${KCCONF_SERVER_KCOIDC_ISSUER_IDENTIFIER}
KCCONF_SERVER_LOG_LEVEL: ${KCCONF_SERVER_LOG_LEVEL0
KCCONF_SERVER_MYSQL_DATABASE: ${KCCONF_SERVER_MYSQL_DATABASE}
KCCONF_SERVER_MYSQL_HOST: ${KCCONF_SERVER_MYSQL_HOST}
KCCONF_SERVER_MYSQL_PASSWORD: ${KCCONF_SERVER_MYSQL_PASSWORD}
KCCONF_SERVER_MYSQL_PORT: ${KCCONF_SERVER_MYSQL_PORT}
KCCONF_SERVER_MYSQL_USER: ${KCCONF_SERVER_MYSQL_USER}
KCCONF_SERVER_PROXY_HEADER: ${KCCONF_SERVER_PROXY_HEADER}
KCCONF_SERVER_SERVER_NAME: ${KCCONF_SERVER_SERVER_NAME}
KCCONF_SERVER_SERVER_SSL_CA_FILE: ${KCCONF_SERVER_SERVER_SSL_CA_FILE}
KCCONF_SERVER_SERVER_SSL_KEY_FILE: ${KCCONF_SERVER_SERVER_SSL_KEY_FILE}
KCCONF_SERVER_SSLKEYS_PATH: ${KCCONF_SERVER_SSLKEYS_PATH}
KCCONF_SERVER_SYSTEM_EMAIL_ADDRESS: ${KCCONF_SERVER_SYSTEM_EMAIL_ADDRESS}
KCUNCOMMENT_LDAP_1: ${KCUNCOMMENT_LDAP_1}
LANG: ${LANG}
SERVICE_TO_START: ${SERVICE_TO_START}
PATH: ${PATH}

View File

@ -1,12 +0,0 @@
tests:
test sending mail:
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
exit-code: 0
stdout:
contains:
- "250 2.0.0 Ok: queued as"
config:
env:
PATH: ${PATH}
KCCONF_SPOOLER_SMTP_SERVER: ${KCCONF_SPOOLER_SMTP_SERVER}

11
core/defaultconfigs/dagent.py Executable file → Normal file
View File

@ -1,14 +1,15 @@
#!/usr/bin/env python3
import os
import kcconf
# Component specific configurations
kcconf.configkopano({
r"/tmp/kopano/dagent.cfg":
r"/etc/kopano/dagent.cfg":
{
# Certain configuration can be pre-defined at startup:
#'lmtp_listen': "0.0.0.0:2003",
'log_file': "-",
'log_level': "4",
'tmp_path': "/tmp/dagent/"
}
})
# Override configs from environment variables
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/"))
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/etc/kopano/"))

14
core/defaultconfigs/gateway.py Executable file → Normal file
View File

@ -1,14 +1,18 @@
#!/usr/bin/env python3
import os
import kcconf
# Component specific configurations
kcconf.configkopano({
r"/tmp/kopano/gateway.cfg":
r"/etc/kopano/gateway.cfg":
{
# Certain configuration can be pre-defined at startup:
#'imap_listen': "0.0.0.0:143",
'log_file': "-",
'log_level': "4",
'tmp_path': "/tmp/gateway/",
'pop3_listen': "",
'imap_listen': "",
'imaps_listen': "*:993"
}
})
# Override configs from environment variables
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/"))
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/etc/kopano/"))

View File

@ -1,5 +0,0 @@
#!/usr/bin/env python3
import kcconf
# Override configs from environment variables
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/"))

10
core/defaultconfigs/ical.py Executable file → Normal file
View File

@ -1,14 +1,14 @@
#!/usr/bin/env python3
import os
import kcconf
# Component specific configurations
kcconf.configkopano({
r"/tmp/kopano/ical.cfg":
r"/etc/kopano/ical.cfg":
{
# Certain configuration can be pre-defined at startup:
#'ical_listen': "0.0.0.0:8080",
'log_file': "-",
'log_level': "4"
}
})
# Override configs from environment variables
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/"))
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/etc/kopano/"))

View File

@ -1,14 +0,0 @@
#!/usr/bin/env python3
import kcconf
# Component specific configurations
kcconf.configkopano({
r"/tmp/kopano/kapid.cfg":
{
# Certain configuration can be pre-defined at startup:
#'listen': "0.0.0.0:8039",
}
})
# Override configs from environment variables
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/"))

10
core/defaultconfigs/monitor.py Executable file → Normal file
View File

@ -1,14 +1,14 @@
#!/usr/bin/env python3
import os
import kcconf
# Component specific configurations
kcconf.configkopano({
r"/tmp/kopano/monitor.cfg":
r"/etc/kopano/monitor.cfg":
{
# Certain configuration can be pre-defined at startup:
#'log_level': "4"
'log_file': "-",
'log_level': "4"
}
})
# Override configs from environment variables
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/"))
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/etc/kopano/"))

10
core/defaultconfigs/search.py Executable file → Normal file
View File

@ -1,14 +1,14 @@
#!/usr/bin/env python3
import os
import kcconf
# Component specific configurations
kcconf.configkopano({
r"/tmp/kopano/search.cfg":
r"/etc/kopano/search.cfg":
{
# Certain configuration can be pre-defined at startup:
#'index_path': "/kopano/data/search/"
'log_file': "-",
'log_level': "4"
}
})
# Override configs from environment variables
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/"))
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/etc/kopano/"))

14
core/defaultconfigs/server.py Executable file → Normal file
View File

@ -1,14 +1,18 @@
#!/usr/bin/env python3
import os
import kcconf
# Component specific configurations
kcconf.configkopano({
r"/tmp/kopano/server.cfg":
r"/etc/kopano/server.cfg":
{
# Certain configuration can be pre-defined at startup:
#'server_listen': "0.0.0.0:236",
'log_file': "-",
'log_level': "3",
'attachment_path': "/kopano/data/attachments/",
'user_plugin': "ldap",
'server_listen': "",
'server_listen_tls': "*:237"
}
})
# Override configs from environment variables
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/"))
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/etc/kopano/"))

View File

@ -1,15 +0,0 @@
#!/usr/bin/env python3
import os
import kcconf
# Component specific configurations
kcconf.configkopano({
r"/tmp/kopano/spamd.cfg":
{
# Certain configuration can be pre-defined at startup:
#'log_level': "3"
}
})
# Override configs from environment variables
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/"))

11
core/defaultconfigs/spooler.py Executable file → Normal file
View File

@ -1,14 +1,15 @@
#!/usr/bin/env python3
import os
import kcconf
# Component specific configurations
kcconf.configkopano({
r"/tmp/kopano/spooler.cfg":
r"/etc/kopano/spooler.cfg":
{
# Certain configuration can be pre-defined at startup:
#'log_level': "4",
'log_file': "-",
'log_level': "4",
'tmp_path': "/tmp/spooler/"
}
})
# Override configs from environment variables
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/tmp/kopano/"))
kcconf.configkopano(kcconf.parseenvironmentvariables(r"/etc/kopano/"))

View File

@ -1,6 +0,0 @@
port:
tcp:2003:
listening: true
process:
kopano-dagent:
running: true

View File

@ -1,6 +0,0 @@
port:
tcp:2003:
listening: true
process:
kopano-dagent:
running: true

View File

@ -1,3 +0,0 @@
process:
kopano-gateway:
running: true

View File

@ -1,3 +0,0 @@
process:
kopano-gateway:
running: true

View File

@ -1,20 +0,0 @@
file:
/var/lib/kopano-grapi:
exists: true
mode: "0755"
size: 4096
owner: kapi
group: kopano
filetype: directory
/var/run/kopano/grapi:
exists: true
mode: "0755"
owner: kapi
group: kopano
filetype: directory
mount:
/var/lib/kopano-grapi:
exists: true
opts:
- rw
- relatime

View File

@ -1,7 +0,0 @@
file:
/var/run/kopano/grapi:
exists: true
mode: "0755"
owner: kapi
group: kopano
filetype: directory

View File

@ -1,3 +0,0 @@
process:
kopano-ical:
running: true

View File

@ -1,3 +0,0 @@
process:
kopano-ical:
running: true

View File

@ -1,3 +0,0 @@
process:
kapid:
running: true

View File

@ -1,3 +0,0 @@
process:
kapid:
running: true

View File

@ -1,3 +0,0 @@
process:
kopano-monitor:
running: true

View File

@ -1,3 +0,0 @@
process:
kopano-monitor:
running: true

View File

@ -1,9 +0,0 @@
file:
/var/run/kopano/search.sock:
exists: true
mode: "0700"
size: 0
owner: kopano
group: kopano
filetype: socket
contains: []

View File

@ -1,9 +0,0 @@
file:
/var/run/kopano/search.sock:
exists: true
mode: "0700"
size: 0
owner: kopano
group: kopano
filetype: socket
contains: []

View File

@ -1,33 +0,0 @@
file:
# TODO how to make path dynamic?
/kopano/data/attachments/:
exists: true
mode: "0755"
owner: kopano
group: kopano
filetype: directory
/run/kopano/prio.sock:
exists: true
mode: "0660"
owner: kopano
group: kopano
filetype: socket
/run/kopano/server.sock:
exists: true
mode: "0666"
owner: kopano
group: kopano
filetype: socket
process:
kopano-server:
running: true
http:
# TODO what if plain http is deactivated? (or uses a different port?)
http://localhost:236:
status: 405
timeout: 5000
# TODO what if ssl is deactivated? (or uses a different port?)
https://localhost:237:
status: 405
allow-insecure: true
timeout: 5000

View File

@ -1,4 +0,0 @@
http:
http://localhost:236:
status: 405
timeout: 5000

View File

@ -1,3 +0,0 @@
process:
kopano-spamd:
running: true

View File

@ -1,3 +0,0 @@
process:
kopano-spamd:
running: true

View File

@ -1,3 +0,0 @@
process:
kopano-spooler:
running: true

View File

@ -1,3 +0,0 @@
process:
kopano-spooler:
running: true

View File

@ -1,14 +0,0 @@
#!/bin/bash
set -e
case "$SERVICE_TO_START" in
server|dagent|gateway|ical|grapi|kapi|monitor|search|spooler)
goss -g /kopano/goss/"$SERVICE_TO_START"/goss.yaml validate --format json_oneline
;;
*)
echo "This service still needs a proper check"
;;
esac
exit 0

View File

@ -4,13 +4,12 @@ via environment variables"""
import re
import os
import os.path
import sys
def configkopano(configs):
""" Changes configuration files according to configs typically returned from parseenvironmentvariables(..)"""
for filename, config in configs.items():
if not os.path.exists(filename):
continue
return
# read configuration file
with open(filename) as f:
contents = f.read()
@ -35,13 +34,9 @@ def configkopano(configs):
contents = re.sub(r"^\s*#?\s*{}\s*=.*".format(key), r"{} = {}".format(key, newvalue), contents, 0, re.MULTILINE)
# save new configuration
try:
with open(filename, "w") as f:
f.write(contents)
f.close()
except (OSError, PermissionError):
print("Can't open {}, ignoring file changes".format(filename))
def parseenvironmentvariables(prependingpath):
""" Parse all environment variables starting with KCCONF_, KCCOMMENT_ and KCUNCOMMENT_ and

View File

@ -1,296 +1,71 @@
#!/bin/bash
set -eu # unset variables are errors & non-zero return values exit the whole script
[ "$DEBUG" ] && set -x
ADDITIONAL_KOPANO_PACKAGES=${ADDITIONAL_KOPANO_PACKAGES:-""}
AUTOCONFIGURE=${AUTOCONFIGURE:-true} # when set to false will disable all automatic configuration actions
KCCONF_SERVER_MYSQL_SOCKET=${KCCONF_SERVER_MYSQL_SOCKET:-""}
DISABLE_CHECKS=${DISABLE_CHECKS:-false}
DISABLE_CONFIG_CHANGES=${DISABLE_CONFIG_CHANGES:-false}
KCCONF_DAGENT_SERVER_SOCKET=${KCCONF_DAGENT_SERVER_SOCKET:-"file:///var/run/kopano/server.sock"}
KCCONF_GATEWAY_SERVER_SOCKET=${KCCONF_GATEWAY_SERVER_SOCKET:-"tcp://kopano_server:236"}
KCCONF_ICAL_SERVER_SOCKET=${KCCONF_ICAL_SERVER_SOCKET:-"tcp://kopano_server:236"}
KCCONF_MONITOR_SERVER_SOCKET=${KCCONF_MONITOR_SERVER_SOCKET:-"file:///var/run/kopano/server.sock"}
KCCONF_SEARCH_SERVER_SOCKET=${KCCONF_SEARCH_SERVER_SOCKET:-"file:///var/run/kopano/server.sock"}
KCCONF_SPOOLER_SERVER_SOCKET=${KCCONF_SPOOLER_SERVER_SOCKET:-"file:///var/run/kopano/server.sock"}
KOPANO_CON=${KOPANO_CON:-"file:///var/run/kopano/server.sock"}
KCCONF_SPOOLER_SMTP_SERVER=${KCCONF_SPOOLER_SMTP_SERVER:-mail}
KCCONF_SPOOLER_SMTP_PORT=${KCCONF_SPOOLER_SMTP_PORT:-25}
KOPANO_CONFIG_PATH=${KOPANO_CONFIG_PATH:-/tmp/kopano}
if [ "${AUTOCONFIGURE}" == true ]; then
# copy configuration files to /tmp/kopano (default value of $KOPANO_CONFIG_PATH) to prevent modification of mounted config files
mkdir -p /tmp/kopano
cp /etc/kopano/*.cfg /tmp/kopano
set -eu # unset variables are errors & non-zero return values exit the whole script
if [ ! -e /kopano/"$SERVICE_TO_START".py ]; then
if [ ! -e /kopano/$SERVICE_TO_START.py ]
then
echo "Invalid service specified: $SERVICE_TO_START" | ts
exit 1
fi
# Hint: this is not compatible with a read-only container.
# The general recommendation is to already build a container that has all required packages installed.
ADDITIONAL_KOPANO_PACKAGES=$(echo "$ADDITIONAL_KOPANO_PACKAGES" | tr -d '"')
if mkdir -p "/var/lib/apt/lists/" 2&> /dev/null; then
[ -n "${ADDITIONAL_KOPANO_PACKAGES// }" ] && apt update
[ -n "${ADDITIONAL_KOPANO_PACKAGES// }" ] && for installpkg in $ADDITIONAL_KOPANO_PACKAGES; do
# shellcheck disable=SC2016 disable=SC2086
if [ "$(dpkg-query -W -f='${Status}' $installpkg 2>/dev/null | grep -c 'ok installed')" -eq 0 ]; then
DEBIAN_FRONTEND=noninteractive apt --assume-yes --no-upgrade install "$installpkg"
else
echo "INFO: $installpkg is already installed"
fi
done
else
echo "Notice: Container is run read-only, skipping package installation."
echo "If you want to have additional packages installed in the container either:"
echo "- build your own image with the packages already included"
echo "- switch the container to 'read_only: false'"
fi
mkdir -p /tmp/"$SERVICE_TO_START" /var/run/kopano
# TODO is this still required now that we won't modify configuration mounted to /etc/kopano?
if [ "${DISABLE_CONFIG_CHANGES}" == false ]; then
echo "Configure core service '$SERVICE_TO_START'" | ts
/kopano/"$SERVICE_TO_START".py
fi
# ensure removed pid-file on unclean shutdowns and mounted volumes
rm -f /var/run/kopano/"$SERVICE_TO_START".pid
fi
coreversion=$(dpkg-query --showformat='${Version}' --show kopano-server)
echo "Using Kopano Groupware Core: $coreversion"
[ ! -z "$ADDITIONAL_KOPANO_PACKAGES" ] && apt update
[ ! -z "$ADDITIONAL_KOPANO_PACKAGES" ] && for installpkg in "$ADDITIONAL_KOPANO_PACKAGES"; do
if [ $(dpkg-query -W -f='${Status}' $installpkg 2>/dev/null | grep -c "ok installed") -eq 0 ]; then
apt --assume-yes install $installpkg;
fi
done
mkdir -p /kopano/data/attachments /tmp/$SERVICE_TO_START /var/run/kopano
echo "Configure core service '$SERVICE_TO_START'" | ts
/usr/bin/python3 /kopano/$SERVICE_TO_START.py
echo "Set ownership" | ts
chown -R kopano:kopano /run /tmp
chown kopano:kopano /kopano/data/ /kopano/data/attachments
#echo "Clean old pid files and sockets" | ts
#rm -f /var/run/kopano/*
# allow helper commands given by "docker-compose run"
if [ $# -gt 0 ]; then
if [ $# -gt 0 ]
then
exec "$@"
exit
fi
# services need to be aware of the machine-id
if [ "${AUTOCONFIGURE}" == true ] && [ "$DISABLE_CHECKS" == false ]; then
dockerize \
-wait file:///etc/machine-id \
-wait file:///var/lib/dbus/machine-id
fi
# put specified socket into KOPANO_CON variable to ease checks further down
case "$SERVICE_TO_START" in
dagent)
EXE="${EXE:-$(command -v kopano-dagent)}"
KOPANO_CON="$KCCONF_DAGENT_SERVER_SOCKET"
;;
gateway)
EXE="${EXE:-$(command -v kopano-gateway)}"
KOPANO_CON="$KCCONF_GATEWAY_SERVER_SOCKET"
;;
grapi)
EXE="${EXE:-$(command -v kopano-grapi)}"
;;
ical)
EXE="${EXE:-$(command -v kopano-ical)}"
KOPANO_CON="$KCCONF_ICAL_SERVER_SOCKET"
;;
kapi)
EXE="${EXE:-$(command -v kopano-kapid)}"
;;
monitor)
EXE="${EXE:-$(command -v kopano-monitor)}"
KOPANO_CON="$KCCONF_MONITOR_SERVER_SOCKET"
;;
search)
EXE="${EXE:-$(command -v kopano-search)}"
KOPANO_CON="$KCCONF_SEARCH_SERVER_SOCKET"
;;
server)
EXE="${EXE:-$(command -v kopano-server)}"
;;
spamd)
EXE="${EXE:-$(command -v kopano-spamd)}"
;;
spooler)
EXE="${EXE:-$(command -v kopano-spooler)}"
KOPANO_CON="$KCCONF_SPOOLER_SERVER_SOCKET"
;;
esac
if [[ "$KOPANO_CON" =~ ^http.* ]]; then
KOPANO_CON=$(sed 's/.*\/\//tcp:\/\//' <<< "$KOPANO_CON")
fi
# start regular service
case "$SERVICE_TO_START" in
server)
if [ "${AUTOCONFIGURE}" == true ]; then
echo "Set ownership" | ts
mkdir -p /kopano/data/attachments
chown kopano:kopano /kopano/data/ /kopano/data/attachments
if [[ "$DISABLE_CHECKS" == false ]]; then
# determine db connection mode (unix vs. network socket)
if [ -n "$KCCONF_SERVER_MYSQL_SOCKET" ]; then
DB_CON="file://$KCCONF_SERVER_MYSQL_SOCKET"
else
DB_CON="tcp://$KCCONF_SERVER_MYSQL_HOST:$KCCONF_SERVER_MYSQL_PORT"
fi
server)
# TODO needs to be extended for the other services and certificates
dockerize \
-wait file://"$KCCONF_SERVER_SERVER_SSL_CA_FILE" \
-wait file://"$KCCONF_SERVER_SERVER_SSL_KEY_FILE" \
-wait "$DB_CON" \
-wait file://$KCCONF_SERVER_SERVER_SSL_CA_FILE \
-wait file://$KCCONF_SERVER_SERVER_SSL_KEY_FILE \
-wait tcp://db:3306 \
-timeout 360s
fi
# pre populate database
if dpkg --compare-versions "$coreversion" "gt" "8.7.84"; then
kopano-dbadm -c "$KOPANO_CONFIG_PATH/server.cfg" populate
fi
fi
# cleaning up env variables
unset "${!KCCONF_@}"
exec "$EXE" -F
exec /usr/sbin/kopano-server -F
;;
dagent)
if [ "${AUTOCONFIGURE}" == true ] && [ "$DISABLE_CHECKS" == false ]; then
dockerize \
-wait "$KOPANO_CON" \
-timeout 360s
fi
# cleaning up env variables
unset "${!KCCONF_@}"
exec "$EXE" -l
dagent)
exec /usr/sbin/kopano-dagent -l
;;
gateway)
if [ "${AUTOCONFIGURE}" == true ] && [ "$DISABLE_CHECKS" == false ]; then
dockerize \
-wait "$KOPANO_CON" \
-timeout 360s
fi
# cleaning up env variables
unset "${!KCCONF_@}"
exec "$EXE" -F
gateway)
exec /usr/sbin/kopano-gateway -F
;;
ical)
if [ "${AUTOCONFIGURE}" == true ] && [ "$DISABLE_CHECKS" == false ]; then
dockerize \
-wait "$KOPANO_CON" \
-timeout 360s
fi
# cleaning up env variables
unset "${!KCCONF_@}"
exec "$EXE" -F
ical)
exec /usr/sbin/kopano-ical -F
;;
grapi)
if [ "${AUTOCONFIGURE}" == true ]; then
LC_CTYPE=en_US.UTF-8
export socket_path=/var/run/kopano/grapi
export pid_file="$socket_path/grapi.pid"
mkdir -p "$socket_path" /var/lib/kopano-grapi
chown -R kapi:kopano "$socket_path"
chown kapi:kopano /var/lib/kopano-grapi
# TODO there could be a case where multiple backends are desired
case $GRAPI_BACKEND in
ldap)
[ -n "$KCCONF_GRAPI_LDAP_URI" ] && export LDAP_URI="${KCCONF_GRAPI_LDAP_URI}"
[ -n "$KCCONF_GRAPI_LDAP_BASEDN" ] && export LDAP_BASEDN="${KCCONF_GRAPI_LDAP_BASEDN}"
[ -n "$KCCONF_GRAPI_LDAP_BINDDN" ] && export LDAP_BINDDN="${KCCONF_GRAPI_LDAP_BINDDN}"
if [ -n "$KCCONF_GRAPI_LDAP_BINDPW_FILE" ]; then
bindpw="$(cat "${KCCONF_GRAPI_LDAP_BINDPW_FILE}")"
export LDAP_BINDPW="${bindpw}"
fi
monitor)
exec /usr/sbin/kopano-monitor -F
;;
esac
sed s/\ *=\ */=/g "$KOPANO_CONFIG_PATH/grapi.cfg" > /tmp/grapi-env
# shellcheck disable=SC2046
export $(grep -v '^#' /tmp/grapi-env | xargs -d '\n')
fi
# cleaning up env variables
unset "${!KCCONF_@}"
# the backend option is only available in more recent versions of grapi
grapiversion=$(dpkg-query --showformat='${Version}' --show kopano-grapi)
echo "Using Kopano Grapi: $grapiversion"
if dpkg --compare-versions "$grapiversion" "gt" "10.0.0"; then
exec "$EXE" serve --backend="$GRAPI_BACKEND"
else
exec "$EXE" serve
fi
search)
exec /usr/bin/python /usr/sbin/kopano-search -F
;;
kapi)
if [ "${AUTOCONFIGURE}" == true ]; then
mkdir -p /kopano/data/kapi-kvs
if [ "$KCCONF_KAPID_INSECURE" = "yes" ]; then
dockerize \
-skip-tls-verify \
-wait "$KCCONF_KAPID_OIDC_ISSUER_IDENTIFIER"/.well-known/openid-configuration \
-timeout 360s
else
dockerize \
-wait "$KCCONF_KAPID_OIDC_ISSUER_IDENTIFIER"/.well-known/openid-configuration \
-timeout 360s
fi
LC_CTYPE=en_US.UTF-8
sed s/\ *=\ */=/g "$KOPANO_CONFIG_PATH/kapid.cfg" > /tmp/kapid-env
# shellcheck disable=SC2046
export $(grep -v '^#' /tmp/kapid-env | xargs -d '\n')
"$EXE" setup
fi
# cleaning up env variables
unset "${!KCCONF_@}"
kapiversion=$(dpkg-query --showformat='${Version}' --show kopano-kapid)
echo "Using Kopano Kapi: $kapiversion"
exec "$EXE" serve --log-timestamp=false
spooler)
exec /usr/sbin/kopano-spooler -F
;;
monitor)
if [ "${AUTOCONFIGURE}" == true ] && [ "$DISABLE_CHECKS" == false ]; then
dockerize \
-wait "$KOPANO_CON" \
-timeout 360s
fi
# cleaning up env variables
unset "${!KCCONF_@}"
exec "$EXE" -F
;;
search)
if [ "${AUTOCONFIGURE}" == true ] && [ "$DISABLE_CHECKS" == false ]; then
dockerize \
-wait "$KOPANO_CON" \
-timeout 360s
# give kopano-server a moment to settler before starting search
sleep 5
fi
# cleaning up env variables
unset "${!KCCONF_@}"
# with commit 702bb3fccb3 search does not need -F any longer
searchversion=$(dpkg-query --showformat='${Version}' --show kopano-search)
if dpkg --compare-versions "$searchversion" "gt" "8.7.82.165"; then
exec "$EXE" --config "$KOPANO_CONFIG_PATH/search.cfg"
else
exec /usr/bin/python3 "$EXE" --config "$KOPANO_CONFIG_PATH/search.cfg" -F
fi
;;
spamd)
if [ "${AUTOCONFIGURE}" == true ] && [ "$DISABLE_CHECKS" == false ]; then
dockerize \
-wait "$KOPANO_CON" \
-timeout 360s
fi
# cleaning up env variables
unset "${!KCCONF_@}"
exec "$EXE" --config "$KOPANO_CONFIG_PATH/spamd.cfg" -F
;;
spooler)
if [ "${AUTOCONFIGURE}" == true ] && [ "$DISABLE_CHECKS" == false ]; then
dockerize \
-wait "$KOPANO_CON" \
-wait tcp://"$KCCONF_SPOOLER_SMTP_SERVER":"$KCCONF_SPOOLER_SMTP_PORT" \
-timeout 1080s
fi
# cleaning up env variables
unset "${!KCCONF_@}"
exec "$EXE" -F
;;
*)
*)
echo "Failed to start: Unknown service name: '$SERVICE_TO_START'" | ts
exit 1
esac

View File

@ -1,5 +0,0 @@
# Database helpers
## create-multiple-databases.sh
Script to create additional databases during the initial container startup. Based on https://github.com/mrts/docker-postgresql-multiple-databases.

View File

@ -1,20 +0,0 @@
#!/bin/bash
set -eu
mysql=${mysql:?}
function create_user_and_database() {
local database=$1
echo " Creating database '$database'"
echo "CREATE DATABASE IF NOT EXISTS ${database};" | "${mysql[@]}"
echo "GRANT ALL PRIVILEGES ON ${database}.* TO '${MYSQL_USER}';" | "${mysql[@]}"
}
if [ -n "$MYSQL_ADDITIONAL_DATABASES" ]; then
echo "Multiple database creation requested: $MYSQL_ADDITIONAL_DATABASES"
for db in $(echo "$MYSQL_ADDITIONAL_DATABASES" | tr ',' ' '); do
create_user_and_database "$db"
done
echo "Additional databases created"
fi

View File

@ -1,30 +0,0 @@
version: "3.5"
services:
db:
image: mariadb:10.3.10-bionic
restart: unless-stopped
container_name: ${COMPOSE_PROJECT_NAME}_db
volumes:
- mysql:/var/lib/mysql
environment:
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_USER=${MYSQL_USER}
env_file:
- db.env
healthcheck:
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']
interval: 30s
timeout: 10s
retries: 4
networks:
- kopano-net
kopano_server:
depends_on:
- db
volumes:
mysql:

View File

@ -1,31 +0,0 @@
version: "3.5"
services:
kopano_kwmserver:
environment:
- enable_mcu_api=yes
- pipeline_forced_regexp=@conference/.*
#- pipeline_forced_regexp=@group/.*
kopano_kwmbridge:
image: ${docker_repo:-zokradonh}/kopano_kwmbridge:${KWMBRIDGE_VERSION:-latest}
read_only: true
restart: unless-stopped
depends_on:
- kopano_kwmserver
environment:
- INSECURE=${INSECURE}
- oidc_issuer_identifier=https://${FQDN}
- kwm_server_urls=http://kwmserver:8778
#- kwm_server_urls=https://${FQDNCLEANED}:8443
- use_nat_1to1_ips=${PUBLICIP}
- use_nat_1to1_candidate_type=host
- ice_udp_port_range=65435:65535
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanossl:/kopano/ssl
ports:
- 65435:65535/udp
tmpfs:
- /tmp

View File

@ -1,29 +0,0 @@
version: "3.5"
services:
web:
ports:
- "8443:8443" # this port should be firewalled off so that only known instances of kwmbridge can connect tot it
kopano_kwmserver:
environment:
- enable_mcu_api=yes
kopano_kwmbridge:
image: ${docker_repo:-zokradonh}/kopano_kwmbridge:${KWMBRIDGE_VERSION:-latest}
read_only: true
restart: unless-stopped
depends_on:
- kopano_kwmserver
environment:
- INSECURE=${INSECURE}
- oidc_issuer_identifier=https://${FQDN}
- kwm_server_urls=https://${FQDNCLEANED}:8443
env_file:
- kopano_kwmbridge.env
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanossl:/kopano/ssl
network_mode: "host"
tmpfs:
- /tmp

View File

@ -1,45 +0,0 @@
version: "3.5"
services:
ldap:
image: ${docker_repo:-zokradonh}/${LDAP_CONTAINER:-kopano_ldap_demo}:${LDAP_VERSION:-latest}
restart: unless-stopped
container_name: ${COMPOSE_PROJECT_NAME}_ldap
ports:
- ${LDAPPORT:-389}:389
environment:
- LDAP_ADMIN_PASSWORD=${LDAP_ADMIN_PASSWORD}
- LDAP_BASE_DN=${LDAP_BASE_DN}
- LDAP_DOMAIN=${LDAP_DOMAIN}
- LDAP_LOG_LEVEL=0
- LDAP_ORGANISATION=${LDAP_ORGANISATION}
- LDAP_READONLY_USER_PASSWORD=${LDAP_READONLY_USER_PASSWORD}
- LDAP_READONLY_USER=true
env_file:
- ldap.env
command: "--copy-service"
volumes:
- ldap:/var/lib/ldap
- slapd:/etc/ldap/slapd.d
networks:
- ldap-net
mail:
depends_on:
- ldap
networks:
- ldap-net
kopano_server:
depends_on:
- ldap
networks:
- ldap-net
volumes:
ldap:
slapd:
networks:
ldap-net:
driver: bridge

View File

@ -1,71 +0,0 @@
version: "3.5"
services:
mail:
image: mailserver/docker-mailserver:10
restart: unless-stopped
hostname: mail # hostname and domainname may need to be commented on some platforms (e.g. ChromeOS)
domainname: ${LDAP_DOMAIN}
container_name: ${COMPOSE_PROJECT_NAME}_mail
ports:
- "${SMTPPORT:-25}:25"
- "${SMTPSPORT:-465}:465"
- "${MSAPORT:-587}:587"
volumes:
- maildata:/var/mail
- mailstate:/var/mail-state
- maillogs:/var/log/mail
- mtaconfig:/tmp/docker-mailserver/
environment:
- DMS_DEBUG=0
- ENABLE_CLAMAV=1
- ENABLE_FAIL2BAN=1
- ENABLE_LDAP=1
- ENABLE_POSTFIX_VIRTUAL_TRANSPORT=1
- ENABLE_POSTGREY=1
- ENABLE_SASLAUTHD=1
- ENABLE_SPAMASSASSIN=1
- LDAP_BIND_DN=${LDAP_BIND_DN}
- LDAP_BIND_PW=${LDAP_BIND_PW}
- LDAP_QUERY_FILTER_ALIAS=${LDAP_QUERY_FILTER_ALIAS}
- LDAP_QUERY_FILTER_DOMAIN=${LDAP_QUERY_FILTER_DOMAIN}
- LDAP_QUERY_FILTER_GROUP=${LDAP_QUERY_FILTER_GROUP}
- LDAP_QUERY_FILTER_USER=${LDAP_QUERY_FILTER_USER}
- LDAP_SEARCH_BASE=${LDAP_SEARCH_BASE}
- LDAP_SERVER_HOST=${LDAP_SERVER}
- ONE_DIR=1
- PERMIT_DOCKER=connected-networks
- POSTFIX_DAGENT=lmtp:kopano_dagent:2003
- PFLOGSUMM_TRIGGER=logrotate
- POSTMASTER_ADDRESS=${POSTMASTER_ADDRESS}
- SASLAUTHD_LDAP_BIND_DN=${LDAP_BIND_DN}
- SASLAUTHD_LDAP_FILTER=${SASLAUTHD_LDAP_FILTER}
- SASLAUTHD_LDAP_PASSWORD=${LDAP_BIND_PW}
- SASLAUTHD_LDAP_SEARCH_BASE=${LDAP_SEARCH_BASE}
- SASLAUTHD_LDAP_SERVER=${LDAP_HOST}
- SASLAUTHD_MECHANISMS=rimap
- SASLAUTHD_MECH_OPTIONS=kopano_gateway
- SMTP_ONLY=1
- SPAMASSASSIN_SPAM_TO_INBOX=1
- SSL_TYPE=self-signed
- TZ=${TZ}
env_file:
- mail.env
networks:
- kopano-net
# dns: 1.1.1.1 # using Google DNS can lead to lookup errors uncomment this option and
# set to the ip of a trusted dns service (Cloudflare is given as an example).
# See https://github.com/zokradonh/kopano-docker/issues/52 for more information.
cap_add:
- NET_ADMIN
- SYS_PTRACE
kopano_spooler:
depends_on:
- mail
volumes:
maildata:
mailstate:
maillogs:
mtaconfig:

View File

@ -1,22 +0,0 @@
version: "3.5"
services:
web:
ports:
- "${CADDY:-2015}:2015"
- "${HTTP:-80}:80"
- "${HTTPS:-443}:443"
kopano_server:
ports:
- ${KOPANOPORT:-236}:236
- ${KOPANOSPORT:-237}:237
kopano_gateway:
ports:
- "${POP3PORT:-110}:110"
- "${IMAPPORT:-143}:143"
kopano_ical:
ports:
- "${ICALPORT:-8080}:8080"

View File

@ -1,534 +0,0 @@
version: "3.5"
services:
web:
image: ${docker_repo:-zokradonh}/kopano_web:${KWEB_VERSION:-latest}
read_only: true
restart: unless-stopped
environment:
- DEFAULTREDIRECT=${DEFAULTREDIRECT:-/webapp}
- EMAIL=${EMAIL:-off}
- FQDN=${FQDN}
- TLS_MODE=tls_auto
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- web:/.kweb
networks:
web-net:
aliases:
- ${FQDNCLEANED:-domain.invalid}
kopano_ssl:
image: ${docker_repo:-zokradonh}/kopano_ssl:${SSL_VERSION:-latest}
read_only: true
environment:
- FQDN=${FQDN}
- PKI_COUNTRY=NL
env_file:
- kopano_ssl.env
volumes:
- kopanossl:/kopano/ssl
tmpfs:
- /kopano/easypki/
kopano_server:
image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest}
read_only: true # in case additional packages need to be installed this option should be set to false
restart: unless-stopped
hostname: kopano_server
container_name: ${COMPOSE_PROJECT_NAME}_server
depends_on:
- kopano_konnect
- kopano_ssl
environment:
- ADDITIONAL_KOPANO_PACKAGES=${ADDITIONAL_KOPANO_PACKAGES}
- KCCOMMENT_LDAP_1=${KCCOMMENT_LDAP_1}
- KCCONF_ADMIN_DEFAULT_STORE_LOCALE=${MAILBOXLANG:-en_US.UTF-8} # Hint: if additional locales are required these should be added in base/Dockerfile
- KCCONF_LDAP_LDAP_BIND_PASSWD=${LDAP_BIND_PW}
- KCCONF_LDAP_LDAP_BIND_USER=${LDAP_BIND_DN}
- KCCONF_LDAP_LDAP_SEARCH_BASE=${LDAP_SEARCH_BASE}
- KCCONF_LDAP_LDAP_URI=${LDAP_SERVER}
- KCCONF_SERVER_ATTACHMENT_PATH=/kopano/data/attachments
- KCCONF_SERVER_COREDUMP_ENABLED=no
- KCCONF_SERVER_ENABLE_SSO=yes
- KCCONF_SERVER_KCOIDC_INSECURE_SKIP_VERIFY=${INSECURE}
- KCCONF_SERVER_KCOIDC_ISSUER_IDENTIFIER=https://${FQDN}
- KCCONF_SERVER_LOG_LEVEL=3
- KCCONF_SERVER_LOG_TIMESTAMP=0
- KCCONF_SERVER_MYSQL_DATABASE=${MYSQL_DATABASE}
- KCCONF_SERVER_MYSQL_HOST=${MYSQL_HOST}
- KCCONF_SERVER_MYSQL_PASSWORD=${MYSQL_PASSWORD}
- KCCONF_SERVER_MYSQL_PORT=3306
- KCCONF_SERVER_MYSQL_USER=${MYSQL_USER}
- KCCONF_SERVER_PROXY_HEADER=* # delete line if webapp is not behind reverse proxy
- KCCONF_SERVER_SERVER_LISTEN_TLS=0.0.0.0:237
- KCCONF_SERVER_SERVER_LISTEN=0.0.0.0:236
- KCCONF_SERVER_SERVER_NAME=Kopano
- KCCONF_SERVER_SERVER_SSL_CA_FILE=/kopano/ssl/ca.pem
- KCCONF_SERVER_SERVER_SSL_KEY_FILE=/kopano/ssl/kopano_server.pem
- KCCONF_SERVER_SOFTDELETE_LIFETIME=0
- KCCONF_SERVER_SSLKEYS_PATH=/kopano/ssl/clients
- KCCONF_SERVER_SYNC_GAB_REALTIME=no
- KCCONF_SERVER_SYSTEM_EMAIL_ADDRESS=${POSTMASTER_ADDRESS}
- KCCONF_SERVER_USER_PLUGIN_CONFIG=/tmp/kopano/ldap.cfg
- KCCONF_SERVER_USER_PLUGIN=ldap
- KCUNCOMMENT_LDAP_1=${KCUNCOMMENT_LDAP_1}
- SERVICE_TO_START=server
- TZ=${TZ}
env_file:
- kopano_server.env
networks:
- kopano-net
- web-net
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanodata:/kopano/data
- kopanosocket:/run/kopano
- kopanossl:/kopano/ssl
tmpfs:
- /tmp/
kopano_webapp:
image: ${docker_repo:-zokradonh}/kopano_webapp:${WEBAPP_VERSION:-latest}
read_only: true # in case additional packages need to be installed this option should be set to false
restart: unless-stopped
hostname: kopano_webapp
depends_on:
- kopano_server
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanosocket:/run/kopano
- kopanossl:/kopano/ssl
- kopanowebapp:/var/lib/kopano-webapp/
environment:
- ADDITIONAL_KOPANO_WEBAPP_PLUGINS=${ADDITIONAL_KOPANO_WEBAPP_PLUGINS}
- KCCONF_WEBAPP_OIDC_CLIENT_ID=webapp
- KCCONF_WEBAPP_OIDC_ISS=https://${FQDN}
- KCCONF_WEBAPP_CLIENT_TIMEOUT=0 # needed to set to 0 to work around an oidc bug KW-3398
- TZ=${TZ}
env_file:
- kopano_webapp.env
networks:
- kopano-net
- web-net
tmpfs:
- /run/php/
- /run/sessions/
- /tmp/
- /var/lib/kopano-webapp/plugin_files
- /var/log/
kopano_zpush:
image: ${docker_repo:-zokradonh}/kopano_zpush:${ZPUSH_VERSION:-latest}
read_only: true
restart: unless-stopped
hostname: kopano_zpush
container_name: ${COMPOSE_PROJECT_NAME}_zpush
depends_on:
- kopano_server
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanosocket:/run/kopano
- kopanossl:/kopano/ssl
- zpushstates:/var/lib/z-push/
environment:
- TZ=${TZ}
# Shared folders automatically assigned to all users in the format: [{"name":"<folder name>","id":"<kopano folder id>","type":"<type>","flags":"<flags>"},...]
# For more information on the parameters see the z-push-admin help for the addshared-action.
- ZPUSH_ADDITIONAL_FOLDERS=[]
env_file:
- kopano_zpush.env
networks:
- kopano-net
- web-net
tmpfs:
- /tmp/
- /run/sessions/
- /run/php/
- /var/log/
kopano_grapi:
image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest}
read_only: true
restart: unless-stopped
container_name: ${COMPOSE_PROJECT_NAME}_grapi
depends_on:
- kopano_server
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanograpi:/var/lib/kopano-grapi
- kopanosocket:/run/kopano
environment:
- KCCONF_GRAPI_ENABLE_EXPERIMENTAL_ENDPOINTS=no # needs to be set to yes for grapi versions prior to 10.3 to use calendar
- KCCONF_GRAPI_INSECURE=${INSECURE}
- KCCONF_GRAPI_PERSISTENCY_PATH=/var/lib/kopano-grapi
- SERVICE_TO_START=grapi
- TZ=${TZ}
env_file:
- kopano_grapi.env
networks:
- kopano-net
- web-net
tmpfs:
- /tmp/
kopano_kapi:
image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest}
read_only: true
restart: unless-stopped
container_name: ${COMPOSE_PROJECT_NAME}_kapi
depends_on:
- kopano_grapi
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanodata:/kopano/data
- kopanosocket:/run/kopano
- kopanossl:/kopano/ssl
environment:
- DEFAULT_PLUGIN_PUBS_SECRET_KEY_FILE=/kopano/ssl/kapid-pubs-secret.key
- KCCONF_KAPID_INSECURE=${INSECURE}
- KCCONF_KAPID_LISTEN=0.0.0.0:8039
- KCCONF_KAPID_LOG_LEVEL=DEBUG
- KCCONF_KAPID_LOG_LEVEL=info
- KCCONF_KAPID_OIDC_ISSUER_IDENTIFIER=https://${FQDN}
- KCCONF_KAPID_PLUGIN_GRAPI_SOCKET_PATH=/var/run/kopano/grapi
- KCCONF_KAPID_PLUGIN_KVS_DB_DATASOURCE=/kopano/data/kapi-kvs/kvs.db
- SERVICE_TO_START=kapi
- TZ=${TZ}
env_file:
- kopano_kapi.env
networks:
- kopano-net
- web-net
tmpfs:
- /tmp
kopano_kapps:
image: ${docker_repo:-zokradonh}/kopano_kapps:${KAPPS_VERSION:-latest}
read_only: true
restart: unless-stopped
environment:
- SERVICE_TO_START=kapps
env_file:
- kopano_kapps.env
depends_on:
- kopano_kapi
- kopano_konnect
- web
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
networks:
- web-net
tmpfs:
- /tmp
kopano_kdav:
image: ${docker_repo:-zokradonh}/kopano_kdav:${KDAV_VERSION:-latest}
read_only: true
restart: unless-stopped
hostname: kopano_kdav
container_name: ${COMPOSE_PROJECT_NAME}_kdav
depends_on:
- kopano_server
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kdavstates:/var/lib/kopano/kdav
- kopanosocket:/run/kopano
- kopanossl:/kopano/ssl
environment:
- TZ=${TZ}
networks:
- kopano-net
- web-net
tmpfs:
- /run/php/
- /run/sessions/
- /tmp
- /var/log/kdav/
kopano_dagent:
image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest}
read_only: true
restart: unless-stopped
depends_on:
- kopano_server
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanosocket:/run/kopano
- kopanossl:/kopano/ssl
environment:
- KCCONF_AUTORESPOND_SENDDB=/tmp/autorespond.db
- KCCONF_DAGENT_AUTORESPONDER=/usr/local/bin/kopano-autorespond
- KCCONF_DAGENT_LMTP_LISTEN=0.0.0.0:2003
- KCCONF_DAGENT_LOG_LEVEL=3
- KCCONF_DAGENT_LOG_TIMESTAMP=0
- KCCONF_DAGENT_SSLKEY_FILE=/kopano/ssl/kopano_dagent.pem
- SERVICE_TO_START=dagent
- TZ=${TZ}
env_file:
- kopano_dagent.env
networks:
- kopano-net
tmpfs:
- /tmp
kopano_spooler:
image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest}
read_only: true
restart: unless-stopped
hostname: spooler # hostname and domainname may need to be commented on some platforms (e.g. ChromeOS)
domainname: ${LDAP_DOMAIN}
depends_on:
- kopano_server
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanosocket:/run/kopano
- kopanossl:/kopano/ssl
environment:
- KCCONF_SPOOLER_LOG_LEVEL=3
- KCCONF_SPOOLER_LOG_TIMESTAMP=0
- KCCONF_SPOOLER_SMTP_SERVER=mail
- KCCONF_SPOOLER_SMTP_PORT=25
- KCCONF_SPOOLER_SSLKEY_FILE=/kopano/ssl/kopano_spooler.pem
- SERVICE_TO_START=spooler
- TZ=${TZ}
env_file:
- kopano_spooler.env
networks:
- kopano-net
tmpfs:
- /tmp
kopano_gateway:
image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest}
read_only: true
restart: unless-stopped
depends_on:
- kopano_server
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanosocket:/run/kopano
- kopanossl:/kopano/ssl
environment:
- KCCONF_GATEWAY_IMAP_LISTEN=0.0.0.0:143
- KCCONF_GATEWAY_LOG_LEVEL=3
- KCCONF_GATEWAY_LOG_TIMESTAMP=0
- KCCONF_GATEWAY_SERVER_SOCKET=http://kopano_server:236/
- SERVICE_TO_START=gateway
- TZ=${TZ}
env_file:
- kopano_gateway.env
networks:
- kopano-net
tmpfs:
- /tmp
kopano_ical:
image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest}
read_only: true
restart: unless-stopped
depends_on:
- kopano_server
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanosocket:/run/kopano
- kopanossl:/kopano/ssl
environment:
- KCCONF_ICAL_ICAL_LISTEN=0.0.0.0:8080
- KCCONF_ICAL_LOG_LEVEL=3
- KCCONF_ICAL_LOG_TIMESTAMP=0
- KCCONF_ICAL_SERVER_SOCKET=http://kopano_server:236/
- SERVICE_TO_START=ical
- TZ=${TZ}
env_file:
- kopano_ical.env
networks:
- kopano-net
- web-net
tmpfs:
- /tmp
kopano_monitor:
image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest}
read_only: true
restart: unless-stopped
depends_on:
- kopano_server
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanosocket:/run/kopano
- kopanossl:/kopano/ssl
environment:
- SERVICE_TO_START=monitor
- KCCONF_MONITOR_LOG_LEVEL=3
- KCCONF_MONITOR_LOG_TIMESTAMP=0
- TZ=${TZ}
env_file:
- kopano_monitor.env
networks:
- kopano-net
tmpfs:
- /tmp
kopano_search:
image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest}
read_only: true
restart: unless-stopped
container_name: ${COMPOSE_PROJECT_NAME}_search
depends_on:
- kopano_server
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanodata:/kopano/data
- kopanosocket:/run/kopano
- kopanossl:/kopano/ssl
environment:
- SERVICE_TO_START=search
- KCCONF_SEARCH_LOG_LEVEL=3
- KCCONF_SEARCH_LOG_TIMESTAMP=0
- KCCONF_SEARCH_INDEX_PATH=/kopano/data/search/
- TZ=${TZ}
env_file:
- kopano_search.env
networks:
- kopano-net
tmpfs:
- /tmp
kopano_konnect:
image: ${docker_repo:-zokradonh}/kopano_konnect:${KONNECT_VERSION:-latest}
read_only: true
restart: unless-stopped
depends_on:
- kopano_ssl
- web
# to be useful Konnect also needs a running kopano_server, but this dependency cannot be added here since this would be a circular dependency
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanosocket:/run/kopano
- kopanossl:/kopano/ssl
environment:
- allow_client_guests=yes
- allow_dynamic_client_registration=yes
- eckey=/kopano/ssl/meet-kwmserver.pem
- ecparam=/kopano/ssl/ecparam.pem
- encryption_secret_key=/kopano/ssl/konnectd-encryption.key
- FQDN=${FQDN}
- identifier_registration_conf=/kopano/ssl/konnectd-identifier-registration.yaml
- identifier_scopes_conf=/etc/kopano/konnectd-identifier-scopes.yaml
- signing_private_key=/kopano/ssl/konnectd-tokens-signing-key.pem
- validation_keys_path=/kopano/ssl/konnectkeys
env_file:
- kopano_konnect.env
networks:
- kopano-net
- web-net
tmpfs:
- /tmp
kopano_kwmserver:
image: ${docker_repo:-zokradonh}/kopano_kwmserver:${KWM_VERSION:-latest}
read_only: true
restart: unless-stopped
command: wrapper.sh
depends_on:
- kopano_kapi
- kopano_konnect
environment:
- enable_guest_api=yes
- INSECURE=${INSECURE}
- oidc_issuer_identifier=https://${FQDN}
- public_guest_access_regexp=^group/public/.*
- registration_conf=/kopano/ssl/konnectd-identifier-registration.yaml
- turn_service_credentials_password=${TURN_PASSWORD:-}
- turn_service_credentials_user=${TURN_USER:-}
env_file:
- kopano_kwmserver.env
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanossl:/kopano/ssl
networks:
- web-net
tmpfs:
- /tmp
kopano_meet:
image: ${docker_repo:-zokradonh}/kopano_meet:${MEET_VERSION:-latest}
read_only: true
restart: unless-stopped
environment:
- KCCONF_MEET_disableFullGAB=false
- KCCONF_MEET_guests_enabled=true
- KCCONF_MEET_minimumVersion=20200121 # can be used force updates of Meet
- KCCONF_MEET_oidc_useImplicitFlow=true # workaround for guest login with meet https://stash.kopano.io/projects/KWM/repos/meet/pull-requests/102/overview
env_file:
- kopano_meet.env
depends_on:
- kopano_kapi
- kopano_konnect
- kopano_kwmserver
- web
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
networks:
- web-net
tmpfs:
- /tmp
kopano_scheduler:
image: ${docker_repo:-zokradonh}/kopano_scheduler:${SCHEDULER_VERSION:-latest}
read_only: true
restart: "no"
container_name: ${COMPOSE_PROJECT_NAME}_scheduler
networks:
- kopano-net
- web-net
depends_on:
- kopano_server
- kopano_zpush
environment:
- CRON_KOPANOUSERS=10 * * * * docker exec kopano_server kopano-admin --sync
- CRON_ZPUSHGAB=0 22 * * * docker exec kopano_zpush z-push-gabsync -a sync
- CRONDELAYED_KBACKUP=30 1 * * * docker run --rm -it --volumes-from kopano_server -v /root/kopano-backup:/kopano/path ${docker_repo:-zokradonh}/kopano_utils:${CORE_VERSION:-latest} kopano-backup -h
- CRONDELAYED_SOFTDELETE=30 2 * * * docker exec kopano_server kopano-admin --purge-softdelete 30
- TZ=${TZ}
env_file:
- kopano_scheduler.env
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
tmpfs:
- /tmp
volumes:
kdavstates:
kopanodata:
kopanograpi:
kopanolicenses:
kopanosocket:
kopanossl:
kopanowebapp:
web:
zpushstates:
networks:
kopano-net:
driver: bridge
web-net:

154
docker-compose.yml-example Normal file
View File

@ -0,0 +1,154 @@
version: "3"
services:
web:
image: abiosoft/caddy:0.10.4
restart: always
privileged: true
links:
- kwebapp
#- kzpush
ports:
- "10080:80"
- "10443:443"
volumes:
- ./web/Caddyfile:/etc/Caddyfile
- ./data/web:/root/.caddy
mail:
image: tvial/docker-mailserver:latest
restart: always
hostname: mail
domainname: kopano.demo # change here
container_name: mail
ports:
- "25:25"
volumes:
- ./data/mail/data:/var/mail
- ./data/mail/state:/var/mail-state
- ./mail/config:/tmp/docker-mailserver/
#- ./data/web/acme-v01.api.letsencrypt.org/sites/mail.kopano.demo:/tmp/ssl:ro
environment:
- TZ=Europe/Berlin
- ENABLE_SPAMASSASSIN=1
- ENABLE_CLAMAV=1
- ENABLE_FAIL2BAN=1
- ENABLE_POSTGREY=1
- ONE_DIR=0
- DMS_DEBUG=0
- SSL_TYPE=manual
- SSL_CERT_PATH=/tmp/ssl/mail.kopano.demo.crt
- SSL_KEY_PATH=/tmp/ssl/mail.kopano.demo.key
- ENABLE_LDAP=1
- LDAP_SERVER_HOST=ldaps://ldapserver:ldapport #change here
- LDAP_SEARCH_BASE=OU=MyUsers,DC=domain,DC=tld #change here
- LDAP_BIND_DN=cn=SOME_STANDARD_USER,OU=MyUsers,DC=domain,DC=tld #change here
- LDAP_BIND_PW=PASSWORD_OF_SOME_STANDARD_USER #change here
- LDAP_QUERY_FILTER_USER=(&(objectClass=user)(|(mail=%s)(otherMailbox=%s)))
- LDAP_QUERY_FILTER_GROUP=(&(objectclass=group)(mail=%s))
- LDAP_QUERY_FILTER_ALIAS=(&(objectClass=user)(otherMailbox=%s))
- LDAP_QUERY_FILTER_DOMAIN=(&(|(mail=*@%s)(otherMailbox=*@%s)(mailGroupMember=*@%s))(kopanoAccount=1)(|(objectClass=user)(objectclass=group)))
- ENABLE_SASLAUTHD=1
- SASLAUTHD_LDAP_SERVER=ldaps://ldapserver:ldapport #change here
- SASLAUTHD_LDAP_BIND_DN=cn=SOME_STANDARD_USER,OU=MyUsers,DC=domain,DC=tld #change here
- SASLAUTHD_LDAP_PASSWORD=PASSWORD_OF_SOME_STANDARD_USER #change here
- SASLAUTHD_LDAP_SEARCH_BASE=OU=MyUsers,DC=domain,DC=tld #change here
- SASLAUTHD_LDAP_FILTER=(&(sAMAccountName=%U)(objectClass=person))
- SASLAUTHD_MECHANISMS=ldap
- POSTMASTER_ADDRESS=postmaster@domain.tld #change here
- SMTP_ONLY=1
- PERMIT_DOCKER=network
- ENABLE_POSTFIX_VIRTUAL_TRANSPORT=1
- POSTFIX_DAGENT=lmtp:kdagent:2003
- REPORT_RECIPIENT=1
networks:
- kopanonet
cap_add:
- NET_ADMIN
- SYS_PTRACE
# TODO find good example ldap container
db:
image: mariadb:10.3.10-bionic
restart: always
container_name: kopano_db
volumes:
- ./data/mysql/:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=YOUR_MYSQL_ROOT_PASSWORD #change here
- MYSQL_PASSWORD=YOUR_PASSWORD #change here
- MYSQL_DATABASE=kopano
- MYSQL_USER=kopano
healthcheck:
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']
interval: 30s
timeout: 10s
retries: 4
networks:
- kopanonet
kwebapp:
image: zokradonh/kopano_webapp:latest
hostname: kwebapp
container_name: kopano_webapp
links:
- kserver
volumes:
- ./data/z-push-states/:/var/lib/z-push/
- ./ssl/:/kopano/ssl
- ./data/socket/:/run/kopano
environment:
- TZ=Europe/Berlin
#- ADDITIONAL_KOPANO_PACKAGES=kopano-webapp-plugin-mattermost
networks:
- web
- kopanonet
kssl:
image: zokradonh/kopano_ssl
container_name: kopano_ssl
volumes:
- ./data/ssl/:/kopano/ssl
kserver:
image: zokradonh/kopano_core:latest
hostname: kserver
container_name: kopano_server
links:
- db
depends_on:
- db
- kssl
environment:
- SERVICE_TO_START=server
- TZ=Europe/Berlin
- KCCONF_SERVER_COREDUMP_ENABLED=no
- KCCONF_SERVER_LOG_LEVEL=4
- KCCONF_SERVER_MYSQL_HOST=db
- KCCONF_SERVER_MYSQL_PORT=3306
- KCCONF_SERVER_MYSQL_DATABASE=kopano
- KCCONF_SERVER_MYSQL_USER=root
- KCCONF_SERVER_MYSQL_PASSWORD=YOUR_MYSQL_ROOT_PASSWORD #change here
- KCCONF_SERVER_SERVER_SSL_KEY_FILE=/kopano/ssl/kserver.pem
- KCCONF_SERVER_SERVER_SSL_CA_FILE=/kopano/ssl/ca.pem
- KCCONF_SERVER_SSLKEYS_PATH=/kopano/ssl/clients
- KCCONF_SERVER_PROXY_HEADER=* # delete line if webapp is not behind reverse proxy
- KCCONF_SERVER_SYSTEM_EMAIL_ADDRESS=hostmaster@domain.tld #change here
- KCCONF_SERVER_DISABLED_FEATURES=pop3
- KCCONF_LDAP_LDAP_URI=ldaps://ldapserver:ldapport #change here
- KCCONF_LDAP_LDAP_BIND_USER=cn=SOME_STANDARD_USER,OU=MyUsers,DC=domain,DC=tld #change here
- KCCONF_LDAP_LDAP_BIND_PASSWD=PASSWORD_OF_STANDARD_USER #change here
- KCCONF_LDAP_LDAP_SEARCH_BASE=OU=MyUsers,dc=domain,dc=tld #change here
- KCCOMMENT_LDAP_1=!include /usr/share/kopano/ldap.openldap.cfg #delete if you want openldap
- KCUNCOMMENT_LDAP_1=!include /usr/share/kopano/ldap.active-directory.cfg #delete if you want openldap
#- ADDITIONAL_KOPANO_PACKAGES=kopano-migration-imap
networks:
- kopanonet
volumes:
- ./data/kopano/:/kopano/data
- ./data/ssl/:/kopano/ssl
networks:
web:
kopanonet:
driver: bridge

298
docker-compose.yml-wip Normal file
View File

@ -0,0 +1,298 @@
version: '3'
services:
kserver:
image: zokradonh/kopano_core:${CORE_VERSION}
hostname: kserver
container_name: kopano_server
links:
- db
depends_on:
- "kssl"
environment:
- SERVICE_TO_START=server
- TZ=Europe/Berlin
- KCCONF_SERVER_COREDUMP_ENABLED=no
- KCCONF_SERVER_LOG_LEVEL=4
- KCCONF_SERVER_MYSQL_HOST=db
- KCCONF_SERVER_MYSQL_PORT=3306
- KCCONF_SERVER_MYSQL_DATABASE=kopano
- KCCONF_SERVER_MYSQL_USER=root
- KCCONF_SERVER_MYSQL_PASSWORD=YOUR_MYSQL_ROOT_PASSWORD #change here
- KCCONF_SERVER_SERVER_SSL_KEY_FILE=/kopano/ssl/kserver.pem
- KCCONF_SERVER_SERVER_SSL_CA_FILE=/kopano/ssl/ca.pem
- KCCONF_SERVER_SSLKEYS_PATH=/kopano/ssl/clients
- KCCONF_SERVER_PROXY_HEADER=* # delete line if webapp is not behind reverse proxy
- KCCONF_SERVER_SYSTEM_EMAIL_ADDRESS=hostmaster@domain.tld #change here
- KCCONF_SERVER_DISABLED_FEATURES=pop3
- KCCONF_SERVER_SEARCH_SOCKET=http://ksearch:2380/
- KCCONF_LDAP_LDAP_URI=ldaps://ldapserver:ldapport #change here
- KCCONF_LDAP_LDAP_BIND_USER=cn=SOME_STANDARD_USER,OU=MyUsers,DC=domain,DC=tld #change here
- KCCONF_LDAP_LDAP_BIND_PASSWD=PASSWORD_OF_STANDARD_USER #change here
- KCCONF_LDAP_LDAP_SEARCH_BASE=OU=MyUsers,dc=domain,dc=tld #change here
- KCCOMMENT_LDAP_1=!include /usr/share/kopano/ldap.openldap.cfg #delete if you want openldap
- KCUNCOMMENT_LDAP_1=!include /usr/share/kopano/ldap.active-directory.cfg #delete if you want openldap
networks:
- kopanonet
volumes:
- data:/kopano/data
- sslcerts:/kopano/ssl
kdagent:
image: zokradonh/kopano_core:${CORE_VERSION}
container_name: kopano_dagent
links:
- kserver
volumes:
- sslcerts:/kopano/ssl
environment:
- SERVICE_TO_START=dagent
- TZ=Europe/Berlin
- KCCONF_DAGENT_LOG_LEVEL=6
- KCCONF_DAGENT_SERVER_SOCKET=https://kserver:237/
- KCCONF_DAGENT_SSLKEY_FILE=/kopano/ssl/kdagent.pem
networks:
- kopanonet
kgateway:
image: zokradonh/kopano_core:${CORE_VERSION}
container_name: kopano_gateway
links:
- kserver
volumes:
- ./gatewaycerts/:/kopano/certs/
environment:
- SERVICE_TO_START=gateway
- TZ=Europe/Berlin
- KCCONF_GATEWAY_SERVER_SOCKET=http://kserver:236/
- KCCONF_GATEWAY_SSL_PRIVATE_KEY_FILE=/kopano/certs/yourcert.key # change here
- KCCONF_GATEWAY_SSL_CERTIFICATE_FILE=/kopano/certs/yourcert.pem # change here
networks:
- kopanonet
kical:
image: zokradonh/kopano_core:${CORE_VERSION}
container_name: kopano_ical
links:
- kserver
environment:
- SERVICE_TO_START=ical
- TZ=Europe/Berlin
- KCCONF_ICAL_SERVER_SOCKET=http://kserver:236/
networks:
- kopanonet
kmonitor:
image: zokradonh/kopano_core:${CORE_VERSION}
container_name: kopano_monitor
links:
- kserver
volumes:
- sslcerts:/kopano/ssl
environment:
- SERVICE_TO_START=monitor
- TZ=Europe/Berlin
- KCCONF_MONITOR_SERVER_SOCKET=https://kserver:237/
- KCCONF_MONITOR_SSLKEY_FILE=/kopano/ssl/kmonitor.pem
networks:
- kopanonet
ksearch:
image: zokradonh/kopano_core:${CORE_VERSION}
container_name: kopano_search
links:
- kserver
volumes:
- sslcerts:/kopano/ssl
environment:
- SERVICE_TO_START=search
- TZ=Europe/Berlin
- KCCONF_SEARCH_SERVER_BIND_NAME=http://ksearch:2380
- KCCONF_SEARCH_SERVER_SOCKET=https://kserver:237/
- KCCONF_SEARCH_SSLKEY_FILE=/kopano/ssl/ksearch.pem
networks:
- kopanonet
kspooler:
image: zokradonh/kopano_core:${CORE_VERSION}
container_name: kopano_spooler
links:
- kserver
volumes:
- sslcerts:/kopano/ssl
environment:
- SERVICE_TO_START=spooler
- TZ=Europe/Berlin
- KCCONF_SPOOLER_SERVER_SOCKET=https://kserver:237/
- KCCONF_SPOOLER_LOG_LEVEL=4
- KCCONF_SPOOLER_SMTP_SERVER=kmta
- KCCONF_SPOOLER_SSLKEY_FILE=/kopano/ssl/kspooler.pem
networks:
- kopanonet
kwebapp:
image: zokradonh/kopano_webapp:${WEBAPP_VERSION}
hostname: kwebapp
container_name: kopano_webapp
links:
- kserver
#ports:
# - "8236:80"
# - "8237:443"
volumes:
- syncstates:/var/lib/z-push/
- sslcerts:/kopano/ssl
environment:
- TZ=Europe/Berlin
- KCCONF_SERVERHOSTNAME=kserver
- KCCONF_SERVERPORT=237
networks:
- web
- kopanonet
kssl:
image: zokradonh/kopano_ssl
container_name: kopano_ssl
volumes:
- sslcerts:/kopano/ssl
kmta:
image: tvial/docker-mailserver:latest
hostname: myhost #change here
domainname: domain.tld #change here
#dns: 127.0.0.1
container_name: kopano_mta
#links:
# - adtunnel
ports:
- "25:25"
# - "143:143"
# - "587:587"
# - "993:993"
volumes:
- tmpmaildata:/var/mail
- tmpmailstate:/var/mail-state
- ./mtaconfig/:/tmp/docker-mailserver/ # create this dir
environment:
- TZ=Europe/Berlin
- ENABLE_SPAMASSASSIN=1
- ENABLE_CLAMAV=1
- ENABLE_FAIL2BAN=1
- ENABLE_POSTGREY=1
- TLS_LEVEL=intermediate
- POSTGREY_DELAY=10
- ONE_DIR=1
- DMS_DEBUG=0
- ENABLE_LDAP=1
- LDAP_SERVER_HOST=ldaps://ldapserver:ldapport #change here
- LDAP_SEARCH_BASE=OU=MyUsers,DC=domain,DC=tld #change here
- LDAP_BIND_DN=cn=SOME_STANDARD_USER,OU=MyUsers,DC=domain,DC=tld #change here
- LDAP_BIND_PW=PASSWORD_OF_SOME_STANDARD_USER #change here
- LDAP_QUERY_FILTER_USER=(&(objectClass=user)(|(mail=%s)(otherMailbox=%s)))
- LDAP_QUERY_FILTER_GROUP=(&(objectclass=group)(mail=%s))
- LDAP_QUERY_FILTER_ALIAS=(&(objectClass=user)(otherMailbox=%s))
- LDAP_QUERY_FILTER_DOMAIN=(&(|(mail=*@%s)(otherMailbox=*@%s)(mailGroupMember=*@%s))(kopanoAccount=1)(|(objectClass=user)(objectclass=group)))
- ENABLE_SASLAUTHD=1
- SASLAUTHD_LDAP_SERVER=ldaps://ldapserver:ldapport #change here
- SASLAUTHD_LDAP_BIND_DN=cn=SOME_STANDARD_USER,OU=MyUsers,DC=domain,DC=tld #change here
- SASLAUTHD_LDAP_PASSWORD=PASSWORD_OF_SOME_STANDARD_USER #change here
- SASLAUTHD_LDAP_SEARCH_BASE=OU=MyUsers,DC=domain,DC=tld #change here
- SASLAUTHD_LDAP_FILTER=(&(sAMAccountName=%U)(objectClass=person))
- SASLAUTHD_MECHANISMS=ldap
- POSTMASTER_ADDRESS=postmaster@domain.tld #change here
- SMTP_ONLY=1
- PERMIT_DOCKER=network
- ENABLE_POSTFIX_VIRTUAL_TRANSPORT=1
- POSTFIX_DAGENT=lmtp:kdagent:2003
- REPORT_RECIPIENT=1
networks:
- kopanonet
cap_add:
- NET_ADMIN
- SYS_PTRACE
db:
image: mariadb
restart: always
container_name: kopano_db
volumes:
- db:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=YOUR_MYSQL_ROOT_PASSWORD #change here
- MYSQL_PASSWORD=YOUR_PASSWORD #change here
- MYSQL_DATABASE=kopano
- MYSQL_USER=kopano
networks:
- kopanonet
volumes:
db:
data:
syncstates:
sslcerts:
tmpmaildata:
tmpmailstate:
networks:
web:
external:
driver: default
kopanonet:
driver: bridge
version: "3"
services:
rainloop:
image: hardware/rainloop
links:
- mail
volumes:
- ./data/rainloop:/rainloop/data
mail:
image: tvial/docker-mailserver:latest
restart: always
hostname: mail
domainname: fancydomain.tld
container_name: mail
ports:
- "25:25"
- "143:143"
- "587:587"
- "993:993"
- "4190:4190"
volumes:
- ./data/mail/data:/var/mail
- ./data/mail/state:/var/mail-state
- ./mail/config:/tmp/docker-mailserver/
- ./data/entry/acme/acme-v01.api.letsencrypt.org/sites/mail.fancydomain.tld:/tmp/ssl:ro
environment:
- ENABLE_SPAMASSASSIN=1
- ENABLE_CLAMAV=1
- ENABLE_FAIL2BAN=1
- ENABLE_POSTGREY=1
- ONE_DIR=1
- DMS_DEBUG=0
- ENABLE_MANAGESIEVE=1
- SSL_TYPE=manual
- SSL_CERT_PATH=/tmp/ssl/mail.fancydomain.tld.crt
- SSL_KEY_PATH=/tmp/ssl/mail.fancydomain.tld.key
cap_add:
- NET_ADMIN
entry:
image: abiosoft/caddy:0.10.4
restart: always
privileged: true
links:
- rainloop
ports:
- "80:80"
- "443:443"
volumes:
- ./entry/Caddyfile:/etc/Caddyfile
- ./data/entry:/root/.caddy

View File

@ -1,61 +0,0 @@
# Using Apache as the front facing reverse proxy
Example provided by [ronnybremer](https://github.com/ronnybremer) in [Add reverse proxy example for Apache](https://github.com/zokradonh/kopano-docker/issues/372).
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`.
```bash
<VirtualHost aaa.bbb.ccc.ddd:443 [aaaa:bbbb:cccc:dddd:eeee:ffff::yy]:443>
ServerName public.domain.com:443
ServerAdmin your_friendly_admin@domain.com
UseCanonicalName On
ErrorLog logs/meet_ssl_error_log
CustomLog logs/meet_ssl_access_log combined
LogLevel warn
SSLEngine on
SSLCompression off
SSLProxyEngine off
SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:3DES:!aNULL:!MD5:!SEED:!IDEA
# for higher security
# SSLCipherSuite EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH
SSLHonorCipherOrder on
SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
Header unset X-Frame-Options
Header unset Content-Security-Policy
RewriteEngine On
# Meet and PWAs only work on https
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} ^/meet$ [OR]
RewriteCond %{REQUEST_URI} ^/meet/
RewriteRule ^(.*)$ https://public.domain.com/meet/ [R,L]
# We need to access Meet through the proper domain
RewriteCond %{REQUEST_URI} ^/meet$ [OR]
RewriteCond %{REQUEST_URI} ^/meet/
RewriteCond %{HTTP_HOST} !^public.domain.com$ [NC]
RewriteRule ^(.*)$ https://public.domain.com/meet/ [R,L]
# Upgrade Websocket connections
RewriteCond %{HTTP:Connection} Upgrade [NC]
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteRule /api/kwm/v2/(.*) ws://internal.domain.com:2015/api/kwm/v2/$1 [P,L]
<Directory />
Order deny,allow
Deny from all
</Directory>
<Location />
ProxyPass http://internal.domain.com:2015/
ProxyPassReverse http://internal.domain.com:2015/
ProxyPreserveHost On
</Location>
</VirtualHost>
```

View File

@ -1,107 +0,0 @@
version: "3.5"
services:
ldap:
image: ${docker_repo:-zokradonh}/kopano_ldap_demo
container_name: ldap
ports:
- ${LDAPPORT:-389}:389
environment:
- LDAP_ORGANISATION=${LDAP_ORGANISATION}
- LDAP_DOMAIN=${LDAP_DOMAIN}
- LDAP_BASE_DN=${LDAP_BASE_DN}
- LDAP_ADMIN_PASSWORD=${LDAP_ADMIN_PASSWORD}
- LDAP_READONLY_USER=true
- LDAP_READONLY_USER_PASSWORD=${LDAP_READONLY_USER_PASSWORD}
command: "--loglevel info --copy-service"
volumes:
- ldap:/var/lib/ldap
- slapd:/etc/ldap/slapd.d
networks:
- ldap-net
db:
image: mariadb:10.3.10-bionic
restart: always
container_name: kopano_db
volumes:
- mysql/:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- MYSQL_USER=${MYSQL_USER}
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_DATABASE=${MYSQL_DATABASE}
healthcheck:
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']
interval: 30s
timeout: 10s
retries: 4
networks:
- kopano-net
kopano_ssl:
image: ${docker_repo:-zokradonh}/kopano_ssl
container_name: kopano_ssl
environment:
- FQDN=${FQDN}
- PKI_COUNTRY=NL
volumes:
- /etc/kopano/ssl/:/kopano/ssl
kopano_server:
image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest}
hostname: kopano_server
container_name: kopano_server
depends_on:
- db
- ldap
- kopano_ssl
ports:
- ${KOPANOPORT:-236}:236
- ${KOPANOSPORT:-237}:237
environment:
- SERVICE_TO_START=server
- TZ=${TZ}
- KCCONF_SERVER_COREDUMP_ENABLED=no
- KCCONF_SERVER_LOG_LEVEL=3
- KCCONF_SERVER_MYSQL_HOST=${MYSQL_HOST}
- KCCONF_SERVER_MYSQL_PORT=3306
- KCCONF_SERVER_MYSQL_DATABASE=${MYSQL_DATABASE}
- KCCONF_SERVER_MYSQL_USER=${MYSQL_USER}
- KCCONF_SERVER_MYSQL_PASSWORD=${MYSQL_PASSWORD}
- KCCONF_SERVER_SERVER_SSL_KEY_FILE=/kopano/ssl/kopano_server.pem
- KCCONF_SERVER_SERVER_SSL_CA_FILE=/kopano/ssl/ca.pem
- KCCONF_SERVER_SERVER_NAME=Kopano
- KCCONF_SERVER_SSLKEYS_PATH=/kopano/ssl/clients
- KCCONF_SERVER_PROXY_HEADER=* # delete line if webapp is not behind reverse proxy
- KCCONF_SERVER_SYSTEM_EMAIL_ADDRESS=${POSTMASTER_ADDRESS}
- KCCONF_SERVER_SYNC_GAB_REALTIME=no
- KCCONF_LDAP_LDAP_URI=${LDAP_SERVER}
- KCCONF_LDAP_LDAP_BIND_USER=${LDAP_BIND_DN}
- KCCONF_LDAP_LDAP_BIND_PASSWD=${LDAP_BIND_PW}
- KCCONF_LDAP_LDAP_SEARCH_BASE=${LDAP_SEARCH_BASE}
- KCUNCOMMENT_LDAP_1=${KCUNCOMMENT_LDAP_1}
- KCCOMMENT_LDAP_1=${KCCOMMENT_LDAP_1}
- ADDITIONAL_KOPANO_PACKAGES=${ADDITIONAL_KOPANO_PACKAGES}
networks:
- kopano-net
- ldap-net
- web-net
volumes:
- kopanodata/:/kopano/data
- /etc/kopano/ssl/:/kopano/ssl
- /run/kopano/:/run/kopano
volumes:
ldap:
slapd:
mysql:
kopanodata:
networks:
web-net:
kopano-net:
driver: bridge
ldap-net:
name: ldap-net
driver: bridge

View File

@ -1,7 +0,0 @@
version: "3.5"
services:
# disable services
mail:
image: hello-world
restart: "no"

View File

@ -1,40 +0,0 @@
version: "3.5"
# example file to store attachments in s3 (provided by minio)
# rename to docker-compose.override.yml and place it along the existing file to use it
# (and change accesskey an secretkey below)
services:
kopano_server:
depends_on:
- minio
environment:
- KCCONF_SERVER_ATTACHMENT_STORAGE=s3
- KCCONF_SERVER_LOG_LEVEL=6
- KCCONF_SERVER_ATTACHMENT_S3_HOSTNAME=minio:9000
- KCCONF_SERVER_ATTACHMENT_S3_PROTOCOL=http
- KCCONF_SERVER_ATTACHMENT_S3_URISTYLE=path
- KCCONF_SERVER_ATTACHMENT_S3_REGION=us-east-1
- KCCONF_SERVER_ATTACHMENT_S3_ACCESSKEYID=ACCESSKEY
- KCCONF_SERVER_ATTACHMENT_S3_SECRETACCESSKEY=SECRETKEY
- KCCONF_SERVER_ATTACHMENT_S3_BUCKETNAME=kopano
- KCCONF_SERVER_ATTACHMENT_PATH=attachments
minio:
image: minio/minio
ports:
- '9000:9000'
volumes:
- miniodata:/export
- minioconfig:/root/.minio
environment:
- MINIO_ACCESS_KEY=ACCESSKEY
- MINIO_SECRET_KEY=SECRETKEY
command: server /data
entrypoint: sh
command: -c 'mkdir -p /export/kopano && /usr/bin/minio server /export'
networks:
- kopano-net
volumes:
miniodata:
minioconfig:

View File

@ -1,7 +0,0 @@
version: "3.5"
services:
watchtower:
image: v2tec/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock

View File

@ -1,15 +0,0 @@
# Configuration example for running Kopano in a Multiserver setup
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.
**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.
1. Add the `kopano-multiserver.yml` to the `COMPOSE_FILE` variable in your `.env` file.
Example:
```bash
COMPOSE_FILE=docker-compose.yml:docker-compose.ports.yml:examples/kopano-multiserver/kopano-multiserver.yml
```
2. run `docker-compose up -d` from the root of this project.

View File

@ -1,96 +0,0 @@
version: "3.5"
services:
db:
volumes:
- ./database/create-additional-databases.sh:/docker-entrypoint-initdb.d/create-additional-databases.sh
environment:
- MYSQL_ADDITIONAL_DATABASES=${MYSQL_DATABASE}2
kopano_server:
environment:
- KCCONF_ADMIN_SSLKEY_FILE=/kopano/ssl/admin.pem
- KCCONF_SERVER_ENABLE_DISTRIBUTED_KOPANO=true
- KCCONF_SERVER_SERVER_NAME=kopano_server
kopano_server_2:
image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest}
hostname: kopano_server_2
container_name: ${COMPOSE_PROJECT_NAME}_server_2
depends_on:
- db
- kopano_konnect
- kopano_ssl
- ldap
environment:
- ADDITIONAL_KOPANO_PACKAGES=${ADDITIONAL_KOPANO_PACKAGES}
- KCCOMMENT_LDAP_1=${KCCOMMENT_LDAP_1}
- KCCONF_ADMIN_SSLKEY_FILE=/kopano/ssl/admin.pem
- KCCONF_LDAP_LDAP_BIND_PASSWD=${LDAP_BIND_PW}
- KCCONF_LDAP_LDAP_BIND_USER=${LDAP_BIND_DN}
- KCCONF_LDAP_LDAP_SEARCH_BASE=${LDAP_SEARCH_BASE}
- KCCONF_LDAP_LDAP_URI=${LDAP_SERVER}
- KCCONF_SERVER_COREDUMP_ENABLED=no
- KCCONF_SERVER_ENABLE_DISTRIBUTED_KOPANO=true
- KCCONF_SERVER_ENABLE_SSO=yes
- KCCONF_SERVER_KCOIDC_INSECURE_SKIP_VERIFY=${INSECURE}
- KCCONF_SERVER_KCOIDC_ISSUER_IDENTIFIER=https://${FQDN}
- KCCONF_SERVER_MYSQL_DATABASE=${MYSQL_DATABASE}2
- KCCONF_SERVER_MYSQL_HOST=${MYSQL_HOST}
- KCCONF_SERVER_MYSQL_PASSWORD=${MYSQL_PASSWORD}
- KCCONF_SERVER_MYSQL_PORT=3306
- KCCONF_SERVER_MYSQL_USER=${MYSQL_USER}
- KCCONF_SERVER_PROXY_HEADER=* # delete line if webapp is not behind reverse proxy
- KCCONF_SERVER_SERVER_NAME=kopano_server_2
- KCCONF_SERVER_SERVER_SSL_CA_FILE=/kopano/ssl/ca.pem
- KCCONF_SERVER_SERVER_SSL_KEY_FILE=/kopano/ssl/kopano_server_2.pem
- KCCONF_SERVER_SSLKEYS_PATH=/kopano/ssl/clients
- KCCONF_SERVER_SYSTEM_EMAIL_ADDRESS=${POSTMASTER_ADDRESS}
- KCUNCOMMENT_LDAP_1=${KCUNCOMMENT_LDAP_1}
- SERVICE_TO_START=server
- TZ=${TZ}
env_file:
- kopano_server.env
networks:
- kopano-net
- ldap-net
- web-net
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanodata2/:/kopano/data
- kopanosocket2/:/run/kopano
- kopanossl/:/kopano/ssl
kopano_spooler_2:
image: ${docker_repo:-zokradonh}/kopano_core:${CORE_VERSION:-latest}
restart: unless-stopped
hostname: spooler_2
container_name: ${COMPOSE_PROJECT_NAME}_spooler_2
domainname: ${LDAP_DOMAIN}
depends_on:
- kopano_server_2
- mail
volumes:
- kopanosocket2/:/run/kopano
- kopanossl/:/kopano/ssl
environment:
- KCCONF_SPOOLER_LOG_LEVEL=3
- KCCONF_SPOOLER_SMTP_SERVER=mail
- KCCONF_SPOOLER_SSLKEY_FILE=/kopano/ssl/kopano_spooler.pem
- SERVICE_TO_START=spooler
- TZ=${TZ}
env_file:
- kopano_spooler.env
networks:
- kopano-net
kopano_scheduler:
depends_on:
- kopano_server_2
environment:
- CRON_KOPANOUSERS2=10 * * * * docker exec kopano_server_2 kopano-admin --sync
volumes:
kopanodata2:
kopanosocket2:

View File

@ -1,45 +0,0 @@
# Running Kopano Meet without Kopano (with only the LDAP backend)
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.
Check https://github.com/zokradonh/kopano-docker/blob/master/ldap_demo/README.md to learn more about the included demo users.
## Instructions
1. run `setup.sh`
2. check `.env` for any required customization (port 443 already in use?)
3. run `docker-compose up` to start
4. navigate to https://your-domain to login to Kopano Meet
## Additional environment variables for using ActiveDirectory
Create the a file named `docker-compose.override.yml` with the following content in case you are using Microsoft ActiveDirectory.
```yaml
version: "3.5"
services:
kopano_grapi:
environment:
- LDAP_FILTER=(&(objectClass=organizationalPerson)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))
- LDAP_LOGIN_ATTRIBUTE=sAMAccountName
- LDAP_EMAIL_ATTRIBUTE=mail
- LDAP_NAME_ATTRIBUTE=displayName
- LDAP_FAMILY_NAME_ATTRIBUTE=sn
- LDAP_GIVEN_NAME_ATTRIBUTE=givenName
- LDAP_JOB_TITLE_ATTRIBUTE=title
- LDAP_OFFICE_LOCATION_ATTRIBUTE=L
- LDAP_BUSINESS_PHONE_ATTRIBUTE=telephoneNumber
- LDAP_MOBILE_PHONE_ATTRIBUTE=mobile
- USERID_SEARCH_FILTER_TEMPLATE=({loginAttribute}=%(userid)s)
- SEARCH_SEARCH_FILTER_TEMPLATE=(&(objectClass=organizationalPerson)(!(UserAccountControl:1.2.840.113556.1.4.803:=2))(|({emailAttribute}=*%(search)s*)({givenNameAttribute}=*%(search)s*)({familyNameAttribute}=*%(search)s*)))
kopano_konnect:
environment:
- LDAP_LOGIN_ATTRIBUTE=sAMAccountName
- LDAP_NAME_ATTRIBUTE=displayName
- LDAP_UUID_ATTRIBUTE_TYPE=binary
- LDAP_UUID_ATTRIBUTE=objectGUID
```

View File

@ -1,42 +0,0 @@
# Architecture Overview
## web
- external entry point for users accessing Kopano Meet
- reverse proxy for kopano_kapi, kopano_konnect, kopano_kwmserver and kopano_meet
- can retrieve ssl certificate from Lets Encrypt
- redirects all requests to /meet
- recommended to use as it makes web configuration easy and secure (manual configuration will be tendious and potentially less secure)
## ldap
- (optional) bundles OpenLDAP service
- Konnect and Grapi are using it
## kopano_ssl
- helper container to generate ssl certificates for internal usage
- will create required files and then stop
## kopano_grapi
- groupware backend of the Kopano RestAPI
- connects to LDAP to provide a global addressbook to users
## kopano_kapi
- http endpoint of the Kopano RestAPI
- stores recent calls for the user in a key value stores (queried over Rest)
## kopano_konnect
- authentification component (OpenID Connect) for Meet
- connects to the LDAP backend to verify user logins via bind
## kopano_kwmserver
- WebRTC signalling server
## kopano_meet
- provides the Meet web application/frontend

View File

@ -1,26 +0,0 @@
version: "3.5"
services:
kopano_kwmserver:
environment:
- enable_mcu_api=yes
- pipeline_forced_regexp=@conference/.*
#- pipeline_forced_regexp=@group/.*
kopano_kwmbridge:
image: ${docker_repo:-zokradonh}/kopano_kwmbridge:${KWMBRIDGE_VERSION:-latest}
read_only: true
restart: unless-stopped
depends_on:
- kopano_kwmserver
environment:
- INSECURE=${INSECURE}
- oidc_issuer_identifier=https://${FQDN}
- kwm_server_urls=https://${FQDN}
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanossl/:/kopano/ssl
network_mode: "host"
tmpfs:
- /tmp

View File

@ -1,201 +0,0 @@
version: "3.5"
services:
web:
image: ${docker_repo:-kopano}/kopano_web:${KWEB_VERSION:-latest}
restart: unless-stopped
ports:
- "${CADDY:-2015}:2015"
- "${HTTP:-80}:80"
- "${HTTPS:-443}:443"
environment:
- DEFAULTREDIRECT=/meet
- EMAIL=${EMAIL:-off}
- FQDN=${FQDN}
command: wrapper.sh
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- web:/.kweb
networks:
web-net:
aliases:
- ${FQDNCLEANED:-domain.invalid}
ldap:
image: ${docker_repo:-kopano}/${LDAP_CONTAINER:-kopano_ldap_demo}:${LDAP_VERSION:-latest}
restart: unless-stopped
container_name: ${COMPOSE_PROJECT_NAME}_ldap
environment:
- LDAP_ADMIN_PASSWORD=${LDAP_ADMIN_PASSWORD}
- LDAP_BASE_DN=${LDAP_BASE_DN}
- LDAP_DOMAIN=${LDAP_DOMAIN}
- LDAP_ORGANISATION=${LDAP_ORGANISATION}
- LDAP_READONLY_USER_PASSWORD=${LDAP_READONLY_USER_PASSWORD}
- LDAP_READONLY_USER=true
command: "--loglevel info --copy-service"
volumes:
- ldap:/var/lib/ldap
- slapd:/etc/ldap/slapd.d
networks:
- ldap-net
kopano_ssl:
image: ${docker_repo:-kopano}/kopano_ssl:${SSL_VERSION:-latest}
environment:
- FQDN=${FQDN}
- PKI_COUNTRY=NL
volumes:
- kopanossl/:/kopano/ssl
kopano_kustomer:
image: kopano/kustomerd:${KUSTOMER_VERSION:-latest}
restart: unless-stopped
command: serve
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanolicenses:/etc/kopano/licenses
- kopanosocket/:/run/kopano
kopano_grapi:
image: ${docker_repo:-kopano}/kopano_core:${CORE_VERSION:-latest}
restart: unless-stopped
container_name: ${COMPOSE_PROJECT_NAME}_grapi
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanosocket/:/run/kopano
environment:
- GRAPI_BACKEND=ldap
- LDAP_BASEDN=${LDAP_SEARCH_BASE}
- LDAP_BINDDN=${LDAP_BIND_DN}
- LDAP_BINDPW=${LDAP_BIND_PW}
- LDAP_URI=${LDAP_SERVER}
- SERVICE_TO_START=grapi
- TZ=${TZ}
networks:
- kopano-net
- ldap-net
kopano_kapi:
image: ${docker_repo:-kopano}/kopano_core:${CORE_VERSION:-latest}
restart: unless-stopped
container_name: ${COMPOSE_PROJECT_NAME}_kapi
depends_on:
- kopano_grapi
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanodata/:/kopano/data
- kopanosocket/:/run/kopano
- kopanossl/:/kopano/ssl
environment:
- DEFAULT_PLUGIN_PUBS_SECRET_KEY_FILE=/kopano/ssl/kapid-pubs-secret.key
- KCCONF_KAPID_INSECURE=${INSECURE}
- KCCONF_KAPID_LISTEN=0.0.0.0:8039
- KCCONF_KAPID_LOG_LEVEL=DEBUG
- KCCONF_KAPID_LOG_LEVEL=info
- KCCONF_KAPID_OIDC_ISSUER_IDENTIFIER=https://${FQDN}
- KCCONF_KAPID_PLUGIN_GRAPI_SOCKET_PATH=/var/run/kopano/grapi
- KCCONF_KAPID_PLUGIN_KVS_DB_DATASOURCE=/kopano/data/kapi-kvs/kvs.db
- SERVICE_TO_START=kapi
- TZ=${TZ}
networks:
- kopano-net
- web-net
kopano_konnect:
image: ${docker_repo:-kopano}/kopano_konnect:${KONNECT_VERSION:-latest}
restart: unless-stopped
depends_on:
- kopano_ssl
- web
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanossl/:/kopano/ssl
environment:
- allow_client_guests=yes
- allow_dynamic_client_registration=yes
- eckey=/kopano/ssl/meet-kwmserver.pem
- ecparam=/kopano/ssl/ecparam.pem
- encryption_secret_key=/kopano/ssl/konnectd-encryption.key
- FQDN=${FQDN}
- identifier_registration_conf=/kopano/ssl/konnectd-identifier-registration.yaml
- identifier_scopes_conf=/etc/kopano/konnectd-identifier-scopes.yaml
- KONNECT_BACKEND=ldap
- LDAP_BASEDN=${LDAP_SEARCH_BASE}
- LDAP_BINDDN=${LDAP_BIND_DN}
- LDAP_BINDPW=${LDAP_BIND_PW}
- LDAP_EMAIL_ATTRIBUTE=mail
- LDAP_FILTER=(objectClass=organizationalPerson)
- LDAP_LOGIN_ATTRIBUTE=uid
- LDAP_NAME_ATTRIBUTE=cn
- LDAP_SCOPE=sub
- LDAP_URI=${LDAP_SERVER}
- LDAP_UUID_ATTRIBUTE_TYPE=text
- LDAP_UUID_ATTRIBUTE=uidNumber
- signing_private_key=/kopano/ssl/konnectd-tokens-signing-key.pem
networks:
- kopano-net
- ldap-net
- web-net
kopano_kwmserver:
image: ${docker_repo:-kopano}/kopano_kwmserver:${KWM_VERSION:-latest}
restart: unless-stopped
command: wrapper.sh
depends_on:
- kopano_kapi
- kopano_konnect
environment:
- enable_guest_api=yes
- INSECURE=${INSECURE}
- oidc_issuer_identifier=https://${FQDN}
- public_guest_access_regexp=^group/public/.*
- registration_conf=/kopano/ssl/konnectd-identifier-registration.yaml
- turn_service_credentials_password=${TURN_PASSWORD}
- turn_service_credentials_user=${TURN_USER}
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
- kopanossl/:/kopano/ssl
networks:
- web-net
kopano_meet:
image: ${docker_repo:-kopano}/kopano_meet:${MEET_VERSION:-latest}
restart: unless-stopped
environment:
- KCCONF_MEET_disableFullGAB=false
- KCCONF_MEET_GRID_WEBAPP=no
- KCCONF_MEET_guests_enabled=true
- KCCONF_MEET_useIdentifiedUser=true
- SERVICE_TO_START=meet
depends_on:
- kopano_kapi
- kopano_konnect
- kopano_kwmserver
- web
volumes:
- /etc/machine-id:/etc/machine-id
- /etc/machine-id:/var/lib/dbus/machine-id
networks:
- web-net
volumes:
kopanodata:
kopanolicenses:
kopanosocket:
kopanossl:
ldap:
slapd:
web:
networks:
kopano-net:
driver: bridge
ldap-net:
driver: bridge
web-net:

View File

@ -1,40 +0,0 @@
# please consult https://github.com/kopano-dev/kopano-docker
# for possible configuration values and their impact
# Access to the Kopano Turn service can be requested at https://portal.kopano.com/content/turn-server-access-request
TURN_USER=
TURN_PASSWORD=
# Defines how Kopano can be accessed from the outside world
FQDN=kopano.demo
FQDNCLEANED=kopano.demo
DEFAULTREDIRECT=/meet
EMAIL=self_signed
CADDY=2015
HTTP=80
HTTPS=443
TZ=Europe/Berlin
LDAP_CONTAINER=kopano_ldap_demo
LDAP_ORGANISATION="Kopano Demo"
LDAP_DOMAIN=kopano.demo
LDAP_BASE_DN=dc=kopano,dc=demo
LDAP_SERVER=ldap://ldap:389
LDAP_ADMIN_PASSWORD=adminpassword
LDAP_READONLY_USER_PASSWORD=readonlypassword
LDAP_BIND_DN=cn=readonly,dc=kopano,dc=demo
LDAP_BIND_PW=readonlypassword
LDAP_SEARCH_BASE=dc=kopano,dc=demo
# Settings for test environments
INSECURE=yes
# Docker and docker-compose settings
# Docker Repository to push to/pull from
docker_repo=kopano
COMPOSE_PROJECT_NAME=kopano
# Additional packages to install
ADDITIONAL_KOPANO_PACKAGES=python3-grapi.backend.ldap

Some files were not shown because too many files have changed in this diff Show More