diff --git a/database/README.md b/database/README.md new file mode 100644 index 0000000..cca1906 --- /dev/null +++ b/database/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/database/create-additional-databases.sh b/database/create-additional-databases.sh new file mode 100644 index 0000000..f09bae7 --- /dev/null +++ b/database/create-additional-databases.sh @@ -0,0 +1,20 @@ +#!/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 diff --git a/examples/kopano-multiserver/README.md b/examples/kopano-multiserver/README.md new file mode 100644 index 0000000..0c1887a --- /dev/null +++ b/examples/kopano-multiserver/README.md @@ -0,0 +1,15 @@ +# 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. \ No newline at end of file diff --git a/examples/kopano-multiserver/kopano-multiserver.yml b/examples/kopano-multiserver/kopano-multiserver.yml new file mode 100644 index 0000000..070fbba --- /dev/null +++ b/examples/kopano-multiserver/kopano-multiserver.yml @@ -0,0 +1,95 @@ +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_SERVER_SERVER_NAME=kopano_server + - KCCONF_SERVER_ENABLE_DISTRIBUTED_KOPANO=true + - KCCONF_ADMIN_SSLKEY_FILE=/kopano/ssl/admin.pem + + 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 + - ldap + - kopano_ssl + - kopano_konnect + environment: + - SERVICE_TO_START=server + - TZ=${TZ} + - KCCONF_SERVER_COREDUMP_ENABLED=no + - KCCONF_SERVER_MYSQL_HOST=${MYSQL_HOST} + - KCCONF_SERVER_MYSQL_PORT=3306 + - KCCONF_SERVER_MYSQL_DATABASE=${MYSQL_DATABASE}2 + - KCCONF_SERVER_MYSQL_USER=${MYSQL_USER} + - KCCONF_SERVER_MYSQL_PASSWORD=${MYSQL_PASSWORD} + - KCCONF_SERVER_SERVER_SSL_KEY_FILE=/kopano/ssl/kopano_server_2.pem + - KCCONF_SERVER_SERVER_SSL_CA_FILE=/kopano/ssl/ca.pem + - KCCONF_SERVER_SERVER_NAME=kopano_server_2 + - 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_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} + - KCCONF_SERVER_ENABLE_SSO=yes + - KCCONF_SERVER_KCOIDC_ISSUER_IDENTIFIER=https://${FQDN} + - KCCONF_SERVER_KCOIDC_INSECURE_SKIP_VERIFY=${INSECURE} + - KCCONF_SERVER_ENABLE_DISTRIBUTED_KOPANO=true + - KCCONF_ADMIN_SSLKEY_FILE=/kopano/ssl/admin.pem + env_file: + - kopano_server.env + networks: + - kopano-net + - ldap-net + - web-net + volumes: + - kopanodata2/:/kopano/data + - kopanossl/:/kopano/ssl + - kopanosocket2/:/run/kopano + + 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: + - kopanossl/:/kopano/ssl + - kopanosocket2/:/run/kopano + environment: + - SERVICE_TO_START=spooler + - TZ=${TZ} + - KCCONF_SPOOLER_LOG_LEVEL=3 + - KCCONF_SPOOLER_SMTP_SERVER=mail + - KCCONF_SPOOLER_SSLKEY_FILE=/kopano/ssl/kopano_spooler.pem + env_file: + - kopano_spooler.env + networks: + - kopano-net + + kopano_scheduler: + depends_on: + - kopano_server_2 + environment: + - TZ=${TZ} + - CRON_KOPANOUSERS2=10 * * * * docker exec kopano_server_2 kopano-admin --sync + +volumes: + kopanodata2: + kopanosocket2: diff --git a/ldap_demo/README.md b/ldap_demo/README.md index c2ddeb7..d0209a0 100644 --- a/ldap_demo/README.md +++ b/ldap_demo/README.md @@ -6,9 +6,15 @@ Image to for an OpenLDAP server to provide some demo users for Kopano. Based on The LDAP tree is prepared for both single tenant setups (the default in Kopano) and multi tenant setups. To configure the multi tenant mode (also referred to as "hosted") of `kopano-server` the following values need to be added to `kopano_server.env`: -``` +```bash KCCONF_SERVER_ENABLE_HOSTED_KOPANO=YES KCCONF_LDAP_LDAP_COMPANY_TYPE_ATTRIBUTE_VALUE=kopano-company ``` +Additionally the ldap tree is also prepared for multiserver installations (also referred to as "distributed"), where multiple `kopano-server` processes share the total amount of mailboxes (controlled through a manual mapping in LDAP). See [Multiserver Example](../examples/kopano-multiserver) for more information. + +```bash +$ docker-compose -f examples/kopano-multiserver.yml up +``` + Demo users created in the demo ldap all have a password that is identical to the username, e.g. the password for `user1` user `user1`. diff --git a/ldap_demo/bootstrap/ldif/demo-users.ldif b/ldap_demo/bootstrap/ldif/demo-users.ldif index 1fca67f..0eb861a 100644 --- a/ldap_demo/bootstrap/ldif/demo-users.ldif +++ b/ldap_demo/bootstrap/ldif/demo-users.ldif @@ -46,6 +46,38 @@ objectClass: organizationalUnit objectClass: top ou: resources +dn: ou=servers,{{ LDAP_BASE_DN }} +objectClass: organizationalUnit +objectClass: top +ou: servers + +dn: cn=kopano_server,ou=servers,{{ LDAP_BASE_DN }} +cn: kopano_server +description: Node 1 in a multi server setup +ipHostNumber: kopano_server +objectClass: device +objectClass: ipHost +objectClass: kopano-server +objectClass: top +kopanoContainsPublic: 1 +kopanoFilePath: /var/run/kopano/server.sock +kopanoHttpPort: 236 +kopanoSslPort: 237 + +# the kopanoFilePath below should be a different file than for node 2 (e.g. on a different volume) +dn: cn=kopano_server_2,ou=servers,{{ LDAP_BASE_DN }} +cn: kopano_server_2 +description: Node 2 in a multi server setup +ipHostNumber: kopano_server_2 +objectClass: device +objectClass: ipHost +objectClass: kopano-server +objectClass: top +kopanoContainsPublic: 0 +kopanoFilePath: /var/run/kopano/server.sock +kopanoHttpPort: 236 +kopanoSslPort: 237 + # user2, users, {{ LDAP_DOMAIN }} dn: uid=user2,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} gidNumber: 2 @@ -539,6 +571,7 @@ jpegphoto:: /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQO 1FFAF1W2KoAC8Z3Zxnn8PQCraT+ZbvGpbJwy8HHHPP60UUAdj8G9RW0lutEY7YZma6tVJ+42B5k f4cMPbPpXqe31zRRWUlqAgH4UEfU0UVIhhFG386KKBhtox7UUUwDbTdtFFACbaKKKQH/2Q== physicalDeliveryOfficeName: Munich +kopanoUserServer: kopano_server # user5, users, {{ LDAP_DOMAIN }} dn: uid=user5,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -973,6 +1006,7 @@ jpegphoto:: /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQO V6l/CKKKqGxU9yFmNRMeaKKtEEMvA4qvMcKKKKAK0hrPuHNFFAjI1HO1juOcVyurOwZACfvCiik DOm0V2a0jcnmq3i47bE+6UUU2M4nwkgL7u+etFFFCIluf//Z physicalDeliveryOfficeName: Urk +kopanoUserServer: kopano_server_2 # user6, users, {{ LDAP_DOMAIN }} dn: uid=user6,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -1000,6 +1034,7 @@ l: Nieuw-Schoonebeek postalCode: 9704BF street: Mettering 960 secretary: uid=user7,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} +kopanoUserServer: kopano_server # user7, users, {{ LDAP_DOMAIN }} dn: uid=user7,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -1028,6 +1063,7 @@ postalCode: 57621 street: Monika-Werner-Strasse 88 secretary: uid=user8,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} physicalDeliveryOfficeName: Barcelona +kopanoUserServer: kopano_server_2 # user8, users, {{ LDAP_DOMAIN }} dn: uid=user8,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -1055,6 +1091,7 @@ l: Koudum postalCode: 7263 YB street: Arieweg 464 secretary: uid=user9,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} +kopanoUserServer: kopano_server # user9, users, {{ LDAP_DOMAIN }} dn: uid=user9,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -1083,6 +1120,7 @@ l: Vriescheloo postalCode: 1984 GB street: Haileysteeg 758 secretary: uid=user10,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} +kopanoUserServer: kopano_server_2 # user10, users, {{ LDAP_DOMAIN }} dn: uid=user10,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -1110,6 +1148,7 @@ telephoneNumber: 088 9637134 labeledURI: http://www.van.org/ title: Patent examiner secretary: uid=user11,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} +kopanoUserServer: kopano_server # user11, users, {{ LDAP_DOMAIN }} dn: uid=user11,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -1801,6 +1840,7 @@ title: Education administrator l: Burgerveen postalCode: 3343RP secretary: uid=user12,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} +kopanoUserServer: kopano_server_2 # user12, users, {{ LDAP_DOMAIN }} dn: uid=user12,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -1829,6 +1869,7 @@ labeledURI: http://groettner.com/ title: Clinical cytogeneticist l: Eisenberg postalCode: 48453 +kopanoUserServer: kopano_server # user13, users, {{ LDAP_DOMAIN }} dn: uid=user13,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -1857,6 +1898,7 @@ title: Dramatherapist l: West Tatyanna postalCode: CV66 3NT secretary: uid=user14,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} +kopanoUserServer: kopano_server_2 # user14, users, {{ LDAP_DOMAIN }} dn: uid=user14,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -1885,6 +1927,7 @@ telephoneNumber: 0587440322 labeledURI: http://www.hermann.com/ title: Occupational psychologist secretary: uid=user15,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} +kopanoUserServer: kopano_server # user15, users, {{ LDAP_DOMAIN }} dn: uid=user15,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -1912,6 +1955,7 @@ mobile: +44(0)1706147107 telephoneNumber: 02296 80513 labeledURI: http://kirlin.com/ title: Training and development officer +kopanoUserServer: kopano_server_2 # user16, users, {{ LDAP_DOMAIN }} dn: uid=user16,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -1940,6 +1984,7 @@ title: Social worker l: Geithain postalCode: 41858 secretary: uid=user17,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} +kopanoUserServer: kopano_server # user17, users, {{ LDAP_DOMAIN }} dn: uid=user17,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -1967,6 +2012,7 @@ mobile: 02894 67296 telephoneNumber: +49(0)3335177743 labeledURI: http://bonbach.com/ title: Medical secretary +kopanoUserServer: kopano_server_2 # user18, users, {{ LDAP_DOMAIN }} dn: uid=user18,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -1995,6 +2041,7 @@ title: Exhibition designer l: Dinkelsbuhl postalCode: 70320 secretary: uid=user19,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} +kopanoUserServer: kopano_server # user19, users, {{ LDAP_DOMAIN }} dn: uid=user19,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -2022,6 +2069,7 @@ labeledURI: http://will.net/ title: Agricultural consultant l: South Marquiseshire postalCode: ML13 2RQ +kopanoUserServer: kopano_server_2 # beamer, resources, {{ LDAP_DOMAIN }} dn: uid=beamer,ou=resources,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -2042,6 +2090,7 @@ homeDirectory: /home/beamer sn: beamer uid: beamer mail: beamer@{{ LDAP_DOMAIN }} +kopanoUserServer: kopano_server # trainingroom, resources, {{ LDAP_DOMAIN }} dn: uid=trainingroom,ou=resources,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -2062,6 +2111,7 @@ kopanoResourceType: Room kopanoSharedStoreOnly: 1 userPassword:: dHJhaW5pbmdyb29t mail: trainingroom@{{ LDAP_DOMAIN }} +kopanoUserServer: kopano_server_2 # sharedbox, resources, {{ LDAP_DOMAIN }} dn: uid=sharedbox,ou=resources,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -2081,6 +2131,7 @@ kopanoAccount: 1 kopanoResourceCapacity: 1 mail: sharedbox@{{ LDAP_DOMAIN }} kopanoSharedStoreOnly: 1 +kopanoUserServer: kopano_server # sales, groups, {{ LDAP_DOMAIN }} dn: cn=sales,ou=groups,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -2705,6 +2756,7 @@ jpegphoto:: /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQO GdqgHHQ0UVRz3u7liNkdjHIRwuVbFWdMvGtLxDIxMT/ACk+lFFZtJ6HqYevOlONWDs0/wBTqt3p RmiiuM/V4u6uIxqMtRRQMYWooopAf//Z physicalDeliveryOfficeName: Mumbai +kopanoUserServer: kopano_server_2 # user3, users, {{ LDAP_DOMAIN }} dn: uid=user3,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -3200,6 +3252,7 @@ jpegphoto:: /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQO AhsLYNX4X6UUUMdy7E1WYztPFFFQWaUJ3JVa6jxRRTJbKY4apGPy0UUhGdO/wA1RbxRRQO5LE/z CuktZBHCCT2oooQ2Mk1BQ3B/WiiigR//2Q== physicalDeliveryOfficeName: Delft +kopanoUserServer: kopano_server # user1, users, {{ LDAP_DOMAIN }} dn: uid=user1,ou=users,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -4008,6 +4061,7 @@ jpegphoto:: /9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAYEBQYFBAYGBQYHBwYIChAKCgkJChQO physicalDeliveryOfficeName: Kopenhagen kopanoQuotaOverride: 1 kopanoQuotaHard: 1200000000 +kopanoUserServer: kopano_server_2 # distributionlist, groups, {{ LDAP_DOMAIN }} dn: cn=distributionlist,ou=groups,ou=CompanyA,{{ LDAP_BASE_DN }} @@ -4159,6 +4213,7 @@ postalCode: 13145 secretary: uid=user21,ou=users,ou=CompanyB,{{ LDAP_BASE_DN }} kopanoAdmin: 0 cn: Niko Liebelt & Co +kopanoUserServer: kopano_server # user21, users, {{ LDAP_DOMAIN }} dn: uid=user21,ou=users,ou=CompanyB,{{ LDAP_BASE_DN }} @@ -4185,6 +4240,7 @@ labeledURI: http://rice-schmidt.com/ title: Engineer, water l: East Colonel postalCode: WN7R 3AB +kopanoUserServer: kopano_server_2 # user22, users, {{ LDAP_DOMAIN }} dn: uid=user22,ou=users,ou=CompanyB,{{ LDAP_BASE_DN }} @@ -4212,6 +4268,7 @@ l: Neuss postalCode: 56933 secretary: uid=user23,ou=users,ou=CompanyB,{{ LDAP_BASE_DN }} userPassword:: e0NSWVBUfXNUNDd4VE5IUTh5U2c= +kopanoUserServer: kopano_server # user23, users, {{ LDAP_DOMAIN }} dn: uid=user23,ou=users,ou=CompanyB,{{ LDAP_BASE_DN }} @@ -4241,6 +4298,7 @@ l: Opeinde postalCode: 5557CV secretary: uid=user1,ou=users,ou=CompanyB,{{ LDAP_BASE_DN }} kopanoSendAsPrivilege: 22 +kopanoUserServer: kopano_server_2 # group1, groups, {{ LDAP_DOMAIN }} dn: cn=group1,ou=groups,ou=CompanyB,{{ LDAP_BASE_DN }} @@ -4276,4 +4334,5 @@ objectClass: inetOrgPerson userPassword:: bWVldGluZ3Jvb20z sn: meetingroom3 uidNumber: 20055 -uid: meetingroom3 \ No newline at end of file +uid: meetingroom3 +kopanoUserServer: kopano_server diff --git a/ssl/Dockerfile b/ssl/Dockerfile index 65da80a..7b6e64f 100644 --- a/ssl/Dockerfile +++ b/ssl/Dockerfile @@ -2,7 +2,7 @@ FROM alpine:3.9 ARG VCS_REF -ENV CODE_VERSION=1.1.0 \ +ENV CODE_VERSION=1.2.0 \ PKI_ROOT=/kopano/easypki \ PKI_ORGANIZATION="Internal Kopano System" \ PKI_COUNTRY=DE diff --git a/ssl/start.sh b/ssl/start.sh index 8c0891e..ecc6207 100755 --- a/ssl/start.sh +++ b/ssl/start.sh @@ -21,7 +21,7 @@ if [ ! -f /kopano/ssl/ca.pem ]; then cp /kopano/easypki/internalca/certs/internalca.crt /kopano/ssl/ca.pem.tmp mv /kopano/ssl/ca.pem.tmp /kopano/ssl/ca.pem - for s in kopano_server kopano_dagent kopano_monitor kopano_search kopano_spooler kopano_webapp; do + for s in kopano_server kopano_server_2 kopano_dagent kopano_monitor kopano_search kopano_spooler kopano_webapp admin; do if [ ! -f /kopano/ssl/$s.pem ]; then echo "Creating $s certificate..." easypki create --ca-name internalca --organizational-unit $s --expire 3650 --dns $s --dns "$FQDN" $s