Installation Guide
www.tine-groupware.de | docker-compose.yml | Dockerfile
Schnellstart
Dies ist eine schnelle und leichte Möglichkeit, tine auszuprobieren. Hierfür benötigen Sie Docker und Docker Compose (https://docs.docker.com/compose/).
Erstellen Sie im ersten Schritt einen Ordner. Docker Compose verwendet die Ordnernamen zur Identifizierung.
mkdir tine
cd tine
wget https://tine-docu.s3web.rz1.metaways.net/de/operators/docker/docker-compose.yml
Jetzt können Sie Docker-Compose starten.
Anmerkung
Je nach Docker-Installation erfolgt der Docker Compose Aufruf so: docker compose
oder so docker-compose
.
docker compose up
Warten Sie einen Moment, bis die Datenbank erreichbar ist. Im Webcontainer Log steht dann web_1 | DB available
. Dann können Sie Tine installieren. Öffnen Sie dafür ein neues Terminal und führen Sie den Installer aus. Im Installer müssen Sie die Tine-Lizenz und Datenschutzerklärung bestätigen und können das Password für den initialen Admin festlegen.
docker compose exec web tine20_install
tine ist jetzt unter http://127.0.0.1:4000 erreichbar.
setup.php UI
Die tine-Setup-UI ist dann unter http://127.0.0.1:4000/setup.php erreichbar. Bitte dran denken, dass diese im Container
mit HTTP Basic Auth geschützt ist. Benutzername und Passworthash sollten über die ENV Variable TINE20_SETUP_HTPASSWD gesetzt werden (Beispiel: "setup:$apr1$JhCtViTh$k15DH.HvNR5hZ66Ew5aTH/" #setup:setuppw).
Der hash kann mit htpasswd generiert werden:
1. htpasswd -c setup.htpasswd setup
.
2. Pasword eingeben wiederholen
3. Benutzername und Passworthash aus der Datei setup.htpasswd
kopieren.
Hinweis: Bei der Verwendung von docker-compose muss $
wie folgt escaped werden: $$
.
Aufräumen
Um alle von Docker Compose erstellten Container, Netzwerke und Volumes zu stoppen und löschen nutzen Sie:
docker compose down --volumes
Image
Dieses Image enthält den tine-Code, PHP-FPM und Nginx. Zusätzlich benötigen Sie eine Datenbank, beispielsweise MariaDB. In der Produktion sollte dieses Image mit einem Reverse-Proxy verwendet werden, der die gesamte benutzerdefinierte Konfiguration und SSL-Terminierung übernimmt.
Paths
Path | Definition |
---|---|
/etc/tine20/config.inc.php |
tine Hauptkonfigurationsdatei. |
/etc/tine20/conf.d/* |
tine Konfigurationsdateien werden automatisch eingeschlossen. |
/var/lib/tine20/files |
Speichern der User-Daten. Dateien wie die im tine-Dateimanager |
/var/lib/tine20/tmp |
Temporäre Dateispeicherung |
/var/lib/tine20/caching |
Wird zum Zwischenspeichern verwendet, wenn TINE20_CACHING_BACKEND == 'File' |
/var/lib/tine20/sessions |
Wird als Sitzungsspeicher verwendet, wenn TINE20_SESSION_BACKEND == 'File' |
Update
Zum Updaten einmal 'docker compose down && docker composer up' machen. Falls man eine andere Major-Version haben möchte, kann vorher in der docker-compose.yml auch eine konkrete Version angegeben werden.
Zum Updaten von tine selbst verwendet man folgenden Befehl (ggf. muss der Name des Containers angepasst werden, herausfinden kann man ihn z.B. mit 'docker ps'):
docker exec --user tine20 tine-docker_web_1 sh -c "php /usr/share/tine20/setup.php --config=/etc/tine20 --update"
Falls dieser Fehler erscheint:
"Tinebase_Exception -> waited for Action Queue to become empty for more than 300 sec"
Sollte geprüft werden, ob noch Jobs in der Queue sind und/oder man startet das Update mit dem Schalter skipQueueCheck=1
.
SSL / Reverse Proxy
Um den tine-Container "von aussen" verfügbar zu machen, kann man einen NGINX, Traefik oder HAProxy davorschalten.
NGINX
Beispiel einer NGINX VHOST conf:
server {
listen 80;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/MYDOMAIN.de/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/MYDOMAIN.de/privkey.pem;
server_name tine.MYDOMAIN.de autodiscover.MYDOMAIN.de;
if ($ssl_protocol = "" ) {
rewrite ^ https://$server_name$request_uri? permanent;
}
access_log /var/www/MYDOMAIN/logs/nginx-access.log;
error_log /var/www/MYDOMAIN/logs/nginx-error.log;
client_max_body_size 2G; # set maximum upload size
location /.well-known { }
location / {
proxy_pass http://127.0.0.1:4000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
TRAEFIK
Alternativ zu NGINX kann man auch traefik zur docker-composer.yml hinzufügen:
traefik:
image: "traefik:v2.6"
restart: always
container_name: "traefik"
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.http01.acme.httpchallenge=true"
- "--certificatesresolvers.http01.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.http01.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- "./letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
web:
image: tinegroupware/tine:2021.11
#[...]
labels:
- "traefik.enable=true"
- "traefik.http.routers.tile-server.rule=Host(`MYDOMAIN.de`)"
- "traefik.http.routers.tile-server.entrypoints=websecure"
- "traefik.http.routers.tile-server.tls.certresolver=http01"
- "traefik.http.services.tile-server.loadbalancer.server.port=80"
Migration
Um von einer alten Installation mit lokaler tine auf das Docker-Setup zu migrieren, müssen nur die Volumes entsprechend gemountet werden (das root-Passwort der Datenbank sollte bekannt sein und die DB sollte die gleiche Version haben):
db:
image: mariadb:10.6
volumes:
- "/var/lib/mysql:/var/lib/mysql"
#[...]
web:
image: tinegroupware/tine:2021.11
volumes:
- "/var/lib/tine20/files:/var/lib/tine20/files"
#[...]
Bitte achtet auf die korrekte Angabe des TINE20_DATABASE_TABLEPREFIX -> sonst werden ggf. die Tabellen nicht gefunden.
Falls das nicht klappt oder die alte tine DB auf einem anderen Server liegt, sollte man die tine CLI Funktionen --backup
und --restore
benutzen.
Dabei muss beachtet werden, dass auf die Backup-Dateien von innerhalb des tine-Containers aus zugriffen werden kann.
Custom-Konfiguration
Wenn man möchte, kann man Custom-Configs (via conf.d) ebenfalls als eigenes Volume in den Container mounten:
web:
image: tinegroupware/tine:2021.11
volumes:
- "conf.d:/etc/tine20/conf.d"
#[...]
docker-compose.yml
version: '2'
services:
db:
image: mariadb:10.9.8
command: --max-allowed-packet=209715210
restart: always
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: &MYSQL_DATABASE tine
MYSQL_USER: &MYSQL_USER tine
MYSQL_PASSWORD: &MYSQL_PASSWORD tine
MARIADB_AUTO_UPGRADE: 1
### use volume for persistent DB
volumes:
- "tine_db:/var/lib/mysql"
### OR
# - "./data/tine_mysql:/var/lib/mysql"
networks:
- internal_network
web:
image: tinegroupware/tine:2023
restart: always
depends_on:
- db
- cache
environment:
TINE20_DATABASE_HOST: db
TINE20_DATABASE_DBNAME: *MYSQL_DATABASE
TINE20_DATABASE_USERNAME: *MYSQL_USER
TINE20_DATABASE_PASSWORD: *MYSQL_PASSWORD
TINE20_DATABASE_TABLEPREFIX: tine_
TINE20_CACHING_BACKEND: Redis
TINE20_CACHING_REDIS_HOST: cache
TINE20_ACTIONQUEUE_HOST: cache
TINE20_SESSION_BACKEND: Redis
TINE20_SESSION_HOST: cache
TINE20_CREDENTIALCACHESHAREDKEY: change_me
TINE20_SETUPUSER_USERNAME: tinesetup
TINE20_SETUPUSER_PASSWORD: tinesetup
TINE20_SETUP_HTPASSWD: "setup:$$apr1$$JhCtViTh$$k15DH.HvNR5hZ66Ew5aTH/" #setup:setuppw
TINE20_ACTIONQUEUE: "true"
BROADCASTHUB_URL: http://broadcasthub
# TINE20_LOGGER_PRIORITY: "7"
### the url of you tine installation (should be adjusted)
# TINE20_URL: http://localhost:4000
### install+update tine automatically
# TINE20_INSTALL: "true"
### needed for auto-install
# TINE20_ACCEPTED_TERMS_VERSION: 10000
# TINE20_LOGIN_USERNAME: admin
# TINE20_LOGIN_PASSWORD: change_me
### apps to install - if omitted, all available apps are installed
# TINE20_APPLICATION_TO_INSTALL: "Addressbook,Felamimail,Calendar,Filemanager"
volumes:
- "tine_files:/var/lib/tine20/files"
# use this for custom configuration files (like logger.inc.php)
- "./conf.d:/etc/tine20/conf.d"
### OR
# NOTE: you need to make sure that the folder has the correct file permissions
# - "./data/tine_files:/var/lib/tine20/files"
networks:
- external_network
- internal_network
ports:
- "127.0.0.1:4000:80"
### for traefik support (see https://doc.traefik.io/traefik/providers/docker/)
# labels:
# - "traefik.enable=true"
# - "traefik.http.routers.web.rule=Host(`MYDOMAIN.de`)"
# - "traefik.http.routers.web.entrypoints=websecure"
# - "traefik.http.routers.web.tls.certresolver=http01"
# - "traefik.http.services.web.loadbalancer.server.port=80"
cache:
image: redis:6.0.16
restart: always
networks:
- internal_network
broadcasthub:
image: tinegroupware/broadcasthub:0.7
restart: always
networks:
- external_network
- internal_network
ports:
- "5001:80"
environment:
REDIS_URL: redis://cache:6379
REDIS_CHANNEL: broadcasthub
TINE20_JSON_API_URL: http://localhost
AUTH_TIMEOUT: 5000
WS_PORT: 80
DEBUG: '*'
DEBUG_DEFAULT_LOGGING: "on"
DEBUG_LOG_TO_FILE: "off"
DEBUG_LOG_FILE: ../../stdout.log
### other optional services
############################################################################
# docservice
############
# to use this in tine, you need to add the following to your config:
#
# 'filesystem' => [
# 'createPreviews' => true,
# 'previewServiceUrl' => 'http://docservice/v2/documentPreviewService',
# 'previewServiceVersion' => 2,
# [...]
# ],
############################################################################
# docservice:
# image: tinegroupware/document-preview-service:2.1
# restart: always
# networks:
# - internal_network
############################################################################
# documentserver
############################################################################
#
# to use this in tine, you need to add the following to your config:
#
# return [
# 'OnlyOfficeIntegrator' => [
# 'onlyOfficePublicUrl' => 'http://localhost:4020/',
# 'onlyOfficeServerUrl' => 'http://documentserver/',
# 'tine20ServerUrl' => 'http://web/',
# 'jwtEnabled' => true,
# 'jwtSecret' => 'change_me_also_define_in_tine_cfg',
# ],
#
############################################################################
# documentserver:
# image: onlyoffice/documentserver:latest
# restart: always
# ports:
# - "4020:80"
# environment:
# JWT_ENABLED: "true"
# JWT_SECRET: "change_me_also_define_in_tine_cfg"
# networks:
# - external_network
# - internal_network
# clamav:
# image: tiredofit/clamav
# restart: always
# container_name: clamav
# environment:
# - ZABBIX_HOSTNAME=clamav
# # need to be created on the host
# volumes:
# - "clamav_files:/data"
# networks:
# - internal_network
# traefik:
# image: "traefik:v2.6"
# restart: always
# container_name: "traefik"
# command:
# - "--providers.docker=true"
# - "--providers.docker.exposedbydefault=false"
# - "--entrypoints.web.address=:80"
# - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
# - "--entrypoints.web.http.redirections.entryPoint.scheme=https"
# - "--entrypoints.web.http.redirections.entrypoint.permanent=true"
# - "--entrypoints.websecure.address=:443"
# - "--certificatesresolvers.http01.acme.httpchallenge=true"
# - "--certificatesresolvers.http01.acme.httpchallenge.entrypoint=web"
# - "--certificatesresolvers.http01.acme.storage=/letsencrypt/acme.json"
# ports:
# - "80:80"
# - "443:443"
# - "8080:8080"
# volumes:
# - "./letsencrypt:/letsencrypt"
# - "/var/run/docker.sock:/var/run/docker.sock:ro"
### if you use directory mounts, you might no need that
volumes:
tine_files:
tine_db:
# clamav_files:
networks:
external_network:
internal_network:
internal: true
Ansible Rolle für Deployments
https://github.com/tine-groupware/tine/tree/main/scripts/ansible/roles/tinedockercompose