Compare commits
	
		
			107 Commits
		
	
	
		
			auto_app_i
			...
			kc_stable
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e46a9411ef | |||
| b9a7b9730e | |||
| 00264a9c44 | |||
| d7d33b099f | |||
| 01fe498831 | |||
| 9859907d4b | |||
| 6c0fa9c12d | |||
| a3c99a72bf | |||
| c94ffed09d | |||
| 7a863573c9 | |||
| c930bbcf56 | |||
| a13e7a509c | |||
| 0f9aba3e9e | |||
| eb3e2486ce | |||
| 2b4e63ef31 | |||
| c056687849 | |||
| 180c269337 | |||
| 7eea2e0785 | |||
| be915272b4 | |||
| 9be859db25 | |||
| 97e1d72604 | |||
| 8a1fae2bac | |||
| ce817e3928 | |||
| 7a64d3c6a7 | |||
| bb781e654b | |||
| cb5cd5f7b2 | |||
| 0a3e943b26 | |||
| 4f1aaf5d1d | |||
| 019b71fde1 | |||
| 7527399da0 | |||
| 94e84122ed | |||
| 0d9ab936a0 | |||
| 09ec6f842c | |||
| b5d40aa428 | |||
| eead80b60a | |||
| 24670cdb6b | |||
| 7e4ab9288c | |||
| 199bf61300 | |||
| 99514b5991 | |||
| eefb14e150 | |||
| a34e100bd7 | |||
| 24ca6b22bc | |||
| c4ea5e053e | |||
| 9d2e5cc05b | |||
| 72bb75a49f | |||
| 5014bcb276 | |||
| 88fc62bcd0 | |||
| c54b975654 | |||
| e9a602cc78 | |||
| 90c7b87655 | |||
| 3a8c203b51 | |||
| 634a3553b9 | |||
| 24e9571ba1 | |||
| 6546a05cf9 | |||
| ad3059d518 | |||
| 92af4b9c01 | |||
| 92dca3fab7 | |||
| 201585bea8 | |||
| a0e8fdad40 | |||
| 6427ce181f | |||
| 37f575038b | |||
| 7e4c87346a | |||
| 944230afe0 | |||
| 63a1787ad6 | |||
| 1deee41205 | |||
| b8d209e531 | |||
| f48d314699 | |||
| a6ea635fd4 | |||
| c9b8aec108 | |||
| db39e8dee6 | |||
| ed68b3e57c | |||
| 78ea500d5e | |||
| 6f219781e5 | |||
| 162c056f07 | |||
| 5d537d5173 | |||
| 7a25bd4835 | |||
| eac7431b13 | |||
| fce0b9f7cb | |||
| 7b0a0741b6 | |||
| e1bc039b09 | |||
| a52515e63e | |||
| cff544c554 | |||
| f086d1bc77 | |||
| 897d787d86 | |||
| 35b36d8c30 | |||
| 738f71e6de | |||
| 5c80e759e5 | |||
| 782593c07c | |||
| 19c260b8da | |||
| 3156757fee | |||
| 012e9c2310 | |||
| 805b29d918 | |||
| 9148747de6 | |||
| c646f95706 | |||
| f0bbb28626 | |||
| 0e8c5ecd17 | |||
| f87f9fc4da | |||
| 1b76b6211f | |||
| 17bedc79e5 | |||
| 26bd2225d4 | |||
| 832655e360 | |||
| b86b044e5e | |||
| 8a3e9f1317 | |||
| 0278daa5b6 | |||
| 0f6b38557c | |||
| d3d1aee6a3 | |||
| 63ce9a6fb9 | 
							
								
								
									
										26
									
								
								.drone.yml
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								.drone.yml
									
									
									
									
									
								
							| @ -3,7 +3,7 @@ kind: pipeline | |||||||
| name: deploy to swarm-test.autonomic.zone | name: deploy to swarm-test.autonomic.zone | ||||||
| steps: | steps: | ||||||
|   - name: deployment |   - name: deployment | ||||||
|     image: decentral1se/stack-ssh-deploy:latest |     image: git.coopcloud.tech/coop-cloud/stack-ssh-deploy:latest | ||||||
|     settings: |     settings: | ||||||
|       host: swarm-test.autonomic.zone |       host: swarm-test.autonomic.zone | ||||||
|       stack: nextcloud |       stack: nextcloud | ||||||
| @ -11,15 +11,39 @@ steps: | |||||||
|       purge: true |       purge: true | ||||||
|       deploy_key: |       deploy_key: | ||||||
|         from_secret: drone_ssh_swarm_test |         from_secret: drone_ssh_swarm_test | ||||||
|  |       networks: | ||||||
|  |         - proxy | ||||||
|     environment: |     environment: | ||||||
|       DOMAIN: nextcloud.swarm-test.autonomic.zone |       DOMAIN: nextcloud.swarm-test.autonomic.zone | ||||||
|       STACK_NAME: nextcloud |       STACK_NAME: nextcloud | ||||||
|       LETS_ENCRYPT_ENV: production |       LETS_ENCRYPT_ENV: production | ||||||
|       ADMIN_USER: foobar |       ADMIN_USER: foobar | ||||||
|  |       FPM_TUNE_VERSION: v1 | ||||||
|  |       NGINX_CONF_VERSION: v1 | ||||||
|  |       MY_CNF_VERSION: v1 | ||||||
|  |       ENTRYPOINT_VERSION: v1 | ||||||
|       SECRET_DB_PASSWORD_VERSION: v1 |       SECRET_DB_PASSWORD_VERSION: v1 | ||||||
|       SECRET_DB_ROOT_PASSWORD_VERSION: v1 |       SECRET_DB_ROOT_PASSWORD_VERSION: v1 | ||||||
|       SECRET_ADMIN_PASSWORD_VERSION: v1 |       SECRET_ADMIN_PASSWORD_VERSION: v1 | ||||||
|  |       SECRET_ONLYOFFICE_JWT_VERSION: v1 | ||||||
|  |       SECRET_BBB_SECRET_VERSION: v1 | ||||||
|       EXTRA_VOLUME: "/dev/null:/tmp/.dummy" |       EXTRA_VOLUME: "/dev/null:/tmp/.dummy" | ||||||
| trigger: | trigger: | ||||||
|   branch: |   branch: | ||||||
|     - main |     - main | ||||||
|  | --- | ||||||
|  | kind: pipeline | ||||||
|  | name: generate recipe catalogue | ||||||
|  | steps: | ||||||
|  |   - name: release a new version | ||||||
|  |     image: plugins/downstream | ||||||
|  |     settings: | ||||||
|  |       server: https://build.coopcloud.tech | ||||||
|  |       token: | ||||||
|  |         from_secret: drone_abra-bot_token | ||||||
|  |       fork: true | ||||||
|  |       repositories: | ||||||
|  |         - coop-cloud/auto-recipes-catalogue-json | ||||||
|  |  | ||||||
|  | trigger: | ||||||
|  |   event: tag | ||||||
|  | |||||||
							
								
								
									
										60
									
								
								.env.sample
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								.env.sample
									
									
									
									
									
								
							| @ -1,6 +1,9 @@ | |||||||
| TYPE=nextcloud | TYPE=nextcloud | ||||||
|  | TIMEOUT=900 | ||||||
|  | ENABLE_AUTO_UPDATE=true | ||||||
|  | ENABLE_BACKUPS=true | ||||||
|  |  | ||||||
| DOMAIN={{ .Domain }} | DOMAIN=nextcloud.example.com | ||||||
| ## Domain aliases | ## Domain aliases | ||||||
| #EXTRA_DOMAINS=', `www.nextcloud.example.com`' | #EXTRA_DOMAINS=', `www.nextcloud.example.com`' | ||||||
| LETS_ENCRYPT_ENV=production | LETS_ENCRYPT_ENV=production | ||||||
| @ -9,6 +12,8 @@ COMPOSE_FILE="compose.yml" | |||||||
| COMPOSE_FILE="$COMPOSE_FILE:compose.mariadb.yml" | COMPOSE_FILE="$COMPOSE_FILE:compose.mariadb.yml" | ||||||
| #COMPOSE_FILE="$COMPOSE_FILE:compose.postgres.yml" | #COMPOSE_FILE="$COMPOSE_FILE:compose.postgres.yml" | ||||||
|  |  | ||||||
|  | #MAX_DB_CONNECTIONS=500 | ||||||
|  |  | ||||||
| ADMIN_USER=admin | ADMIN_USER=admin | ||||||
|  |  | ||||||
| SECRET_DB_ROOT_PASSWORD_VERSION=v1 | SECRET_DB_ROOT_PASSWORD_VERSION=v1 | ||||||
| @ -17,7 +22,58 @@ SECRET_ADMIN_PASSWORD_VERSION=v1 | |||||||
|  |  | ||||||
| EXTRA_VOLUME=/dev/null:/tmp/.dummy | EXTRA_VOLUME=/dev/null:/tmp/.dummy | ||||||
|  |  | ||||||
|  | PHP_MEMORY_LIMIT=1G | ||||||
|  | # fpm-tune, see: https://spot13.com/pmcalculator/ | ||||||
|  | FPM_MAX_CHILDREN=16 | ||||||
|  | FPM_START_SERVERS=4 | ||||||
|  | FPM_MIN_SPARE_SERVERS=4 | ||||||
|  | FPM_MAX_SPARE_SERVERS=12 | ||||||
|  |  | ||||||
|  | DEFAULT_QUOTA="10 GB" | ||||||
|  |  | ||||||
| # X_FRAME_OPTIONS_ENABLED=1 | # X_FRAME_OPTIONS_ENABLED=1 | ||||||
| # X_FRAME_OPTIONS_ALLOW_FROM=embedding-site.example.org | # X_FRAME_OPTIONS_ALLOW_FROM=embedding-site.example.org | ||||||
| # APPS="calendar sociallogin onlyoffice" |  | ||||||
|  |  | ||||||
|  | # COMPOSE_FILE="$COMPOSE_FILE:compose.smtp.yml" | ||||||
|  | # See https://github.com/nextcloud/docker#auto-configuration-via-environment-variables for default values | ||||||
|  | # SMTP_AUTHTYPE= | ||||||
|  | # SMTP_HOST= | ||||||
|  | # SMTP_SECURE= | ||||||
|  | # SMTP_NAME= | ||||||
|  | # SMTP_PORT= | ||||||
|  | # MAIL_FROM_ADDRESS= | ||||||
|  | # MAIL_DOMAIN= | ||||||
|  | # SECRET_SMTP_PASSWORD_VERSION=v1 | ||||||
|  |  | ||||||
|  | ## Customization | ||||||
|  | # THEMING_COLOR= | ||||||
|  | # THEMING_SLOGAN= | ||||||
|  | # COPY_ASSETS="flow_background.jpg|app:/var/www/html/themes/" | ||||||
|  | # COPY_ASSETS="$COPY_ASSETS icon_left_brand.svg|app:/var/www/html/themes/" | ||||||
|  | # COPY_ASSETS="$COPY_ASSETS icon.png|app:/var/www/html/themes/" | ||||||
|  |  | ||||||
|  | # APPS="calendar" | ||||||
|  |  | ||||||
|  | # COLLABORA_URL=https://collabora.example.com | ||||||
|  |  | ||||||
|  | # COMPOSE_FILE="$COMPOSE_FILE:compose.onlyoffice.yml" | ||||||
|  | # ONLYOFFICE_URL=https://onlyoffice.example.com | ||||||
|  | # APPS="$APPS onlyoffice" | ||||||
|  | # SECRET_ONLYOFFICE_JWT_VERSION=v1 | ||||||
|  |  | ||||||
|  | # COMPOSE_FILE="$COMPOSE_FILE:compose.bbb.yml" | ||||||
|  | # BBB_URL=https://talk.example.org/bigbluebutton/ # trailing slash! | ||||||
|  | # SECRET_BBB_SECRET_VERSION=v1 | ||||||
|  |  | ||||||
|  | # COMPOSE_FILE="$COMPOSE_FILE:compose.authentik.yml" | ||||||
|  | # APPS="$APPS sociallogin" | ||||||
|  | # AUTHENTIK_USER_PREFIX=authentik | ||||||
|  | # AUTHENTIK_DOMAIN=authentik.example.com | ||||||
|  | # SECRET_AUTHENTIK_SECRET_VERSION=v1 | ||||||
|  | # SECRET_AUTHENTIK_ID_VERSION=v1 | ||||||
|  | # OCC_CMDS="app:disable dashboard" | ||||||
|  | # OCC_CMDS="$OCC_CMDS|config:app:set sociallogin auto_create_groups --value 1" | ||||||
|  | # OCC_CMDS="$OCC_CMDS|config:app:set sociallogin hide_default_login --value 1" | ||||||
|  |  | ||||||
|  | #COMPOSE_FILE="$COMPOSE_FILE:compose.fulltextsearch.yml" | ||||||
|  | #SECRET_ELASTICSEARCH_PASSWORD_VERSION=v1 | ||||||
|  | |||||||
							
								
								
									
										125
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								README.md
									
									
									
									
									
								
							| @ -6,38 +6,91 @@ Fully automated luxury Nextcloud via docker-swarm. | |||||||
|  |  | ||||||
| <!-- metadata --> | <!-- metadata --> | ||||||
| * **Category**: Apps | * **Category**: Apps | ||||||
| * **Status**: 2, beta | * **Status**: 5 | ||||||
| * **Image**: [`nextcloud`](https://hub.docker.com/_/nextcloud), 4, upstream | * **Image**: [`nextcloud`](https://hub.docker.com/_/nextcloud), 4, upstream | ||||||
| * **Healthcheck**: Yes | * **Healthcheck**: Yes | ||||||
| * **Backups**: No | * **Backups**: Yes | ||||||
| * **Email**: 3 | * **Email**: 3 | ||||||
| * **Tests**: 2 | * **Tests**: 2 | ||||||
| * **SSO**: 1 (OAuth) | * **SSO**: 1 (OAuth) | ||||||
| <!-- endmetadata --> | <!-- endmetadata --> | ||||||
|  |  | ||||||
| ## Basic usage | ## Quick start | ||||||
|  |  | ||||||
| 1. Set up Docker Swarm and [`abra`] | * `abra app new nextcloud` | ||||||
| 2. Deploy [`coop-cloud/traefik`] | * `abra app config <app-name>` | ||||||
| 3. `abra app new nextcloud --secrets` (optionally with `--pass` if you'd like | * `abra app secret insert <app-name> smtp_password v1 <SMTP_PASSWORD>` | ||||||
|    to save secrets in `pass`) | * `abra app secret generate -a <app-name>` | ||||||
| 4. `abra app YOURAPPDOMAIN config` - be sure to change `$DOMAIN` to something that resolves to | * `abra app deploy <app-name>` | ||||||
|    your Docker swarm box |  | ||||||
| 5. `abra app YOURAPPDOMAIN deploy` |  | ||||||
|  |  | ||||||
| ## How do I customise the default home page when logging in? | ### Onlyoffice Integration | ||||||
|  |  | ||||||
| - Delete the dashboard app since it is so corporate | `abra app config <app-name>`  | ||||||
| - Follow [these docs](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/default_files_configuration.html) to set the default files list for each user in the Files app | Configure the following envs: | ||||||
| - Configure a `defaultapp` in your `config.php` or use [apporder](https://apps.nextcloud.com/apps/apporder) | ``` | ||||||
|  | COMPOSE_FILE="$COMPOSE_FILE:compose.apps.yml" | ||||||
|  | ONLYOFFICE_URL=https://onlyoffice.example.com | ||||||
|  | SECRET_ONLYOFFICE_JWT_VERSION=v1 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | `abra app secret insert <app-name> onlyoffice_jwt v1 <jwt_secret>` | ||||||
|  | `abra app cmd <app-name> app install_onlyoffice` | ||||||
|  |  | ||||||
|  | ### BBB Integration | ||||||
|  |  | ||||||
|  | `abra app config <app-name>`  | ||||||
|  | Configure the following envs: | ||||||
|  | ``` | ||||||
|  | COMPOSE_FILE="$COMPOSE_FILE:compose.apps.yml" | ||||||
|  | BBB_URL=https://talk.example.org/bigbluebutton/ # trailing slash! | ||||||
|  | SECRET_BBB_SECRET_VERSION=v1 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | `abra app secret insert <app-name> bbb_secret v1 <bbb_secret>` | ||||||
|  | `abra app cmd <app-name> app install_bbb` | ||||||
|  |  | ||||||
|  | ### Authentik Integration | ||||||
|  |  | ||||||
|  |  | ||||||
|  | `abra app config <app-name>`  | ||||||
|  | Configure the following envs: | ||||||
|  | ``` | ||||||
|  | COMPOSE_FILE="$COMPOSE_FILE:compose.authentik.yml" | ||||||
|  | AUTHENTIK_USER_PREFIX=authentik | ||||||
|  | AUTHENTIK_DOMAIN=authentik.example.com | ||||||
|  | AUTHENTIK_SECRET_NAME=authentik_example_com_nextcloud_secret_v1  # the same as in authentik | ||||||
|  | AUTHENTIK_ID_NAME=authentik_example_com_nextcloud_id_v1  # the same as in authentik | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | `abra app cmd <app-name> app set_authentik` | ||||||
|  |  | ||||||
|  | ### Disable Dashboard | ||||||
|  |  | ||||||
|  | Disable dashboard app since it is so corporate: | ||||||
|  |  | ||||||
|  | `abra app config <app-name>`  | ||||||
|  | Configure the following envs: | ||||||
|  | ``` | ||||||
|  | OCC_CMDS="app:disable dashboard" | ||||||
|  | ``` | ||||||
|  | `abra app cmd <app-name> app post_install_occ` | ||||||
|  |  | ||||||
| ## Running `occ` | ## Running `occ` | ||||||
|  |  | ||||||
| `abra app run --user www-data YOURAPPDOMAIN app occ user:list --help` | `abra app cmd <app-name> app run_occ '"user:list --help"'` | ||||||
|  |  | ||||||
|  | ## Default user files | ||||||
|  |  | ||||||
|  | - Follow [these docs](https://docs.nextcloud.com/server/latest/admin_manual/configuration_files/default_files_configuration.html) to set the default files list for each user in the Files app | ||||||
|  |  | ||||||
|  | ## Default App | ||||||
|  |  | ||||||
|  | - Configure a `defaultapp` in your `config.php` or use [apporder](https://apps.nextcloud.com/apps/apporder) | ||||||
|  |  | ||||||
| ## Upgrading Nextcloud apps | ## Upgrading Nextcloud apps | ||||||
|  |  | ||||||
| `abra app run --user www-data YOURAPPDOMAIN app occ app:update --all` | `abra app cmd <app-name> app run_occ '"app:update --all"'` | ||||||
|  |  | ||||||
|  |  | ||||||
| ## How do I fix a Nextcloud version snafu? | ## How do I fix a Nextcloud version snafu? | ||||||
|  |  | ||||||
| @ -66,7 +119,7 @@ Use [this plugin](https://github.com/pulsejet/nextcloud-oidc-login). Unlike the | |||||||
| ``` | ``` | ||||||
|   'oidc_login_client_id' => 'nextcloud', |   'oidc_login_client_id' => 'nextcloud', | ||||||
|   'oidc_login_client_secret' => 'mysecret', |   'oidc_login_client_secret' => 'mysecret', | ||||||
|   'oidc_login_provider_url' => 'https://example.com/auth/realms/myrealm', |   'oidc_login_provider_url' => 'https://example.com/realms/myrealm', | ||||||
|   'oidc_login_disable_registration' => false, |   'oidc_login_disable_registration' => false, | ||||||
|   'oidc_login_hide_password_form' => true, |   'oidc_login_hide_password_form' => true, | ||||||
|   'oidc_login_button_text' => 'Log in with your myssodomain', |   'oidc_login_button_text' => 'Log in with your myssodomain', | ||||||
| @ -190,3 +243,41 @@ docker exec -u www-data $(docker ps -f name=foo_com_app -q) ./occ preview:pre-ge | |||||||
| ``` | ``` | ||||||
|  |  | ||||||
| This app will improve performance of image browsing at the cost of storage space. | This app will improve performance of image browsing at the cost of storage space. | ||||||
|  |  | ||||||
|  | ## Fulltextsearch using elasticsearch | ||||||
|  |  | ||||||
|  | 1. Uncomment the following lines in your env file: | ||||||
|  | ``` | ||||||
|  | #COMPOSE_FILE="$COMPOSE_FILE:compose.fulltextsearch.yml" | ||||||
|  | #SECRET_ELASTICSEARCH_PASSWORD_VERSION=v1 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | 2. Generate the secret for elasticsearch: | ||||||
|  | ```bash | ||||||
|  | abra app secret generate <domain> elasticsearch_password v1 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | 3. Deploy your app: | ||||||
|  | ```bash | ||||||
|  | abra app deploy <domain> | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | 4. Install the apps and configure them: | ||||||
|  | ``` | ||||||
|  | abra app cmd <domain> app install_fulltextsearch | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | 5. You might need to configure the files_fulltextsearch app. run this command to check its settings: | ||||||
|  | ``` | ||||||
|  | abra app cmd <domain> app run_occ '"config:list files_fulltextsearch" | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | 6. You can check if the nextcloud can connect to elasticsearch: | ||||||
|  | ``` | ||||||
|  | abra app cmd <domain> app run_occ '"fulltextsearch:test"' | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | And you can populate the index manually and check if any errors occur: | ||||||
|  | ``` | ||||||
|  | abra app cmd <domain> app run_occ '"fulltextsearch:index"' | ||||||
|  | ``` | ||||||
|  | |||||||
							
								
								
									
										212
									
								
								abra.sh
									
									
									
									
									
								
							
							
						
						
									
										212
									
								
								abra.sh
									
									
									
									
									
								
							| @ -1,122 +1,150 @@ | |||||||
| export FPM_TUNE_VERSION=v4 | #!/bin/bash | ||||||
| export NGINX_CONF_VERSION=v4 |  | ||||||
| export MY_CNF_VERSION=v4 |  | ||||||
| export ENTRYPOINT_VERSION=v2 |  | ||||||
|  |  | ||||||
| NC_APP_DIR="app:/var/www/html" | export FPM_TUNE_VERSION=v5 | ||||||
|  | export NGINX_CONF_VERSION=v7 | ||||||
|  | export MY_CNF_VERSION=v5 | ||||||
|  | export ENTRYPOINT_VERSION=v3 | ||||||
|  | export CRONTAB_VERSION=v1 | ||||||
|  | export PG_BACKUP_VERSION=v1 | ||||||
|  |  | ||||||
| sub_occ(){ | run_occ() { | ||||||
|   # shellcheck disable=SC2034 |  | ||||||
|   abra__service_="app" |  | ||||||
|   # shellcheck disable=SC2034 |  | ||||||
|   abra___user="www-data" |  | ||||||
|   sub_app_run php /var/www/html/occ "$@" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| run_occ(){ |  | ||||||
|     su -p www-data -s /bin/sh -c "/var/www/html/occ $@" |     su -p www-data -s /bin/sh -c "/var/www/html/occ $@" | ||||||
| } | } | ||||||
|  |  | ||||||
| install_apps(){ | post_install_occ() { | ||||||
|  |     IFS='|' read -ra CMD <<<"$OCC_CMDS" | ||||||
|  |     for cmd in "${CMD[@]}"; do | ||||||
|  |         run_occ "$cmd" | ||||||
|  |     done | ||||||
|  | } | ||||||
|  |  | ||||||
|  | install_apps() { | ||||||
|     install_apps="$@" |     install_apps="$@" | ||||||
|     if [ -z "$install_apps" ] |     if [ -z "$install_apps" ]; then | ||||||
|     then |  | ||||||
|         install_apps=$APPS |         install_apps=$APPS | ||||||
|     fi |     fi | ||||||
|     for app in $install_apps |     for app in $install_apps; do | ||||||
|     do |  | ||||||
|         run_occ "app:install $app" |         run_occ "app:install $app" | ||||||
|     done |     done | ||||||
| } | } | ||||||
|  |  | ||||||
| _backup_app() { | set_app_config() { | ||||||
|   # Copied _abra_backup_dir to make UX better on restore and backup |     APP=$1 | ||||||
|   { |     KEY=$2 | ||||||
|     abra__src_="$1" |     VALUE=$3 | ||||||
|     abra__dst_="-" |     run_occ "config:app:set $APP $KEY --value '$VALUE'" | ||||||
|   } |  | ||||||
|  |  | ||||||
|   # shellcheck disable=SC2154 |  | ||||||
|   FILENAME="$(basename "$1").tar" |  | ||||||
|  |  | ||||||
|   debug "Copying '$1' to '$FILENAME'" |  | ||||||
|  |  | ||||||
|   silence |  | ||||||
|   mkdir -p /tmp/abra |  | ||||||
|   sub_app_cp > /tmp/abra/$FILENAME |  | ||||||
|   unsilence |  | ||||||
| } | } | ||||||
|  |  | ||||||
| next_maintenance_on() { | set_system_config() { | ||||||
|   silence |     KEY=$1 | ||||||
|   sub_occ maintenance:mode --on > /dev/null |     VALUE=$2 | ||||||
|   unsilence |     run_occ "config:system:set $KEY --value '$VALUE'" | ||||||
|   debug "Nextcloud maintenance mode enabled" |  | ||||||
| } | } | ||||||
|  |  | ||||||
| next_maintenance_off() { | set_trusted_proxies() { | ||||||
|   silence |     trusted_proxies="$@" | ||||||
|   sub_occ maintenance:mode --off > /dev/null |     if [ -z "$1" ]; then | ||||||
|   unsilence |         trusted_proxies="$TRUSTED_PROXIES" | ||||||
|   debug "Nextcloud maintenance mode disabled" |     fi | ||||||
|  |     set_system_config trusted_proxies "$trusted_proxies" | ||||||
| } | } | ||||||
|  |  | ||||||
| abra_backup_app() { | set_logfile_stdout() { | ||||||
|   # shellcheck disable=SC2154 |     set_system_config logfile '/dev/stdout' | ||||||
|   ARK_FILENAME="$ABRA_BACKUP_DIR/${abra__app_}_app_$(date +%F).tar.gz" |  | ||||||
|   # Cant be FILENAME as that gets changed by something |  | ||||||
|   next_maintenance_on |  | ||||||
|   _backup_app $NC_APP_DIR/config |  | ||||||
|   _backup_app $NC_APP_DIR/data |  | ||||||
|   _backup_app $NC_APP_DIR/themes |  | ||||||
|   # Combine archives |  | ||||||
|   tar -Af /tmp/abra/config.tar /tmp/abra/data.tar |  | ||||||
|   tar -Af /tmp/abra/config.tar /tmp/abra/themes.tar |  | ||||||
|   gzip /tmp/abra/config.tar -c > "$ARK_FILENAME" |  | ||||||
|   rm /tmp/abra/*.tar |  | ||||||
|   success "Backed up 'app' to $ARK_FILENAME" |  | ||||||
|   next_maintenance_off |  | ||||||
| } | } | ||||||
|  |  | ||||||
| abra_backup_db() { | customize() { | ||||||
|   next_maintenance_on |     if [ -z "$1" ] | ||||||
|   _abra_backup_mysql "db" "nextcloud" |     then | ||||||
|   next_maintenance_off |             echo "Usage: ... customize <assets_path>" | ||||||
|  |             exit 1 | ||||||
|  |     fi | ||||||
|  |     asset_dir=$1 | ||||||
|  |     for asset in $COPY_ASSETS; do | ||||||
|  |         source=$(echo $asset | cut -d "|" -f1) | ||||||
|  |         target=$(echo $asset | cut -d "|" -f2) | ||||||
|  |         echo copy $source to $target | ||||||
|  |         abra app cp $APP_NAME $asset_dir/$source $target | ||||||
|  |     done | ||||||
|  |  | ||||||
|  |     abra app cmd -T $APP_NAME app set_app_config theming color \"$THEMING_COLOR\" | ||||||
|  |     abra app cmd -T $APP_NAME app set_app_config theming slogan \"$THEMING_SLOGAN\" | ||||||
|  |     abra app cmd -T $APP_NAME app run_occ '"theming:config background \"/var/www/html/themes/flow_background.jpg\""' | ||||||
|  |     abra app cmd -T $APP_NAME app run_occ '"theming:config logo \"/var/www/html/themes/icon_left_brand.svg\""' | ||||||
|  |     abra app cmd -T $APP_NAME app run_occ '"theming:config logoheader \"/var/www/html/themes/icon.png\""' | ||||||
| } | } | ||||||
|  |  | ||||||
| abra_backup() { | install_bbb() { | ||||||
|   abra_backup_app && abra_backup_db |     install_apps bbb | ||||||
|  |     set_app_config bbb app.navigation true | ||||||
|  |     set_app_config bbb api.url "$BBB_URL" | ||||||
|  |     set_app_config bbb api.secret "$(cat /run/secrets/bbb_secret)" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | install_onlyoffice() { | ||||||
| abra_restore_app() { |     install_apps onlyoffice | ||||||
|   next_maintenance_on |     set_app_config onlyoffice DocumentServerUrl "$ONLYOFFICE_URL" | ||||||
|   # shellcheck disable=SC2034 |     set_app_config onlyoffice jwt_secret "$(cat /run/secrets/onlyoffice_jwt)" | ||||||
|   { |     set_app_config onlyoffice customizationForcesave true | ||||||
|   abra__src_="-" |  | ||||||
|   abra__dst_=$NC_APP_DIR |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   zcat "$@" | sub_app_cp |  | ||||||
|  |  | ||||||
|   next_maintenance_off |  | ||||||
|   sub_occ files:scan --all > /dev/null # Needs to be run in normal mode |  | ||||||
|   success "Restored 'app'" |  | ||||||
| } | } | ||||||
|  |  | ||||||
| # abra_restore_db() { | install_collabora() { | ||||||
| #   warning "Restoring the database is on a existing app and not a new one has not been tested. Use with caution." |     install_apps richdocuments | ||||||
| #   next_maintenance_on |     set_app_config richdocuments wopi_url "$COLLABORA_URL" | ||||||
| #   # 3wc: unlike abra_backup_db, we can assume abra__service_ will be 'db' if we | } | ||||||
| #   # got this far.. |  | ||||||
|  |  | ||||||
| #   # shellcheck disable=SC2034 | install_fulltextsearch() { | ||||||
| #   abra___no_tty="true" |     install_apps fulltextsearch | ||||||
|  |     install_apps fulltextsearch_elasticsearch | ||||||
|  |     install_apps files_fulltextsearch | ||||||
|  |     set_app_config fulltextsearch search_platform "OCA\\FullTextSearch_Elasticsearch\\Platform\\ElasticSearchPlatform" | ||||||
|  |     set_app_config fulltextsearch_elasticsearch elastic_host "http://elastic:$(cat /run/secrets/elasticsearch_password)@elasticsearch:9200/" | ||||||
|  |     set_app_config fulltextsearch_elasticsearch elastic_index "nextcloud" | ||||||
|  |     set_app_config files_fulltextsearch files_local "1" | ||||||
|  | } | ||||||
|  |  | ||||||
| #   DB_PASSWORD=$(sub_app_run cat /run/secrets/db_password) | set_default_quota() { | ||||||
|  |     set_app_config files default_quota "$DEFAULT_QUOTA" | ||||||
|  | } | ||||||
|  |  | ||||||
| #   zcat "$@" | sub_app_run mysql -u root -p"$DB_PASSWORD" wordpress | set_authentik() { | ||||||
|  |     install_apps sociallogin | ||||||
|  |     AUTHENTIK_SECRET=$(cat /run/secrets/authentik_secret) | ||||||
|  |     AUTHENTIK_ID=$(cat /run/secrets/authentik_id) | ||||||
|  |     set_system_config logo_url https://$AUTHENTIK_DOMAIN | ||||||
|  |     set_app_config sociallogin custom_providers " | ||||||
|  | { | ||||||
|  |     \"custom_oidc\":[ | ||||||
|  |     { | ||||||
|  |         \"name\":\"$AUTHENTIK_USER_PREFIX\", | ||||||
|  |         \"title\":\"authentik\", | ||||||
|  |         \"authorizeUrl\": \"https://$AUTHENTIK_DOMAIN/application/o/authorize/\", | ||||||
|  |         \"tokenUrl\": \"https://$AUTHENTIK_DOMAIN/application/o/token/\", | ||||||
|  |         \"displayNameClaim\":\"preferred_username\", | ||||||
|  |         \"userInfoUrl\": \"https://$AUTHENTIK_DOMAIN/application/o/userinfo/\", | ||||||
|  |         \"logoutUrl\": \"https://$AUTHENTIK_DOMAIN/application/o/nextcloud/end-session/\", | ||||||
|  |         \"clientId\":\"$AUTHENTIK_ID\", | ||||||
|  |         \"clientSecret\":\"$AUTHENTIK_SECRET\", | ||||||
|  |         \"scope\":\"openid profile email nextcloud\", | ||||||
|  |         \"groupsClaim\":\"nextcloud_groups\", | ||||||
|  |         \"style\":\"openid\", | ||||||
|  |         \"defaultGroup\":\"\", | ||||||
|  |         \"groupMapping\": { | ||||||
|  |           \"admin\": \"admin\", | ||||||
|  |           \"authentik Admins\": \"admin\" | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | ] | ||||||
|  | }" | ||||||
|  |  | ||||||
| #   success "Restored 'db'" |     set_app_config sociallogin update_profile_on_login 1 | ||||||
| #   next_maintenance_off |     set_app_config sociallogin auto_create_groups 1 | ||||||
| # } |     set_app_config sociallogin hide_default_login 1 | ||||||
|  |     run_occ 'config:system:set social_login_auto_redirect --value true' | ||||||
|  |     run_occ 'config:system:set allow_user_to_change_display_name --value=false' | ||||||
|  |     run_occ 'config:system:set lost_password_link --value=disabled' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | disable_skeletondirectory() { | ||||||
|  |     run_occ "config:system:set skeletondirectory --value ''" | ||||||
|  | } | ||||||
|  | |||||||
							
								
								
									
										24
									
								
								alaconnect.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								alaconnect.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | authentik: | ||||||
|  |     uncomment: | ||||||
|  |         - compose.authentik.yml | ||||||
|  |         - AUTHENTIK_USER_PREFIX | ||||||
|  |         - AUTHENTIK_DOMAIN | ||||||
|  |         - SECRET_AUTHENTIK_SECRET_VERSION | ||||||
|  |         - SECRET_AUTHENTIK_ID_VERSION | ||||||
|  |     initial-hooks: | ||||||
|  |         - app set_authentik | ||||||
|  |     shared_secrets: | ||||||
|  |         nextcloud_secret: authentik_secret | ||||||
|  |         nextcloud_id: authentik_id | ||||||
|  | onlyoffice: | ||||||
|  |     uncomment: | ||||||
|  |         - compose.onlyoffice.yml | ||||||
|  |         - ONLYOFFICE_URL | ||||||
|  |         - SECRET_ONLYOFFICE_JWT_VERSION | ||||||
|  |     initial-hooks: | ||||||
|  |         - app install_onlyoffice | ||||||
|  | collabora: | ||||||
|  |     uncomment: | ||||||
|  |         - COLLABORA_URL | ||||||
|  |     initial-hooks: | ||||||
|  |         - app install_collabora | ||||||
							
								
								
									
										14
									
								
								compose.authentik.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								compose.authentik.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | |||||||
|  | version: "3.8" | ||||||
|  | services: | ||||||
|  |   app: | ||||||
|  |     secrets: | ||||||
|  |       - authentik_secret | ||||||
|  |       - authentik_id | ||||||
|  |  | ||||||
|  | secrets: | ||||||
|  |   authentik_secret: | ||||||
|  |     external: true | ||||||
|  |     name: ${STACK_NAME}_authentik_secret_${SECRET_AUTHENTIK_SECRET_VERSION} | ||||||
|  |   authentik_id: | ||||||
|  |     external: true | ||||||
|  |     name: ${STACK_NAME}_authentik_id_${SECRET_AUTHENTIK_ID_VERSION} | ||||||
							
								
								
									
										12
									
								
								compose.bbb.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								compose.bbb.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | version: "3.8" | ||||||
|  | services: | ||||||
|  |   app: | ||||||
|  |     secrets: | ||||||
|  |       - bbb_secret | ||||||
|  |     environment: | ||||||
|  |       - BBB_URL | ||||||
|  |  | ||||||
|  | secrets: | ||||||
|  |   bbb_secret: | ||||||
|  |     external: true | ||||||
|  |     name: ${STACK_NAME}_bbb_secret_${SECRET_BBB_SECRET_VERSION} | ||||||
							
								
								
									
										55
									
								
								compose.fulltextsearch.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								compose.fulltextsearch.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | version: "3.8" | ||||||
|  |  | ||||||
|  | services: | ||||||
|  |   elasticsearch: | ||||||
|  |     image: "docker.elastic.co/elasticsearch/elasticsearch:8.15.0" | ||||||
|  |     environment: | ||||||
|  |       - cluster.name=docker-cluster | ||||||
|  |       - bootstrap.memory_lock=true | ||||||
|  |       - "ES_JAVA_OPTS=-Xms512m -Xmx512m" | ||||||
|  |       - discovery.type=single-node | ||||||
|  |       # Disable authentication and ssl completely | ||||||
|  |       # - xpack.security.enabled=false | ||||||
|  |       # Use this to enable Basic Authentication: | ||||||
|  |       - xpack.security.enabled=true | ||||||
|  |       - xpack.security.http.ssl.enabled=false | ||||||
|  |       - ELASTIC_PASSWORD_FILE=/var/run/secrets/elasticsearch_password | ||||||
|  |     ulimits: | ||||||
|  |       memlock: | ||||||
|  |         soft: -1 | ||||||
|  |         hard: -1 | ||||||
|  |     volumes: | ||||||
|  |       - elasticsearch:/usr/share/elasticsearch/data | ||||||
|  |     networks: | ||||||
|  |       - internal | ||||||
|  |     secrets: | ||||||
|  |       - source: elasticsearch_password | ||||||
|  |         uid: "1000" | ||||||
|  |         gid: "1000" | ||||||
|  |         mode: 0600 | ||||||
|  |  | ||||||
|  |   searchindexer: | ||||||
|  |     image: nextcloud:28.0.10-fpm | ||||||
|  |     volumes: | ||||||
|  |       - nextcloud:/var/www/html/ | ||||||
|  |       - nextapps:/var/www/html/custom_apps:cached | ||||||
|  |       - nextdata:/var/www/html/data:cached | ||||||
|  |       - nextconfig:/var/www/html/config:cached | ||||||
|  |       - ${EXTRA_VOLUME} | ||||||
|  |     networks: | ||||||
|  |       - internal | ||||||
|  |     entrypoint: su -p www-data -s /bin/sh -c '/var/www/html/occ fulltextsearch:live' | ||||||
|  |  | ||||||
|  |   # Add the secret to the app service so it is avaiable in the | ||||||
|  |   # install_fulltextsearch command | ||||||
|  |   app: | ||||||
|  |     secrets: | ||||||
|  |       - elasticsearch_password | ||||||
|  |  | ||||||
|  | secrets: | ||||||
|  |   elasticsearch_password: | ||||||
|  |     external: true | ||||||
|  |     name: ${STACK_NAME}_elasticsearch_password_${SECRET_ELASTICSEARCH_PASSWORD_VERSION} | ||||||
|  |  | ||||||
|  | volumes: | ||||||
|  |   elasticsearch: | ||||||
| @ -15,6 +15,7 @@ services: | |||||||
|       - MYSQL_USER=nextcloud |       - MYSQL_USER=nextcloud | ||||||
|       - MYSQL_PASSWORD_FILE=/run/secrets/db_password |       - MYSQL_PASSWORD_FILE=/run/secrets/db_password | ||||||
|       - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_root_password |       - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_root_password | ||||||
|  |       - MAX_DB_CONNECTIONS=${MAX_DB_CONNECTIONS:-100} | ||||||
|     configs: |     configs: | ||||||
|       - source: my_tune |       - source: my_tune | ||||||
|         target: /etc/mysql/conf.d/my-tune.cnf |         target: /etc/mysql/conf.d/my-tune.cnf | ||||||
| @ -27,14 +28,25 @@ services: | |||||||
|       - internal |       - internal | ||||||
|     deploy: |     deploy: | ||||||
|       labels: |       labels: | ||||||
|           backupbot.backup: "true" |         backupbot.backup.pre-hook: 'mysqldump --single-transaction -u root -p"$$(cat /run/secrets/db_root_password)" nextcloud > /var/lib/mysql/backup.sql' | ||||||
|           backupbot.backup.pre-hook: 'mkdir -p /tmp/backup/ && mysqldump --single-transaction -u root -p"$$(cat /run/secrets/db_root_password)" nextcloud > /tmp/backup/backup.sql' |         backupbot.backup.volumes.mariadb.path: "backup.sql" | ||||||
|           backupbot.backup.post-hook: "rm -rf /tmp/backup" |         backupbot.restore.post-hook: 'mysql -u root -p"$$(cat /run/secrets/db_root_password)" nextcloud < /var/lib/mysql/backup.sql' | ||||||
|           backupbot.backup.path: "/tmp/backup/" |     healthcheck: | ||||||
|  |       test: ["CMD-SHELL", 'mysqladmin -p"$$(cat /run/secrets/db_root_password)"  ping'] | ||||||
|  |       interval: 30s | ||||||
|  |       timeout: 10s | ||||||
|  |       retries: 10 | ||||||
|  |       start_period: 1m | ||||||
| configs: | configs: | ||||||
|   my_tune: |   my_tune: | ||||||
|     name: ${STACK_NAME}_my_cnf_${MY_CNF_VERSION} |     name: ${STACK_NAME}_my_cnf_${MY_CNF_VERSION} | ||||||
|     file: my-tune.cnf |     file: my-tune.cnf | ||||||
|  |     template_driver: golang | ||||||
|  |  | ||||||
|  | secrets: | ||||||
|  |   db_root_password: | ||||||
|  |     external: true | ||||||
|  |     name: ${STACK_NAME}_db_root_password_${SECRET_DB_ROOT_PASSWORD_VERSION} | ||||||
|  |  | ||||||
| volumes: | volumes: | ||||||
|   mariadb: |   mariadb: | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								compose.onlyoffice.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								compose.onlyoffice.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | version: "3.8" | ||||||
|  | services: | ||||||
|  |   app: | ||||||
|  |     secrets: | ||||||
|  |       - onlyoffice_jwt | ||||||
|  |     environment: | ||||||
|  |       - ONLYOFFICE_URL | ||||||
|  |  | ||||||
|  | secrets: | ||||||
|  |   onlyoffice_jwt: | ||||||
|  |     external: true | ||||||
|  |     name: ${STACK_NAME}_onlyoffice_jwt_${SECRET_ONLYOFFICE_JWT_VERSION} | ||||||
| @ -10,28 +10,37 @@ services: | |||||||
|       - NEXTCLOUD_UPDATE=1 |       - NEXTCLOUD_UPDATE=1 | ||||||
|  |  | ||||||
|   db: |   db: | ||||||
|     image: "postgres:12" |     image: "postgres:13" | ||||||
|  |     command: -c "max_connections=${MAX_DB_CONNECTIONS:-100}" | ||||||
|     volumes: |     volumes: | ||||||
|       - "postgres:/var/lib/postgresql/data" |       - "postgres:/var/lib/postgresql/data" | ||||||
|     networks: |     networks: | ||||||
|       - internal |       - internal | ||||||
|     environment: |     environment: | ||||||
|       POSTGRES_USER: nextcloud  |       POSTGRES_USER: nextcloud | ||||||
|       POSTGRES_PASSWORD_FILE: /run/secrets/db_password |       POSTGRES_PASSWORD_FILE: /run/secrets/db_password | ||||||
|       POSTGRES_DB: nextcloud  |       POSTGRES_DB: nextcloud | ||||||
|     secrets: |     secrets: | ||||||
|       - db_password |       - db_password | ||||||
|     healthcheck: |     healthcheck: | ||||||
|       test: ["CMD-SHELL", "pg_isready"] |       test: ["CMD-SHELL", "pg_isready", "-U", "nextcloud"] | ||||||
|       interval: 10s |       interval: 10s | ||||||
|       timeout: 5s |       timeout: 5s | ||||||
|       retries: 5 |       retries: 5 | ||||||
|     deploy: |     deploy: | ||||||
|       labels: |       labels: | ||||||
|             backupbot.backup: "true" |         backupbot.backup.pre-hook: "/pg_backup.sh backup" | ||||||
|             backupbot.backup.pre-hook: "mkdir -p /tmp/backup/ && PGPASSWORD=$$(cat $${POSTGRES_PASSWORD_FILE}) pg_dump -U $${POSTGRES_USER} $${POSTGRES_DB} > /tmp/backup/backup.sql" |         backupbot.backup.volumes.postgres.path: "backup.sql" | ||||||
|             backupbot.backup.post-hook: "rm -rf /tmp/backup" |         backupbot.restore.post-hook: '/pg_backup.sh restore' | ||||||
|             backupbot.backup.path: "/tmp/backup/" |     configs: | ||||||
|  |         - source: pg_backup | ||||||
|  |           target: /pg_backup.sh | ||||||
|  |           mode: 0555 | ||||||
|  |  | ||||||
| volumes: | volumes: | ||||||
|   postgres: |   postgres: | ||||||
|  |  | ||||||
|  | configs: | ||||||
|  |   pg_backup: | ||||||
|  |     name: ${STACK_NAME}_pg_backup_${PG_BACKUP_VERSION} | ||||||
|  |     file: pg_backup.sh | ||||||
|  | |||||||
							
								
								
									
										19
									
								
								compose.smtp.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								compose.smtp.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | version: "3.8" | ||||||
|  | services: | ||||||
|  |   app: | ||||||
|  |     secrets: | ||||||
|  |       - smtp_password | ||||||
|  |     environment: | ||||||
|  |       - SMTP_AUTHTYPE | ||||||
|  |       - SMTP_HOST | ||||||
|  |       - SMTP_SECURE | ||||||
|  |       - SMTP_NAME | ||||||
|  |       - SMTP_PORT | ||||||
|  |       - SMTP_PASSWORD_FILE=/run/secrets/smtp_password | ||||||
|  |       - MAIL_FROM_ADDRESS | ||||||
|  |       - MAIL_DOMAIN | ||||||
|  |  | ||||||
|  | secrets: | ||||||
|  |   smtp_password: | ||||||
|  |     external: true | ||||||
|  |     name: ${STACK_NAME}_smtp_password_${SECRET_SMTP_PASSWORD_VERSION} | ||||||
							
								
								
									
										68
									
								
								compose.yml
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								compose.yml
									
									
									
									
									
								
							| @ -1,7 +1,9 @@ | |||||||
| version: "3.8" | version: "3.8" | ||||||
| services: | services: | ||||||
|   web: |   web: | ||||||
|     image: nginx:1.23.1 |     image: nginx:1.27.1 | ||||||
|  |     depends_on: | ||||||
|  |       - app | ||||||
|     configs: |     configs: | ||||||
|       - source: nginx_conf |       - source: nginx_conf | ||||||
|         target: /etc/nginx/nginx.conf |         target: /etc/nginx/nginx.conf | ||||||
| @ -33,14 +35,23 @@ services: | |||||||
|         - "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirect" |         - "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirect" | ||||||
|         - "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLForceHost=true" |         - "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLForceHost=true" | ||||||
|         - "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLHost=${DOMAIN}" |         - "traefik.http.middlewares.${STACK_NAME}-redirect.headers.SSLHost=${DOMAIN}" | ||||||
|  |         - "caddy=${DOMAIN}" | ||||||
|  |         - "caddy.reverse_proxy={{upstreams 80}}" | ||||||
|  |         - "caddy.tls.on_demand=" | ||||||
|  |     healthcheck: | ||||||
|  |       test: ["CMD-SHELL", 'curl -s -N curl -Ns localhost/status.php |  grep "installed\":true"'] | ||||||
|  |       interval: 30s | ||||||
|  |       timeout: 10s | ||||||
|  |       retries: 10 | ||||||
|  |       start_period: 5m | ||||||
|  |  | ||||||
|   app: |   app: | ||||||
|     image: nextcloud:24.0.6-fpm |     image: nextcloud:28.0.10-fpm | ||||||
|     depends_on: |     depends_on: | ||||||
|       - db |       - db | ||||||
|     configs: |     configs: | ||||||
|       - source: fpm_tune |       - source: fpm_tune | ||||||
|         target: /usr/local/etc/php-fpm.d/fpm-tune.conf |         target: /usr/local/etc/php-fpm.d/zzz-fpm-tune.conf | ||||||
|       - source: entrypoint |       - source: entrypoint | ||||||
|         target: /custom-entrypoint.sh |         target: /custom-entrypoint.sh | ||||||
|         mode: 555 |         mode: 555 | ||||||
| @ -50,6 +61,7 @@ services: | |||||||
|       - admin_password |       - admin_password | ||||||
|     environment: |     environment: | ||||||
|       - APPS |       - APPS | ||||||
|  |       - OCC_CMDS | ||||||
|       - X_FRAME_OPTIONS_ALLOW_FROM |       - X_FRAME_OPTIONS_ALLOW_FROM | ||||||
|       - X_FRAME_OPTIONS_ENABLED |       - X_FRAME_OPTIONS_ENABLED | ||||||
|       - DOMAIN |       - DOMAIN | ||||||
| @ -57,14 +69,15 @@ services: | |||||||
|       - NEXTCLOUD_ADMIN_USER=${ADMIN_USER} |       - NEXTCLOUD_ADMIN_USER=${ADMIN_USER} | ||||||
|       - NEXTCLOUD_ADMIN_PASSWORD_FILE=/run/secrets/admin_password |       - NEXTCLOUD_ADMIN_PASSWORD_FILE=/run/secrets/admin_password | ||||||
|       - NEXTCLOUD_TRUSTED_DOMAINS=${DOMAIN} |       - NEXTCLOUD_TRUSTED_DOMAINS=${DOMAIN} | ||||||
|       - TRUSTED_PROXIES=traefik |       - TRUSTED_PROXIES=10.0.0.0/8 | ||||||
|       - REDIS_HOST=cache |       - REDIS_HOST=cache | ||||||
|       - SMTP_HOST |  | ||||||
|       - MAIL_FROM_ADDRESS |  | ||||||
|       - MAIL_DOMAIN |  | ||||||
|       - SMTP_AUTHTYPE=PLAIN |  | ||||||
|       - OVERWRITEPROTOCOL=https |       - OVERWRITEPROTOCOL=https | ||||||
|       - PHP_MEMORY_LIMIT=1G |       - PHP_MEMORY_LIMIT=${PHP_MEMORY_LIMIT:-1G} | ||||||
|  |       - FPM_MAX_CHILDREN=${FPM_MAX_CHILDREN:-131} | ||||||
|  |       - FPM_START_SERVERS=${FPM_START_SERVERS:-32} | ||||||
|  |       - FPM_MIN_SPARE_SERVERS=${FPM_MIN_SPARE_SERVERS:-32} | ||||||
|  |       - FPM_MAX_SPARE_SERVERS=${FPM_MAX_SPARE_SERVERS:-98} | ||||||
|  |       - DEFAULT_QUOTA | ||||||
|     volumes: |     volumes: | ||||||
|       - nextcloud:/var/www/html/ |       - nextcloud:/var/www/html/ | ||||||
|       - nextapps:/var/www/html/custom_apps:cached |       - nextapps:/var/www/html/custom_apps:cached | ||||||
| @ -78,12 +91,21 @@ services: | |||||||
|         failure_action: rollback |         failure_action: rollback | ||||||
|         order: start-first |         order: start-first | ||||||
|       labels: |       labels: | ||||||
|         - "coop-cloud.${STACK_NAME}.version=2.1.4+24.0.6-fpm" |         - "coop-cloud.${STACK_NAME}.version=6.0.11+28.0.10-fpm" | ||||||
|         - "backupbot.backup=true" |         - "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT:-120}" | ||||||
|         - "backupbot.backup.path=/var/www/html/config/,/var/www/html/data/,/var/www/html/custom_apps/" |         - "backupbot.backup=${ENABLE_BACKUPS:-true}" | ||||||
|  |         - "backupbot.backup.volumes.redis=false" | ||||||
|  |        #- "backupbot.backup.volumes.nextcloud=false" | ||||||
|  |  | ||||||
|  |     healthcheck: | ||||||
|  |       test: ["CMD-SHELL", 'SCRIPT_NAME=status SCRIPT_FILENAME=/var/www/html/status.php REQUEST_METHOD=GET cgi-fcgi -bind -connect 127.0.0.1:9000 | grep "installed\":true"'] | ||||||
|  |       interval: 30s | ||||||
|  |       timeout: 10s | ||||||
|  |       retries: 10 | ||||||
|  |       start_period: 15m | ||||||
|  |  | ||||||
|   cron: |   cron: | ||||||
|     image: nextcloud:24.0.6-fpm |     image: nextcloud:28.0.10-fpm | ||||||
|     volumes: |     volumes: | ||||||
|       - nextcloud:/var/www/html/ |       - nextcloud:/var/www/html/ | ||||||
|       - nextapps:/var/www/html/custom_apps:cached |       - nextapps:/var/www/html/custom_apps:cached | ||||||
| @ -93,21 +115,27 @@ services: | |||||||
|     networks: |     networks: | ||||||
|       - internal |       - internal | ||||||
|     entrypoint: /cron.sh |     entrypoint: /cron.sh | ||||||
|  |     configs: | ||||||
|  |       - source: crontab | ||||||
|  |         target: /var/spool/cron/crontabs/www-data | ||||||
|  |  | ||||||
|  |  | ||||||
|   cache: |   cache: | ||||||
|     image: redis:7.0.5-alpine |     image: redis:7.4.0-alpine | ||||||
|     networks: |     networks: | ||||||
|       - internal |       - internal | ||||||
|     volumes: |     volumes: | ||||||
|       - "redis:/data" |       - "redis:/data" | ||||||
|  |     healthcheck: | ||||||
|  |       test: ["CMD", "redis-cli", "ping"] | ||||||
|  |       interval: 3s | ||||||
|  |       timeout: 5s | ||||||
|  |       retries: 20 | ||||||
|  |  | ||||||
| secrets: | secrets: | ||||||
|   db_root_password: |  | ||||||
|     external: true |  | ||||||
|     name: ${STACK_NAME}_db_root_password_${SECRET_DB_ROOT_PASSWORD_VERSION} |  | ||||||
|   db_password: |   db_password: | ||||||
|     external: true |     external: true | ||||||
|     name: ${STACK_NAME}_db_password_${SECRET_DB_ROOT_PASSWORD_VERSION} |     name: ${STACK_NAME}_db_password_${SECRET_DB_PASSWORD_VERSION} | ||||||
|   admin_password: |   admin_password: | ||||||
|     external: true |     external: true | ||||||
|     name: ${STACK_NAME}_admin_password_${SECRET_ADMIN_PASSWORD_VERSION} |     name: ${STACK_NAME}_admin_password_${SECRET_ADMIN_PASSWORD_VERSION} | ||||||
| @ -128,10 +156,14 @@ configs: | |||||||
|   fpm_tune: |   fpm_tune: | ||||||
|     name: ${STACK_NAME}_fpm_tune_${FPM_TUNE_VERSION} |     name: ${STACK_NAME}_fpm_tune_${FPM_TUNE_VERSION} | ||||||
|     file: fpm-tune.ini |     file: fpm-tune.ini | ||||||
|  |     template_driver: golang | ||||||
|   entrypoint: |   entrypoint: | ||||||
|     name: ${STACK_NAME}_entrypoint_${ENTRYPOINT_VERSION} |     name: ${STACK_NAME}_entrypoint_${ENTRYPOINT_VERSION} | ||||||
|     file: entrypoint.sh.tmpl |     file: entrypoint.sh.tmpl | ||||||
|     template_driver: golang |     template_driver: golang | ||||||
|  |   crontab: | ||||||
|  |     name: ${STACK_NAME}_crontab_${CRONTAB_VERSION} | ||||||
|  |     file: crontab | ||||||
|  |  | ||||||
| networks: | networks: | ||||||
|   proxy: |   proxy: | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								crontab
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								crontab
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | */5 * * * * php -d memory_limit=1G -f /var/www/html/cron.php | ||||||
| @ -1,5 +1,30 @@ | |||||||
| #!/bin/bash | #!/bin/bash | ||||||
|  |  | ||||||
|  | set -eu | ||||||
|  |  | ||||||
|  | file_env() { | ||||||
|  |   local var="$1" | ||||||
|  |   local fileVar="${var}_FILE" | ||||||
|  |   local def="${2:-}" | ||||||
|  |  | ||||||
|  |   if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then | ||||||
|  |     echo >&2 "error: both $var and $fileVar are set (but are exclusive)" | ||||||
|  |     exit 1 | ||||||
|  |   fi | ||||||
|  |  | ||||||
|  |   local val="$def" | ||||||
|  |   if [ "${!var:-}" ]; then | ||||||
|  |     val="${!var}" | ||||||
|  |   elif [ "${!fileVar:-}" ]; then | ||||||
|  |     val="$(< "${!fileVar}")" | ||||||
|  |   fi | ||||||
|  |  | ||||||
|  |   export "$var"="$val" | ||||||
|  |   unset "$fileVar" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | file_env "SMTP_PASSWORD" | ||||||
|  |  | ||||||
| echo "Giving the db container some time to come up"; sleep 20 | echo "Giving the db container some time to come up"; sleep 20 | ||||||
| # see this issue with postgres db https://github.com/nextcloud/docker/issues/1204 | # see this issue with postgres db https://github.com/nextcloud/docker/issues/1204 | ||||||
|  |  | ||||||
| @ -9,4 +34,8 @@ if ! [[ $(grep {{ env "X_FRAME_OPTIONS_ALLOW_FROM" }} lib/public/AppFramework/Ht | |||||||
| fi | fi | ||||||
| {{ end }} | {{ end }} | ||||||
|  |  | ||||||
|  | # Required for healthcheck | ||||||
|  | which cgi-fcgi > /dev/null || (apt-get update && apt-get install -y libfcgi-bin) | ||||||
|  |  | ||||||
|  |  | ||||||
| /entrypoint.sh php-fpm | /entrypoint.sh php-fpm | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| pm = dynamic | pm = dynamic | ||||||
| pm.max_children = 131 | pm.max_children = {{ env "FPM_MAX_CHILDREN" }} | ||||||
| pm.start_servers = 32 | pm.start_servers = {{ env "FPM_START_SERVERS" }} | ||||||
| pm.min_spare_servers = 32 | pm.min_spare_servers = {{ env "FPM_MIN_SPARE_SERVERS" }} | ||||||
| pm.max_spare_servers = 98 | pm.max_spare_servers = {{ env "FPM_MAX_SPARE_SERVERS" }} | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ key_buffer_size                = 16M | |||||||
| innodb_log_file_size           = 256M | innodb_log_file_size           = 256M | ||||||
| long_query_time                = 1 | long_query_time                = 1 | ||||||
| max_allowed_packet             = 256M | max_allowed_packet             = 256M | ||||||
| max_connections                = 100 | max_connections                = {{ env "MAX_DB_CONNECTIONS" }} | ||||||
| max_heap_table_size            = 64M | max_heap_table_size            = 64M | ||||||
| max_user_connections           = 0 | max_user_connections           = 0 | ||||||
| myisam_recover_options         = BACKUP | myisam_recover_options         = BACKUP | ||||||
|  | |||||||
| @ -11,6 +11,10 @@ events { | |||||||
|  |  | ||||||
| http { | http { | ||||||
|     include       /etc/nginx/mime.types; |     include       /etc/nginx/mime.types; | ||||||
|  |     # See https://github.com/nextcloud/forms/issues/1838#issuecomment-1860497200 | ||||||
|  |     types { | ||||||
|  |         application/javascript js mjs; | ||||||
|  |     } | ||||||
|     default_type  application/octet-stream; |     default_type  application/octet-stream; | ||||||
|  |  | ||||||
|     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ' |     log_format  main  '$remote_addr - $remote_user [$time_local] "$request" ' | ||||||
| @ -59,12 +63,12 @@ http { | |||||||
|         #pagespeed off; |         #pagespeed off; | ||||||
|  |  | ||||||
|         # HTTP response headers borrowed from Nextcloud `.htaccess` |         # HTTP response headers borrowed from Nextcloud `.htaccess` | ||||||
|         add_header Referrer-Policy                      "no-referrer"   always; |         add_header Referrer-Policy                      "no-referrer"       always; | ||||||
|         add_header X-Content-Type-Options               "nosniff"       always; |         add_header X-Content-Type-Options               "nosniff"           always; | ||||||
|         add_header X-Download-Options                   "noopen"        always; |         add_header X-Download-Options                   "noopen"            always; | ||||||
|         add_header X-Permitted-Cross-Domain-Policies    "none"          always; |         add_header X-Permitted-Cross-Domain-Policies    "none"              always; | ||||||
|         add_header X-Robots-Tag                         "none"          always; |         add_header X-Robots-Tag                         "noindex, nofollow" always; | ||||||
|         add_header X-XSS-Protection                     "1; mode=block" always; |         add_header X-XSS-Protection                     "1; mode=block"     always; | ||||||
|  |  | ||||||
|         {{ if eq (env "X_FRAME_OPTIONS_ENABLED") "1" }} |         {{ if eq (env "X_FRAME_OPTIONS_ENABLED") "1" }} | ||||||
|         add_header Content-Security-Policy              "frame-ancestors {{ env "X_FRAME_OPTIONS_ALLOW_FROM" }} {{ env "DOMAIN" }}"; |         add_header Content-Security-Policy              "frame-ancestors {{ env "X_FRAME_OPTIONS_ALLOW_FROM" }} {{ env "DOMAIN" }}"; | ||||||
| @ -132,6 +136,9 @@ http { | |||||||
|         # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php` |         # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php` | ||||||
|         # to the URI, resulting in a HTTP 500 error response. |         # to the URI, resulting in a HTTP 500 error response. | ||||||
|         location ~ \.php(?:$|/) { |         location ~ \.php(?:$|/) { | ||||||
|  |             # Required for legacy support | ||||||
|  |             rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri; | ||||||
|  |  | ||||||
|             fastcgi_split_path_info ^(.+?\.php)(/.*)$; |             fastcgi_split_path_info ^(.+?\.php)(/.*)$; | ||||||
|             set $path_info $fastcgi_path_info; |             set $path_info $fastcgi_path_info; | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										27
									
								
								pg_backup.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								pg_backup.sh
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | |||||||
|  | #!/bin/bash | ||||||
|  |  | ||||||
|  | set -e | ||||||
|  |  | ||||||
|  | BACKUP_FILE='/var/lib/postgresql/data/backup.sql' | ||||||
|  |  | ||||||
|  | function backup { | ||||||
|  |   export PGPASSWORD=$(cat /run/secrets/db_password) | ||||||
|  |   pg_dump -U ${POSTGRES_USER} ${POSTGRES_DB} > $BACKUP_FILE | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function restore { | ||||||
|  |     cd /var/lib/postgresql/data/ | ||||||
|  |     # Don't allow any other connections than local | ||||||
|  |     cp pg_hba.conf pg_hba.conf.bak | ||||||
|  |     echo "local all all trust" > pg_hba.conf | ||||||
|  |     su postgres -c 'pg_ctl reload' | ||||||
|  |     # Recreate Database | ||||||
|  |     psql -U ${POSTGRES_USER} -d postgres -c "DROP DATABASE ${POSTGRES_DB} WITH (FORCE);"  | ||||||
|  |     createdb -U ${POSTGRES_USER} ${POSTGRES_DB} | ||||||
|  |     psql -U ${POSTGRES_USER} -d ${POSTGRES_DB} -1 -f $BACKUP_FILE | ||||||
|  |     # Restore allowed connections | ||||||
|  |     cat pg_hba.conf.bak > pg_hba.conf | ||||||
|  |     su postgres -c 'pg_ctl reload' | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $@ | ||||||
							
								
								
									
										57
									
								
								release/3.1.0+25.0.1-fpm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								release/3.1.0+25.0.1-fpm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | |||||||
|  |  | ||||||
|  | ## FPM Tune | ||||||
|  |  | ||||||
|  | The fpm-tune.ini settings are now configurable by `.env`. Please add this to your servers configs: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | # fpm-tune, see: https://spot13.com/pmcalculator/ | ||||||
|  | FPM_MAX_CHILDREN=131 | ||||||
|  | FPM_START_SERVERS=32 | ||||||
|  | FPM_MIN_SPARE_SERVERS=32 | ||||||
|  | FPM_MAX_SPARE_SERVERS=98 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## SMTP | ||||||
|  |  | ||||||
|  | Add SMTP Config to your .env file: | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | # COMPOSE_FILE="$COMPOSE_FILE:compose.smtp.yml" | ||||||
|  | # See https://github.com/nextcloud/docker#auto-configuration-via-environment-variables for default values | ||||||
|  | # SMTP_AUTHTYPE= | ||||||
|  | # SMTP_HOST= | ||||||
|  | # SMTP_SECURE= | ||||||
|  | # SMTP_NAME= | ||||||
|  | # SMTP_PORT= | ||||||
|  | # MAIL_FROM_ADDRESS= | ||||||
|  | # MAIL_DOMAIN= | ||||||
|  | # SECRET_SMTP_PASSWORD_VERSION=v1 | ||||||
|  | abra app secret insert example.com smtp_password v1 example_password | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ## Post Deploy Commands | ||||||
|  |  | ||||||
|  | Some Apps can also be managed with abra app cmd! | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | # COMPOSE_FILE="$COMPOSE_FILE:compose.apps.yml" | ||||||
|  | # APPS="calendar sociallogin onlyoffice" | ||||||
|  | abra app cmd example.com app install_apps | ||||||
|  | # ONLYOFFICE_URL=https://onlyoffice.example.com | ||||||
|  | # SECRET_ONLYOFFICE_JWT_VERSION=v1 | ||||||
|  | abra app secret insert example.com onlyoffice_jwt v1 example_password | ||||||
|  | abra app cmd example.com app install_onlyoffice | ||||||
|  | # BBB_URL=https://talk.example.org/bigbluebutton/ # trailing slash! | ||||||
|  | # SECRET_BBB_SECRET_VERSION=v1 | ||||||
|  | abra app secret insert example.com bbb_secret v1 example_password | ||||||
|  | abra app cmd example.com app install_bbb | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Set Quota | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | # DEFAULT_QUOTA="10 GB" | ||||||
|  | abra app cmd example.com app set_default_quota | ||||||
|  | ``` | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								release/3.2.0+25.0.4-fpm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								release/3.2.0+25.0.4-fpm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | |||||||
|  | If the authentik configuration should be handled by abra add the following to the env: | ||||||
|  |  | ||||||
|  |     COMPOSE_FILE="$COMPOSE_FILE:compose.authentik.yml" | ||||||
|  |     AUTHENTIK_USER_PREFIX=authentik | ||||||
|  |     AUTHENTIK_DOMAIN=authentik.example.com | ||||||
|  |     AUTHENTIK_SECRET_NAME=authentik_example_com_nextcloud_secret_v1  # the same as in authentik | ||||||
|  |     AUTHENTIK_ID_NAME=authentik_example_com_nextcloud_id_v1  # the same as in authentik | ||||||
|  |  | ||||||
|  | And run: | ||||||
|  |  | ||||||
|  |     abra app cmd <app-name> app set_authentik | ||||||
							
								
								
									
										1
									
								
								release/5.0.1+27.0.1-fpm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								release/5.0.1+27.0.1-fpm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | The authentik secrets need to be inserted again, as nextcloud is not sharing the secret with authentik any more. | ||||||
							
								
								
									
										1
									
								
								release/8.0.0+29.0.1-fpm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								release/8.0.0+29.0.1-fpm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | BREAKING CHANGE: compose.apps.yml is now split for bbb and onlyoffice, configs must be updated | ||||||
							
								
								
									
										1
									
								
								release/9.1.0+29.0.5-fpm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								release/9.1.0+29.0.5-fpm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | Added automated customization options. Config needs to be updated to be able to use it. | ||||||
		Reference in New Issue
	
	Block a user