From ad703dbee4696ac5e3180b1f94095160cccd72c6 Mon Sep 17 00:00:00 2001 From: Johanna Dorothea Reichmann Date: Wed, 13 Oct 2021 15:46:46 +0200 Subject: [PATCH] feat(nextcloud): add role for deploying nextcloud with fpm --- roles/nextcloud/defaults/main.yml | 58 ++++++++++ roles/nextcloud/handlers/main.yml | 13 +++ roles/nextcloud/tasks/main.yml | 109 ++++++++++++++++++ .../templates/nextcloud-fpm-opcache.ini.j2 | 14 +++ .../nextcloud/templates/nextcloud-fpm.ini.j2 | 14 +++ roles/nextcloud/templates/nextcloud-group.j2 | 48 ++++++++ roles/nextcloud/templates/nextcloud-passwd.j2 | 29 +++++ .../systemd-nextcloud-cron.service.j2 | 15 +++ .../templates/systemd-nextcloud-cron.timer.j2 | 10 ++ roles/nextcloud/vars/main.yml | 24 ++++ 10 files changed, 334 insertions(+) create mode 100644 roles/nextcloud/defaults/main.yml create mode 100644 roles/nextcloud/handlers/main.yml create mode 100644 roles/nextcloud/tasks/main.yml create mode 100644 roles/nextcloud/templates/nextcloud-fpm-opcache.ini.j2 create mode 100644 roles/nextcloud/templates/nextcloud-fpm.ini.j2 create mode 100644 roles/nextcloud/templates/nextcloud-group.j2 create mode 100644 roles/nextcloud/templates/nextcloud-passwd.j2 create mode 100644 roles/nextcloud/templates/systemd-nextcloud-cron.service.j2 create mode 100644 roles/nextcloud/templates/systemd-nextcloud-cron.timer.j2 create mode 100644 roles/nextcloud/vars/main.yml diff --git a/roles/nextcloud/defaults/main.yml b/roles/nextcloud/defaults/main.yml new file mode 100644 index 0000000..5961f2c --- /dev/null +++ b/roles/nextcloud/defaults/main.yml @@ -0,0 +1,58 @@ +--- + +nextcloud_version: 22.2.0 +nextcloud_user: nextcloud +nextcloud_basepath: /opt/nextcloud +nextcloud_config_path: "{{ nextcloud_basepath }}/config" +# Where data from nextcloud like apps etc are persisted +nextcloud_data_path: "{{ nextcloud_basepath }}/data" +# Where user data like media, documents etc are persisted +nextcloud_storage_path: "{{ nextcloud_basepath }}/storage" +nextcloud_fpm_config_path: "{{ nextcloud_basepath }}/fpm-config" + +nextcloud_database_type: sqlite +nextcloud_database_name: nextcloud +nextcloud_database_user: nextcloud +nextcloud_database_pass: ~ +nextcloud_database_host: localhost + +nextcloud_container_name: nextcloud +nextcloud_container_image: docker.io/library/nextcloud +nextcloud_container_image_variant: "-fpm-alpine" +nextcloud_container_image_ref: "{{ nextcloud_container_name }}:{{ nextcloud_version }}{{ nextcloud_container_image_variant }}" +nextcloud_container_image_force_source: false +nextcloud_container_restart_policy: "unless-stopped" + +# in defaults so it can be unset if needed +nextcloud_container_base_volumes: + - "{{ nextcloud_config_path }}:/var/www/html/config:z" + - "{{ nextcloud_storage_path }}:/var/www/html/data:z" + - "{{ nextcloud_data_path }}:/var/www/html:z" + - "{{ nextcloud_fpm_config_path }}/opcache.ini:/usr/local/etc/php/conf.d/opcache-recommended.ini:z" + - "{{ nextcloud_fpm_config_path }}/fpm.ini:/usr/local/etc/php-fpm.d/www.conf:z" + - "{{ nextcloud_basepath }}/nextcloud-passwd:/etc/passwd:z" + - "{{ nextcloud_basepath }}/nextcloud-group:/etc/group:z" +nextcloud_container_extra_volumes: [] +nextcloud_container_extra_labels: {} +nextcloud_container_extra_environment: {} + +nextcloud_container_networks: ~ +nextcloud_container_purge_other_networks: true + +nextcloud_paths: + - path: "{{ nextcloud_config_path }}" + mode: "0755" + owner: "{{ nextcloud_user_info.uid|default(nextcloud_user) }}" + group: "root" + - path: "{{ nextcloud_data_path }}" + mode: "0755" + owner: "{{ nextcloud_user_info.uid|default(nextcloud_user) }}" + group: "{{ nextcloud_user_info.uid|default(nextcloud_user) }}" + - path: "{{ nextcloud_fpm_config_path }}" + mode: "0750" + owner: root + group: root + - path: "{{ nextcloud_storage_path }}" + mode: "0770" + owner: "{{ nextcloud_user_info.uid|default(nextcloud_user) }}" + group: "root" diff --git a/roles/nextcloud/handlers/main.yml b/roles/nextcloud/handlers/main.yml new file mode 100644 index 0000000..4e06e84 --- /dev/null +++ b/roles/nextcloud/handlers/main.yml @@ -0,0 +1,13 @@ +--- + +- name: reload-systemd + systemd: + daemon_reload: yes + +- name: reload-nextcloud + docker_container: + name: "{{ nextcloud_container_name }}" + state: started + restart: yes + force_kill: yes + kill_signal: HUP diff --git a/roles/nextcloud/tasks/main.yml b/roles/nextcloud/tasks/main.yml new file mode 100644 index 0000000..ce8423c --- /dev/null +++ b/roles/nextcloud/tasks/main.yml @@ -0,0 +1,109 @@ +--- + +- name: Create nextcloud user + user: + name: "{{ nextcloud_user }}" + state: present + system: yes + register: nextcloud_user_info + +- name: Ensure nextcloud directories exist and have correct permissions + file: + path: "{{ item.path }}" + state: directory + mode: "{{ item.mode }}" + owner: "{{ item.owner }}" + group: "{{ item.group }}" + loop: "{{ nextcloud_paths }}" + +- name: Ensure docker container for nextcloud is pulled + docker_image: + name: "{{ nextcloud_container_image_ref }}" + state: present + source: pull + force_source: "{{ nextcloud_container_image_force_source }}" + +- name: Template OpCache configuration + template: + src: nextcloud-fpm-opcache.ini.j2 + dest: "{{ nextcloud_fpm_config_path }}/opcache.ini" + mode: "0640" + owner: "root" + group: "root" + notify: + - reload-nextcloud + +- name: Template PHP FPM configuration + template: + src: nextcloud-fpm.ini.j2 + dest: "{{ nextcloud_fpm_config_path }}/fpm.ini" + mode: "0640" + owner: "root" + group: "root" + notify: + - reload-nextcloud + +- name: Template modified /etc/passwd for nextcloud container + template: + src: nextcloud-passwd.j2 + dest: "{{ nextcloud_basepath }}/nextcloud-passwd" + mode: "0640" + owner: "root" + group: "root" + notify: + - reload-nextcloud + +- name: Template modified /etc/passwd for nextcloud container + template: + src: nextcloud-group.j2 + dest: "{{ nextcloud_basepath }}/nextcloud-group" + mode: "0640" + owner: "root" + group: "root" + notify: + - reload-nextcloud + +- name: Template systemd service for nextcloud's cron job + template: + src: systemd-nextcloud-cron.service.j2 + dest: /etc/systemd/system/nextcloud-cron.service + mode: "0640" + owner: root + group: root + notify: + - reload-systemd + +- name: Template timer for nextcloud's cron job + template: + src: systemd-nextcloud-cron.timer.j2 + dest: /etc/systemd/system/nextcloud-cron.timer + mode: "0640" + owner: root + group: root + notify: + - reload-systemd + +- meta: flush_handlers + +- name: Enable systemd timer for nextcloud cron + systemd: + name: "nextcloud-cron.timer" + enabled: yes + +- name: Ensure systemd timer for nextcloud cron is started + systemd: + name: "nextcloud-cron.timer" + state: started + + +- name: Ensure docker container for nextcloud is running + docker_container: + name: "{{ nextcloud_container_name }}" + image: "{{ nextcloud_container_image_ref }}" + volumes: "{{ nextcloud_container_volumes }}" + labels: "{{ nextcloud_container_labels }}" + env: "{{ nextcloud_container_env }}" + networks: "{{ nextcloud_container_networks | default(omit, true) }}" + purge_networks: "{{ nextcloud_container_purge_other_networks }}" + restart_policy: "{{ nextcloud_container_restart_policy }}" + state: started diff --git a/roles/nextcloud/templates/nextcloud-fpm-opcache.ini.j2 b/roles/nextcloud/templates/nextcloud-fpm-opcache.ini.j2 new file mode 100644 index 0000000..7eea796 --- /dev/null +++ b/roles/nextcloud/templates/nextcloud-fpm-opcache.ini.j2 @@ -0,0 +1,14 @@ +opcache.enable=1 +opcache.interned_strings_buffer=32 +; next prime in the set which is suitable for large installations +; default for this setting is 10000 which picks the prime 7963, +; but default installation of nextcloud has already ~9k php files +; see https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.max-accelerated-files +opcache.max_accelerated_files=32531 +opcache.memory_consumption=256 +; deconstructor optimizations +opcache.fast_shutdown=1 +;opcache.save_comments=1 +; not used if validate_timestamps=0 +;opcache.revalidate_freq=1 +opcache.validate_timestamps=0 diff --git a/roles/nextcloud/templates/nextcloud-fpm.ini.j2 b/roles/nextcloud/templates/nextcloud-fpm.ini.j2 new file mode 100644 index 0000000..7318c4b --- /dev/null +++ b/roles/nextcloud/templates/nextcloud-fpm.ini.j2 @@ -0,0 +1,14 @@ +[www] + +user = www-data +group = www-data + +listen = 127.0.0.1:9000 + +pm = dynamic +pm.max_children = 64 +pm.start_servers = 32 +pm.min_spare_servers = 24 +pm.max_spare_servers = 48 + +;pm.max_requests=500 diff --git a/roles/nextcloud/templates/nextcloud-group.j2 b/roles/nextcloud/templates/nextcloud-group.j2 new file mode 100644 index 0000000..f9a94db --- /dev/null +++ b/roles/nextcloud/templates/nextcloud-group.j2 @@ -0,0 +1,48 @@ +root:x:0:root +bin:x:1:root,bin,daemon +daemon:x:2:root,bin,daemon +sys:x:3:root,bin,adm +adm:x:4:root,adm,daemon +tty:x:5: +disk:x:6:root,adm +lp:x:7:lp +mem:x:8: +kmem:x:9: +wheel:x:10:root +floppy:x:11:root +mail:x:12:mail +news:x:13:news +uucp:x:14:uucp +man:x:15:man +cron:x:16:cron +console:x:17: +audio:x:18: +cdrom:x:19: +dialout:x:20:root +ftp:x:21: +sshd:x:22: +input:x:23: +at:x:25:at +tape:x:26:root +video:x:27:root +netdev:x:28: +readproc:x:30: +squid:x:31:squid +xfs:x:33:xfs +kvm:x:34:kvm +games:x:35: +shadow:x:42: +cdrw:x:80: +www-data:x:{{ nextcloud_user_info.group }}:www-data +usb:x:85: +vpopmail:x:89: +users:x:100:games +ntp:x:123: +nofiles:x:200: +smmsp:x:209:smmsp +locate:x:245: +abuild:x:300: +utmp:x:406:utmp +ping:x:999: +nogroup:x:65533: +nobody:x:65534: diff --git a/roles/nextcloud/templates/nextcloud-passwd.j2 b/roles/nextcloud/templates/nextcloud-passwd.j2 new file mode 100644 index 0000000..6744896 --- /dev/null +++ b/roles/nextcloud/templates/nextcloud-passwd.j2 @@ -0,0 +1,29 @@ +root:x:0:0:root:/root:/bin/ash +bin:x:1:1:bin:/bin:/sbin/nologin +daemon:x:2:2:daemon:/sbin:/sbin/nologin +adm:x:3:4:adm:/var/adm:/sbin/nologin +lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin +sync:x:5:0:sync:/sbin:/bin/sync +shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown +halt:x:7:0:halt:/sbin:/sbin/halt +mail:x:8:12:mail:/var/mail:/sbin/nologin +news:x:9:13:news:/usr/lib/news:/sbin/nologin +uucp:x:10:14:uucp:/var/spool/uucppublic:/sbin/nologin +operator:x:11:0:operator:/root:/sbin/nologin +man:x:13:15:man:/usr/man:/sbin/nologin +postmaster:x:14:12:postmaster:/var/mail:/sbin/nologin +cron:x:16:16:cron:/var/spool/cron:/sbin/nologin +ftp:x:21:21::/var/lib/ftp:/sbin/nologin +sshd:x:22:22:sshd:/dev/null:/sbin/nologin +at:x:25:25:at:/var/spool/cron/atjobs:/sbin/nologin +squid:x:31:31:Squid:/var/cache/squid:/sbin/nologin +xfs:x:33:33:X Font Server:/etc/X11/fs:/sbin/nologin +games:x:35:35:games:/usr/games:/sbin/nologin +cyrus:x:85:12::/usr/cyrus:/sbin/nologin +vpopmail:x:89:89::/var/vpopmail:/sbin/nologin +ntp:x:123:123:NTP:/var/empty:/sbin/nologin +smmsp:x:209:209:smmsp:/var/spool/mqueue:/sbin/nologin +guest:x:405:100:guest:/dev/null:/sbin/nologin +nobody:x:65534:65534:nobody:/:/sbin/nologin +www-data:x:{{ nextcloud_user_info.uid }}:{{ nextcloud_user_info.group }}:Linux User,,,:/home/www-data:/sbin/nologin +utmp:x:100:406:utmp:/home/utmp:/bin/false diff --git a/roles/nextcloud/templates/systemd-nextcloud-cron.service.j2 b/roles/nextcloud/templates/systemd-nextcloud-cron.service.j2 new file mode 100644 index 0000000..4eb6e77 --- /dev/null +++ b/roles/nextcloud/templates/systemd-nextcloud-cron.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description=Nextcloud cron.php job +Requires=docker.service +After=docker.service + +[Service] +Type=oneshot +User=root +WorkingDirectory={{ nextcloud_basepath }} +SyslogIdentifier={{ nextcloud_user }} + +ExecStart=/usr/bin/docker exec -t --user={{ nextcloud_user_info.uid }} {{ nextcloud_container_name }} /usr/local/bin/php -f /var/www/html/cron.php + +[Install] +WantedBy=multi-user.target diff --git a/roles/nextcloud/templates/systemd-nextcloud-cron.timer.j2 b/roles/nextcloud/templates/systemd-nextcloud-cron.timer.j2 new file mode 100644 index 0000000..eea545b --- /dev/null +++ b/roles/nextcloud/templates/systemd-nextcloud-cron.timer.j2 @@ -0,0 +1,10 @@ +[Unit] +Description=Run Nextcloud cron.php every 5min + +[Timer] +OnBootSec=5min +OnUnitActiveSec=5min +Unit=nextcloud-cron.service + +[Install] +WantedBy=timers.target diff --git a/roles/nextcloud/vars/main.yml b/roles/nextcloud/vars/main.yml new file mode 100644 index 0000000..8c5181c --- /dev/null +++ b/roles/nextcloud/vars/main.yml @@ -0,0 +1,24 @@ +--- + +nextcloud_container_volumes: "{{ nextcloud_container_base_volumes + nextcloud_container_extra_volumes }}" +nextcloud_container_env: "{{ nextcloud_container_base_environment | combine(nextcloud_container_extra_environment) }}" + +nextcloud_container_base_labels: + version: "{{ nextcloud_version }}" +nextcloud_container_labels: "{{ nextcloud_container_base_labels | combine(nextcloud_container_extra_labels) }}" + +nextcloud_container_base_environment: "{{ nextcloud_container_base_environment_yaml | from_yaml }}" +nextcloud_container_base_environment_yaml: |+2 + {% if nextcloud_database_type == 'postgres' %} + POSTGRES_DB: "{{ nextcloud_database_name }}" + POSTGRES_USER: "{{ nextcloud_database_user }}" + POSTGRES_PASSWORD: "{{ nextcloud_database_pass }}" + POSTGRES_HOST: "{{ nextcloud_database_host }}" + {% elif nextcloud_database_type in ['mysql', 'mariadb'] %} + MYSQL_DATABASE: "{{ nextcloud_database_name }}" + MYSQL_USER: "{{ nextcloud_database_user }}" + MYSQL_PASSWORD: "{{ nextcloud_database_pass }}" + MYSQL_HOST: "{{ nextcloud_database_host }}" + {% elif nextcloud_database_type == 'sqlite' %} + SQLITE_DATABASE: "{{ nextcloud_database_name }}" + {% endif %}