diff --git a/bin/configure.sh b/bin/configure.sh index c5ecadf4..a466bee6 100755 --- a/bin/configure.sh +++ b/bin/configure.sh @@ -1,106 +1,111 @@ #!/bin/bash # Uninstall the old config if [ -d config ]; then echo "Uninstalling the old config." find -L config/ -type f | while read file; do file=$(echo $file | sed -e 's|^config||g') file="./$file" rm -v $file done fi if [ "$1" == "" ]; then echo "Failed to find the configuration folder, please pass one as argument (e.g. config.demo)." exit 1 fi if [ ! -d $1 ]; then echo "Failed to find the configuration folder, please pass one as argument (e.g. config.demo)." exit 1 fi echo "Installing $1." # Link new config rm config ln -s $1 config # Install new config find -L config/ -type f | while read file; do dir=$(dirname $file | sed -e 's|^config||g') dir="./$dir" if [ ! -d $dir ]; then mkdir -p $dir fi cp -v $file $dir/ done if [ -f config.secrets ]; then # Add local secrets echo "" >> src/.env cat config.secrets >> src/.env fi # Generate random secrets if ! grep -q "COTURN_STATIC_SECRET" .env; then COTURN_STATIC_SECRET=$(openssl rand -hex 32); echo "COTURN_STATIC_SECRET=${COTURN_STATIC_SECRET}" >> src/.env fi if ! grep -q "MEET_WEBHOOK_TOKEN" .env; then MEET_WEBHOOK_TOKEN=$(openssl rand -hex 32); echo "MEET_WEBHOOK_TOKEN=${MEET_WEBHOOK_TOKEN}" >> src/.env fi if ! grep -q "MEET_SERVER_TOKEN" .env; then MEET_SERVER_TOKEN=$(openssl rand -hex 32); echo "MEET_SERVER_TOKEN=${MEET_SERVER_TOKEN}" >> src/.env fi if ! grep -q "APP_KEY=base64:" .env; then APP_KEY=$(openssl rand -base64 32); echo "APP_KEY=base64:${APP_KEY}" >> src/.env fi if ! grep -q "PASSPORT_PROXY_OAUTH_CLIENT_ID=" .env; then PASSPORT_PROXY_OAUTH_CLIENT_ID=$(uuidgen); echo "PASSPORT_PROXY_OAUTH_CLIENT_ID=${PASSPORT_PROXY_OAUTH_CLIENT_ID}" >> src/.env fi if ! grep -q "PASSPORT_PROXY_OAUTH_CLIENT_SECRET=" .env; then PASSPORT_PROXY_OAUTH_CLIENT_SECRET=$(openssl rand -base64 32); echo "PASSPORT_PROXY_OAUTH_CLIENT_SECRET=${PASSPORT_PROXY_OAUTH_CLIENT_SECRET}" >> src/.env fi if ! grep -q "PASSPORT_PUBLIC_KEY=|PASSPORT_PRIVATE_KEY=" .env; then PASSPORT_PRIVATE_KEY=$(openssl genrsa 4096); echo "PASSPORT_PRIVATE_KEY=\"${PASSPORT_PRIVATE_KEY}\"" >> src/.env PASSPORT_PUBLIC_KEY=$(echo "$PASSPORT_PRIVATE_KEY" | openssl rsa -pubout 2>/dev/null) echo "PASSPORT_PUBLIC_KEY=\"${PASSPORT_PUBLIC_KEY}\"" >> src/.env fi +if ! grep -q "DES_KEY=" .env; then + DES_KEY=$(openssl rand -base64 24); + echo "DES_KEY=${DES_KEY}" >> src/.env +fi + bin/update-git-refs.sh # Customize configuration sed -i \ -e "s/{{ host }}/${HOST:-kolab.local}/g" \ -e "s/{{ openexchangerates_api_key }}/${OPENEXCHANGERATES_API_KEY}/g" \ -e "s/{{ firebase_api_key }}/${FIREBASE_API_KEY}/g" \ -e "s/{{ public_ip }}/${PUBLIC_IP:-172.18.0.1}/g" \ -e "s/{{ admin_password }}/${ADMIN_PASSWORD}/g" \ src/.env if [ -f /etc/letsencrypt/live/${HOST}/cert.pem ]; then echo "Using the available letsencrypt certificate for ${HOST}" cat >> .env << EOF KOLAB_SSL_CERTIFICATE=/etc/letsencrypt/live/${HOST}/cert.pem KOLAB_SSL_CERTIFICATE_FULLCHAIN=/etc/letsencrypt/live/${HOST}/fullchain.pem KOLAB_SSL_CERTIFICATE_KEY=/etc/letsencrypt/live/${HOST}/privkey.pem PROXY_SSL_CERTIFICATE=/etc/letsencrypt/live/${HOST}/fullchain.pem PROXY_SSL_CERTIFICATE_KEY=/etc/letsencrypt/live/${HOST}/privkey.pem EOF fi diff --git a/docker-compose.yml b/docker-compose.yml index aa4b5887..8e8beffc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,246 +1,247 @@ version: '3' services: coturn: build: context: ./docker/coturn/ container_name: kolab-coturn healthcheck: interval: 10s test: "kill -0 $$(cat /tmp/turnserver.pid)" timeout: 5s retries: 30 environment: - TURN_PUBLIC_IP=${COTURN_PUBLIC_IP} - TURN_LISTEN_PORT=3478 - TURN_STATIC_SECRET=${COTURN_STATIC_SECRET} hostname: sturn.mgmt.com image: kolab-coturn network_mode: host restart: on-failure roundcube: build: context: ./docker/roundcube/ args: GIT_REF_ROUNDCUBEMAIL: ${GIT_REF_ROUNDCUBEMAIL} GIT_REMOTE_ROUNDCUBEMAIL: ${GIT_REMOTE_ROUNDCUBEMAIL} GIT_REF_ROUNDCUBEMAIL_PLUGINS: ${GIT_REF_ROUNDCUBEMAIL_PLUGINS} GIT_REMOTE_ROUNDCUBEMAIL_PLUGINS: ${GIT_REMOTE_ROUNDCUBEMAIL_PLUGINS} GIT_REF_CHWALA: ${GIT_REF_CHWALA} GIT_REMOTE_CHWALA: ${GIT_REMOTE_CHWALA} GIT_REF_SYNCROTON: ${GIT_REF_SYNCROTON} GIT_REMOTE_SYNCROTON: ${GIT_REMOTE_SYNCROTON} GIT_REF_AUTOCONF: ${GIT_REF_AUTOCONF} GIT_REMOTE_AUTOCONF: ${GIT_REMOTE_AUTOCONF} GIT_REF_IRONY: ${GIT_REF_IRONY} GIT_REMOTE_IRONY: ${GIT_REMOTE_IRONY} GIT_REF_FREEBUSY: ${GIT_REF_FREEBUSY} GIT_REMOTE_FREEBUSY: ${GIT_REMOTE_FREEBUSY} container_name: kolab-roundcube hostname: roundcube.hosted.com restart: on-failure depends_on: mariadb: condition: service_healthy pdns: condition: service_healthy environment: - APP_DOMAIN=${APP_DOMAIN} + - DES_KEY=${DES_KEY} - DB_HOST=mariadb - DB_ROOT_PASSWORD=${DB_ROOT_PASSWORD} - DB_RC_DATABASE=roundcube - DB_RC_USERNAME=roundcube - DB_RC_PASSWORD=${DB_PASSWORD:?"DB_PASSWORD is missing"} - IMAP_HOST=imap - IMAP_PORT=11143 - IMAP_ADMIN_LOGIN=${IMAP_ADMIN_LOGIN} - IMAP_ADMIN_PASSWORD=${IMAP_ADMIN_PASSWORD} - MAIL_HOST=postfix - MAIL_PORT=10587 healthcheck: interval: 10s test: "kill -0 $$(cat /run/httpd/httpd.pid)" timeout: 5s retries: 30 # This makes docker's dns, resolve via pdns for this container. # Please note it does not affect /etc/resolv.conf dns: 172.18.0.11 image: roundcube extra_hosts: - "${APP_DOMAIN}:172.18.0.7" networks: kolab: ipv4_address: 172.18.0.9 ports: - "8080:8080" tmpfs: - /tmp - /var/tmp volumes: - ./ext/:/src.orig/:ro - roundcube:/data mariadb: build: context: ./docker/mariadb/ container_name: kolab-mariadb restart: on-failure environment: - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD} - TZ="+02:00" - DB_HKCCP_DATABASE=${DB_DATABASE} - DB_HKCCP_USERNAME=${DB_USERNAME} - DB_HKCCP_PASSWORD=${DB_PASSWORD} - DB_KOLAB_DATABASE=kolab - DB_KOLAB_USERNAME=kolab - DB_KOLAB_PASSWORD=${DB_PASSWORD:?"DB_PASSWORD is missing"} - DB_RC_DATABASE=roundcube - DB_RC_USERNAME=roundcube - DB_RC_PASSWORD=${DB_PASSWORD:?"DB_PASSWORD is missing"} healthcheck: interval: 10s test: "mysqladmin -u root ping && test -e /tmp/initialized" timeout: 5s retries: 30 image: mariadb networks: kolab: ipv4_address: 172.18.0.3 volumes: - mariadb:/var/lib/mysql pdns: build: context: ./docker/pdns/ container_name: kolab-pdns restart: on-failure tty: true hostname: pdns depends_on: mariadb: condition: service_healthy healthcheck: interval: 10s test: "pdns_control rping || exit 1" timeout: 5s retries: 30 image: kolab-pdns environment: - ROLE=both - DB_HOST=mariadb - DB_DATABASE=${DB_DATABASE:?DB_DATABASE} - DB_USERNAME=${DB_USERNAME:?DB_USERNAME} - DB_PASSWORD=${DB_PASSWORD:?DB_PASSWORD} networks: kolab: ipv4_address: 172.18.0.11 tmpfs: - /run - /tmp - /var/run - /var/tmp volumes: - /sys/fs/cgroup:/sys/fs/cgroup:ro redis: build: context: ./docker/redis/ healthcheck: interval: 10s test: "redis-cli ping || exit 1" timeout: 5s retries: 30 container_name: kolab-redis restart: on-failure hostname: redis image: redis networks: - kolab volumes: - ./docker/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro webapp: build: context: ./docker/webapp/ args: GIT_REF: ${KOLAB_GIT_REF} GIT_REMOTE: ${KOLAB_GIT_REMOTE} container_name: kolab-webapp restart: on-failure image: kolab-webapp healthcheck: interval: 10s test: "./artisan octane:status || exit 1" timeout: 5s retries: 30 start_period: 5m depends_on: redis: condition: service_healthy networks: kolab: ipv4_address: 172.18.0.4 volumes: - ./src:/src/kolabsrc.orig:ro ports: - "8000:8000" meet: build: context: ./docker/meet/ args: GIT_REF: ${KOLAB_GIT_REF} GIT_REMOTE: ${KOLAB_GIT_REMOTE} container_name: kolab-meet restart: on-failure healthcheck: interval: 10s test: "curl --insecure -H 'X-AUTH-TOKEN: ${MEET_SERVER_TOKEN}' --fail https://${MEET_LISTENING_HOST}:12443/meetmedia/api/health || exit 1" timeout: 5s retries: 30 start_period: 5m environment: - WEBRTC_LISTEN_IP=${MEET_WEBRTC_LISTEN_IP:?err} - PUBLIC_DOMAIN=${MEET_PUBLIC_DOMAIN:?err} - LISTENING_HOST=${MEET_LISTENING_HOST:?err} - LISTENING_PORT=12443 - TURN_SERVER=${MEET_TURN_SERVER} - TURN_STATIC_SECRET=${COTURN_STATIC_SECRET} - AUTH_TOKEN=${MEET_SERVER_TOKEN:?err} - WEBHOOK_TOKEN=${MEET_WEBHOOK_TOKEN:?err} - WEBHOOK_URL=${APP_PUBLIC_URL:?err}/api/webhooks/meet - SSL_CERT=/etc/pki/tls/certs/meet.${APP_WEBSITE_DOMAIN:?err}.cert - SSL_KEY=/etc/pki/tls/private/meet.${APP_WEBSITE_DOMAIN:?err}.key network_mode: host image: kolab-meet volumes: - ./meet/server:/src/meet/:ro - ./docker/certs/meet.${APP_WEBSITE_DOMAIN}.cert:/etc/pki/tls/certs/meet.${APP_WEBSITE_DOMAIN}.cert - ./docker/certs/meet.${APP_WEBSITE_DOMAIN}.key:/etc/pki/tls/private/meet.${APP_WEBSITE_DOMAIN}.key minio: container_name: kolab-minio restart: on-failure healthcheck: interval: 10s test: "mc ready local || exit 1" timeout: 5s retries: 30 start_period: 5m environment: - MINIO_ROOT_USER=${MINIO_USER} - MINIO_ROOT_PASSWORD=${MINIO_PASSWORD} image: minio/minio networks: kolab: ipv4_address: 172.18.0.14 ports: - "9000:9000" - "9001:9001" entrypoint: sh command: -c 'mkdir -p /data/${MINIO_BUCKET} && minio server /data --console-address ":9001"' volumes: - minio:/data networks: kolab: driver: bridge ipam: config: - subnet: "172.18.0.0/24" volumes: mariadb: minio: roundcube: diff --git a/docker/roundcube/rootfs/opt/app-root/src/roundcubemail-config-templates/config.inc.php b/docker/roundcube/rootfs/opt/app-root/src/roundcubemail-config-templates/config.inc.php index 8b2d46ee..855aff50 100644 --- a/docker/roundcube/rootfs/opt/app-root/src/roundcubemail-config-templates/config.inc.php +++ b/docker/roundcube/rootfs/opt/app-root/src/roundcubemail-config-templates/config.inc.php @@ -1,200 +1,204 @@ 2) { + array_shift($components); + } + $config['session_domain'] = implode('.', $components); + + $config['des_key'] = getenv('DES_KEY'); $config['username_domain'] = getenv('APP_DOMAIN'); $config['use_secure_urls'] = true; $config['mail_domain'] = ''; // IMAP Server Settings $config['default_host'] = getenv('IMAP_HOST'); $config['default_port'] = getenv('IMAP_PORT'); $config['imap_delimiter'] = '/'; $config['imap_force_lsub'] = true; // if (str_contains(getenv('IMAP_URI'), 'tls') || str_contains(getenv('IMAP_URI'), 'ssl')) { // $config['imap_conn_options'] = [ // 'ssl' => [ // 'verify_peer_name' => false, // 'verify_peer' => false, // 'allow_self_signed' => true // ], // 'proxy_protocol' => getenv('IMAP_PROXY_PROTOCOL') // ]; // } $config['proxy_whitelist'] = getenvlist('PROXY_WHITELIST'); // Caching and storage settings $config['imap_cache'] = 'db'; $config['imap_cache_ttl'] = '10d'; $config['messages_cache'] = 'db'; $config['message_cache_ttl'] = '10d'; $config['session_storage'] = 'db'; // SMTP Server Settings $config['smtp_server'] = getenv('MAIL_HOST'); $config['smtp_port'] = getenv('MAIL_PORT'); $config['smtp_user'] = '%u'; $config['smtp_pass'] = '%p'; $config['smtp_helo_host'] = $_SERVER["HTTP_HOST"] ?? null; // $config['smtp_conn_options'] = Array( // 'ssl' => Array( // 'verify_peer_name' => false, // 'verify_peer' => false, // 'allow_self_signed' => true // ) // ); // Kolab specific defaults $config['product_name'] = 'Kolab Groupware'; $config['quota_zero_as_unlimited'] = false; $config['login_lc'] = 2; $config['auto_create_user'] = true; $config['enable_installer'] = false; // The SMTP server does not allow empty identities $config['mdn_use_from'] = true; // Plugins $config['plugins'] = array( // 'kolab_auth', 'acl', 'archive', 'calendar', 'jqueryui', 'kolab_activesync', 'kolab_addressbook', // 'kolab_config', // 'kolab_delegation', 'kolab_files', // 'kolab_folders', // 'kolab_notes', // 'kolab_tags', 'managesieve', 'newmail_notifier', 'odfviewer', 'redundant_attachments', 'tasklist', // contextmenu must be after kolab_addressbook (#444) 'contextmenu', 'enigma', ); // Do not show deleted messages, mark deleted messages as read, // and flag them as deleted instead of moving them to the Trash // folder. $config['skip_deleted'] = true; $config['read_when_deleted'] = true; $config['flag_for_deletion'] = true; $config['delete_always'] = true; $config['session_lifetime'] = 180; $config['password_charset'] = 'UTF-8'; $config['useragent'] = 'Kolab 16/Roundcube ' . RCUBE_VERSION; $config['message_sort_col'] = 'date'; $config['spellcheck_engine'] = 'pspell'; $config['spellcheck_dictionary'] = true; $config['spellcheck_ignore_caps'] = true; $config['spellcheck_ignore_nums'] = true; $config['spellcheck_ignore_syms'] = true; $config['spellcheck_languages'] = array( 'da' => 'Dansk', 'de' => 'Deutsch', 'en' => 'English', 'es' => 'Español', 'fr' => 'Français', 'it' => 'Italiano', 'nl' => 'Nederlands', 'pt' => 'Português', 'ru' => 'Русский', 'sv' => 'Svenska' ); $config['undo_timeout'] = 10; $config['upload_progress'] = 2; $config['address_template'] = '{street}
{locality} {zipcode}
{country} {region}'; $config['preview_pane'] = true; $config['preview_pane_mark_read'] = 0; $config['autoexpand_threads'] = 2; $config['top_posting'] = 0; $config['sig_above'] = false; $config['mdn_requests'] = 0; $config['mdn_default'] = false; $config['dsn_default'] = false; $config['reply_same_folder'] = false; if (file_exists(RCUBE_CONFIG_DIR . '/' . ($_SERVER["HTTP_HOST"] ?? null) . '/' . basename(__FILE__))) { include_once(RCUBE_CONFIG_DIR . '/' . ($_SERVER["HTTP_HOST"] ?? null) . '/' . basename(__FILE__)); } // Re-apply mandatory settings here. $config['debug_level'] = 1; $config['devel_mode'] = false; $config['log_driver'] = 'logfmt'; $config['per_user_logging'] = true; $config['log_date_format'] = 'd-M-Y H:i:s,u O'; $config['smtp_log'] = false; $config['log_logins'] = true; $config['log_session'] = false; $config['sql_debug'] = getenv('SQL_DEBUG'); $config['memcache_debug'] = getenv('MEMCACHE_DEBUG'); $config['imap_debug'] = getenv('IMAP_DEBUG'); $config['smtp_debug'] = getenv('SMTP_DEBUG'); $config['dav_debug'] = getenv('DAV_DEBUG'); $config['skin'] = 'kolab'; $config['skin_include_php'] = false; $config['mime_magic'] = null; $config['im_identify_path'] = '/usr/bin/identify'; $config['im_convert_path'] = '/usr/bin/convert'; $config['log_dir'] = 'logs/'; #$config['temp_dir'] = '/var/lib/roundcubemail/'; // Some additional default folders (archive plugin) $config['archive_mbox'] = 'Archive'; // The Kolab daemon by default creates 'Spam' $config['junk_mbox'] = 'Spam'; $config['default_folders'] = array('INBOX', 'Drafts', 'Sent', 'Spam', 'Trash', 'Archive'); // $config['address_book_type'] = 'ldap'; $config['autocomplete_min_length'] = 3; $config['autocomplete_threads'] = 0; $config['autocomplete_max'] = 15; // Disable the default addressbook and use the dav addressbook by default $config['address_book_type'] = ''; $config['autocomplete_single'] = true; $config['htmleditor'] = 0; $config['kolab_http_request'] = Array( 'ssl_verify_host' => false, 'ssl_verify_peer' => false, ); @include('kolab_syncroton.inc.php'); @include('chwala.inc.php'); ?>