Getting started
Database setup
It is recommended that you install a database server. You can install one on the same host as ownCloud or choose a different host:
[debops_service_mariadb_server]
hostname
In case you chose a different host, you will need to specify which of your
database servers the ownCloud instance should use by specifying the database
server host as owncloud__database_server
.
If you are upgrading an existing Nextcloud installation, you should follow Enabling MySQL 4-byte support and then set the following in your inventory of the database server:
mariadb_server__options:
- section: 'mysqld'
options:
## https://docs.nextcloud.com/server/16/admin_manual/configuration_database/mysql_4byte_support.html
'innodb_large_prefix': 'on'
'innodb_file_format': 'barracuda'
'innodb_file_per_table': 'true'
For database clean installs this is not required anymore because MySQL 4-byte is enabled by default by the debops.mariadb_server Ansible role.
In memory caching
Nextcloud and ownCloud recommend to setup Redis for caching. You can install a Redis server on the same host as ownCloud or choose a different host:
[debops_service_redis_server]
hostname
This role will use a Redis server automatically when it is managed by debops.redis_server Ansible role.
In case you chose a different host, you will need to specify which of your
Redis servers the ownCloud instance should use by setting the Redis
server host as owncloud__redis_host
and setting
owncloud__redis_enabled
to True
.
Additionally, you will need to set the owncloud__redis_password
.
Refer to debops.redis_server documentation for details.
PHP configuration
Starting with Nextcloud 16, a setup warning is emitted in the Nextcloud admin web interface "The PHP memory limit is below the recommended value of 512MB.". The role already configures Nginx to pass an increased memory_limit to PHP. However, this might not be picked up in some cases. When this happens you might want to set the following in your inventory:
php__ini_memory_limit: '512M'
Choosing a Webserver
Supported webservers:
This role started out using Nginx as Webserver. However, ownCloud don’t officially support Nginx. Support for the Apache HTTP Server has been added to the role using debops.apache as role dependency. NextCloud lists Nginx as supported but still recommends Apache.
The current default Webserver is Nginx. Because despite the fact that only Apache is officially supported/recommended, Nginx has been successfully used with this role for some time now. If you have trouble then this would be a good time to try to run it with Apache.
The ownCloud System Requirements don’t use PHP-FPM in their default configuration. You can set the following in your inventory to not install FPM on the ownCloud host:
php__server_api_packages:
- 'cli'
Switching Webservers
Assuming you where using one Webserver before on a host but want to switch then
follow the steps in Choosing a Webserver and additionally add the host to
the debops_service_${not_chosen_webserver}
group of the opposite webserver
you chose for ownCloud.
Now add this:
${not_chosen_webserver}__deploy_state: 'absent'
to your inventory.
Note: Replace the ${not_chosen_webserver}
placeholders.
Then run the site playbook or just the playbook of the unwanted webserver
followed by the debops.owncloud playbook.
This will render ${not_chosen_webserver}
the unwanted webserver harmless
and setup the chosen webserver.
Upgrade
All upgrades be it major or patch need to be done manually for now. The role does not automate this. The way to support Nextcloud auto upgrades would be to use the Nextcloud Docker image because it includes an application upgrade script. The role could be extended to support using the Docker image if needed.
Upgrade the application using the built-in upgrade feature, then rerun the service playbook for this role to ensure the matching settings are applied.
If the application complains under /settings/admin/overview
then you might need to run:
occ upgrade; occ db:add-missing-indice; occ db:add-missing-columns; occ db:convert-filecache-bigint; occ db:add-missing-primary-keys && occ maintenance:mode --off
It also does not hurt to run that by default.
Expected warnings
Nextcloud and ownCloud have a self check under "Administration" -> "Overview". Some warnings are expected to be shown.
Nextcloud 21 and newer: Module
php-imagick
in this instance has no SVG support. For better compatibility it is recommended to install it.Background: SVG support is disabled for security reasons by default. Lets keep it at that for now until we can better assess the situation.
Example inventory
To setup ownCloud on a given host it should be included in the
[debops_service_owncloud]
Ansible inventory group:
[debops_service_owncloud]
hostname
Note that the debops_service_owncloud
group uses the default webserver,
refer to Choosing a Webserver.
Recommended settings
owncloud__config:
# https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/config_sample_php_parameters.html#user-experience
default_phone_region: 'DE'
Ansible facts
The role gathers various Ansible facts about ownCloud for internal use or use by other roles or playbooks.
One of the sources for the facts is the /var/www/owncloud/config/config.php
file which has 0640
as default permissions.
The remote user who gathers the facts should be able to read this file.
Note that facts gathering does not happen with elevated privileges by default.
One way to achieve this is by making your configuration management user member
of the www-data
group by including the following in your inventory:
bootstrap__admin_groups: [ 'admins', 'staff', 'adm', 'sudo', 'www-data' ]
The following Ansible facts are available:
{
"auto_security_updates_enabled": false,
"datadirectory": "/var/www/owncloud/data",
"enabled": true,
"instanceid": "xxxxxxxxxxxx",
"maintenance": false,
"release": "9.0",
"theme": "debops",
"trusted_domains": [
"cloud.example.org"
],
"updatechecker": false,
"variant": "owncloud",
"version": "9.0.7.1",
"webserver": "nginx"
}
Note that the role uses Ansible facts gathered from the config.php
file internally and might not work as expected when those facts can not be gathered.
The following can happen when the configuration management user has no access
to the config.php
file:
Certain occ commands are not available in maintenance mode. The role normally filters those commands out if it detects that ownCloud is in maintenance mode. Maintenance mode is assumed to be off if it can not be detected. If it is on, role execution will stop when one of those occ commands is encountered.
and only the following facts will be available in this case:
{
"auto_security_updates_enabled": true,
"enabled": true,
"variant": "owncloud",
"webserver": "nginx"
}
Example playbook
The following playbooks are used in DebOps. If you are using these role without DebOps you might need to adapt them to make them work in your setup.
Ansible playbook that uses the debops.owncloud
role together with debops.nginx:
---
- name: Install and manage ownCloud instances with Nginx as webserver
collections: [ 'debops.debops', 'debops.roles01',
'debops.roles02', 'debops.roles03' ]
hosts: [ 'debops_service_owncloud', 'debops_service_owncloud_nginx' ]
become: True
environment: '{{ inventory__environment | d({})
| combine(inventory__group_environment | d({}))
| combine(inventory__host_environment | d({})) }}'
pre_tasks:
- name: Apply keyring configuration for php environment
ansible.builtin.import_role:
name: 'keyring'
vars:
keyring__dependent_apt_keys:
- '{{ php__keyring__dependent_apt_keys }}'
- '{{ mariadb__keyring__dependent_apt_keys if (owncloud__database == "mariadb") else [] }}'
- '{{ postgresql__keyring__dependent_apt_keys if (owncloud__database == "postgresql") else [] }}'
- '{{ nginx__keyring__dependent_apt_keys }}'
- '{{ owncloud__keyring__dependent_apt_keys }}'
keyring__dependent_gpg_keys:
- '{{ owncloud__keyring__dependent_gpg_keys }}'
tags: [ 'role::keyring', 'skip::keyring', 'role::php',
'role::mariadb', 'role::postgresql',
'role::nginx', 'role::owncloud' ]
- name: Prepare php environment
ansible.builtin.import_role:
name: 'php'
tasks_from: 'main_env'
tags: [ 'role::php', 'role::php:env', 'role::logrotate' ]
- name: Prepare owncloud environment
ansible.builtin.import_role:
name: 'owncloud'
tasks_from: 'main_env'
tags: [ 'role::owncloud', 'role::owncloud:env', 'role::nginx' ]
roles:
- role: apt_preferences
tags: [ 'role::apt_preferences', 'skip::apt_preferences', 'role::nginx', 'role::php' ]
apt_preferences__dependent_list:
- '{{ nginx__apt_preferences__dependent_list }}'
- '{{ owncloud__apt_preferences__dependent_list }}'
- '{{ php__apt_preferences__dependent_list }}'
- role: ferm
tags: [ 'role::ferm', 'skip::ferm', 'role::nginx' ]
ferm__dependent_rules:
- '{{ nginx__ferm__dependent_rules }}'
- role: python
tags: [ 'role::python', 'skip::python', 'role::ldap', 'role::mariadb', 'role::postgresql' ]
python__dependent_packages3:
- '{{ ldap__python__dependent_packages3 }}'
- '{{ mariadb__python__dependent_packages3
if (owncloud__database == "mariadb")
else [] }}'
- '{{ postgresql__python__dependent_packages3
if (owncloud__database == "postgresql")
else [] }}'
- '{{ nginx__python__dependent_packages3 }}'
python__dependent_packages2:
- '{{ ldap__python__dependent_packages2 }}'
- '{{ mariadb__python__dependent_packages2
if (owncloud__database == "mariadb")
else [] }}'
- '{{ postgresql__python__dependent_packages2
if (owncloud__database == "postgresql")
else [] }}'
- '{{ nginx__python__dependent_packages2 }}'
- role: ldap
tags: [ 'role::ldap', 'skip::ldap' ]
ldap__dependent_tasks:
- '{{ owncloud__ldap__dependent_tasks }}'
- role: mariadb
tags: [ 'role::mariadb', 'skip::mariadb' ]
mariadb__dependent_databases: '{{ owncloud__mariadb__dependent_databases }}'
mariadb__dependent_users: '{{ owncloud__mariadb__dependent_users }}'
when: (owncloud__database == 'mariadb')
- role: postgresql
tags: [ 'role::postgresql', 'skip::postgresql' ]
postgresql__dependent_roles: '{{ owncloud__postgresql__dependent_roles }}'
postgresql__dependent_groups: '{{ owncloud__postgresql__dependent_groups }}'
postgresql__dependent_databases: '{{ owncloud__postgresql__dependent_databases }}'
when: (owncloud__database == 'postgresql')
- role: unattended_upgrades
tags: [ 'role::unattended_upgrades', 'skip::unattended_upgrades' ]
unattended_upgrades__dependent_origins: '{{ owncloud__unattended_upgrades__dependent_origins }}'
- role: php
tags: [ 'role::php', 'skip::php' ]
php__dependent_packages:
- '{{ owncloud__php__dependent_packages }}'
php__dependent_configuration:
- '{{ owncloud__php__dependent_configuration }}'
php__dependent_pools:
- '{{ owncloud__php__dependent_pools }}'
- role: cron
tags: [ 'role::cron', 'skip::cron' ]
- role: logrotate
tags: [ 'role::logrotate', 'skip::logrotate' ]
logrotate__dependent_config:
- '{{ php__logrotate__dependent_config }}'
- '{{ owncloud__logrotate__dependent_config }}'
- role: nginx
tags: [ 'role::nginx', 'skip::nginx' ]
nginx__dependent_maps:
- '{{ owncloud__nginx__dependent_maps }}'
nginx__dependent_servers:
- '{{ owncloud__nginx__dependent_servers }}'
nginx__dependent_upstreams:
- '{{ owncloud__nginx__dependent_upstreams }}'
- role: owncloud
tags: [ 'role::owncloud', 'skip::owncloud' ]
Ansible playbook that uses the debops.owncloud
role together with debops.apache:
---
- name: Install and manage ownCloud instances with Apache as webserver
collections: [ 'debops.debops', 'debops.roles01',
'debops.roles02', 'debops.roles03' ]
hosts: [ 'debops_service_owncloud_apache' ]
become: True
environment: '{{ inventory__environment | d({})
| combine(inventory__group_environment | d({}))
| combine(inventory__host_environment | d({})) }}'
pre_tasks:
- name: Apply keyring configuration for php environment
ansible.builtin.import_role:
name: 'keyring'
vars:
keyring__dependent_apt_keys:
- '{{ php__keyring__dependent_apt_keys }}'
- '{{ mariadb__keyring__dependent_apt_keys if (owncloud__database == "mariadb") else [] }}'
- '{{ postgresql__keyring__dependent_apt_keys if (owncloud__database == "postgresql") else [] }}'
- '{{ owncloud__keyring__dependent_apt_keys }}'
keyring__dependent_gpg_keys:
- '{{ owncloud__keyring__dependent_gpg_keys }}'
tags: [ 'role::keyring', 'skip::keyring', 'role::php',
'role::mariadb', 'role::postgresql', 'role::owncloud' ]
- name: Prepare php environment
ansible.builtin.import_role:
name: 'php'
tasks_from: 'main_env'
tags: [ 'role::php', 'role::php:env', 'role::logrotate' ]
- name: Prepare apache environment
ansible.builtin.import_role:
name: 'apache'
tasks_from: 'main_env'
tags: [ 'role::apache', 'role::apache:env' ]
- name: Prepare owncloud environment
ansible.builtin.import_role:
name: 'owncloud'
tasks_from: 'main_env'
tags: [ 'role::owncloud', 'role::owncloud:env' ]
roles:
- role: apt_preferences
tags: [ 'role::apt_preferences', 'skip::apt_preferences' ]
apt_preferences__dependent_list:
- '{{ owncloud__apt_preferences__dependent_list }}'
- '{{ php__apt_preferences__dependent_list }}'
- role: ferm
tags: [ 'role::ferm', 'skip::ferm' ]
ferm__dependent_rules:
- '{{ apache__ferm__dependent_rules }}'
- role: python
tags: [ 'role::python', 'skip::python', 'role::ldap', 'role::mariadb', 'role::postgresql' ]
python__dependent_packages3:
- '{{ ldap__python__dependent_packages3 }}'
- '{{ mariadb__python__dependent_packages3
if (owncloud__database == "mariadb")
else [] }}'
- '{{ postgresql__python__dependent_packages3
if (owncloud__database == "postgresql")
else [] }}'
python__dependent_packages2:
- '{{ ldap__python__dependent_packages2 }}'
- '{{ mariadb__python__dependent_packages2
if (owncloud__database == "mariadb")
else [] }}'
- '{{ postgresql__python__dependent_packages2
if (owncloud__database == "postgresql")
else [] }}'
- role: ldap
tags: [ 'role::ldap', 'skip::ldap' ]
ldap__dependent_tasks:
- '{{ owncloud__ldap__dependent_tasks }}'
- role: mariadb
tags: [ 'role::mariadb', 'skip::mariadb' ]
mariadb__dependent_users: '{{ owncloud__mariadb__dependent_users }}'
when: (owncloud__database == 'mariadb')
- role: postgresql
tags: [ 'role::postgresql', 'skip::postgresql' ]
postgresql__dependent_roles: '{{ owncloud__postgresql__dependent_roles }}'
postgresql__dependent_groups: '{{ owncloud__postgresql__dependent_groups }}'
postgresql__dependent_databases: '{{ owncloud__postgresql__dependent_databases }}'
when: (owncloud__database == 'postgresql')
- role: unattended_upgrades
tags: [ 'role::unattended_upgrades', 'skip::unattended_upgrades' ]
unattended_upgrades__dependent_origins: '{{ owncloud__unattended_upgrades__dependent_origins }}'
- role: php
tags: [ 'role::php', 'skip::php' ]
php__dependent_packages:
- '{{ owncloud__php__dependent_packages }}'
php__dependent_configuration:
- '{{ owncloud__php__dependent_configuration }}'
php__dependent_pools:
- '{{ owncloud__php__dependent_pools }}'
- role: cron
tags: [ 'role::cron', 'skip::cron' ]
- role: logrotate
tags: [ 'role::logrotate', 'skip::logrotate' ]
logrotate__dependent_config:
- '{{ php__logrotate__dependent_config }}'
- '{{ owncloud__logrotate__dependent_config }}'
- role: apache
tags: [ 'role::apache', 'skip::apache' ]
apache__dependent_snippets: '{{ owncloud__apache__dependent_snippets }}'
apache__dependent_vhosts:
- '{{ owncloud__apache__dependent_vhosts }}'
- role: owncloud
tags: [ 'role::owncloud', 'skip::owncloud' ]
These playbooks are shipped with DebOps and are also contained in this role under
docs/playbooks/
.