Skip to content

Commit

Permalink
Add 'roles/backup_nextcloud/' from commit '922a569d339f05716a69cb27b3…
Browse files Browse the repository at this point in the history
…8bcf9089f2ea25'

git-subtree-dir: roles/backup_nextcloud
git-subtree-mainline: 0783f15
git-subtree-split: 922a569
  • Loading branch information
wiktor2200 committed Apr 29, 2023
2 parents 0783f15 + 922a569 commit 7a71495
Show file tree
Hide file tree
Showing 17 changed files with 812 additions and 0 deletions.
17 changes: 17 additions & 0 deletions roles/backup_nextcloud/.github/workflows/ansible-lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
## Source: https://github.com/marketplace/actions/ansible-lint

name: Ansible Lint
on: [push, pull_request] # yamllint disable-line rule:truthy

jobs:
ansible-lint:
runs-on: ubuntu-latest

steps:
# Important: This sets up your GITHUB_WORKSPACE environment variable
- uses: actions/checkout@v3

- name: Run ansible-lint
# replace `main` with any valid ref, or tags like `v6`
uses: ansible-community/ansible-lint-action@v6
17 changes: 17 additions & 0 deletions roles/backup_nextcloud/.github/workflows/yamllint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
## Source: https://github.com/marketplace/actions/yaml-lint
name: Yaml Lint
"on":
pull_request:
push:

jobs:
yaml-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Run yaml-lint
uses: ibiqlik/action-yamllint@v3
with:
config_file: .yamllint.yml
format: github
12 changes: 12 additions & 0 deletions roles/backup_nextcloud/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
repos:
- repo: https://github.com/adrienverge/yamllint.git
rev: v1.28.0
hooks:
- id: yamllint
args: ["-c=.yamllint.yml", "."]
- repo: https://github.com/ansible-community/ansible-lint.git
rev: v6.8.0
hooks:
- id: ansible-lint
files: \.(yaml|yml)$
28 changes: 28 additions & 0 deletions roles/backup_nextcloud/.yamllint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
## Ansible Galaxy yamllint rules: https://github.com/ansible/galaxy/blob/devel/galaxy/importer/linters/yamllint.yaml
extends: default

rules:
braces: {max-spaces-inside: 1, level: error}
brackets: {max-spaces-inside: 1, level: error}
colons: {max-spaces-after: -1, level: error}
commas: {max-spaces-after: -1, level: error}
comments: disable
comments-indentation: disable
# document-start: disable
empty-lines: {max: 3, level: error}
hyphens: {level: error}
# indentation: disable
key-duplicates: enable
# line-length: disable
# new-line-at-end-of-file: disable
new-lines: {type: unix}
# trailing-spaces: disable
# truthy: disable

## Additional rules with warnings
document-start: {level: warning}
indentation: {level: warning, spaces: 2, indent-sequences: consistent}
line-length: {level: warning, max: 180}
trailing-spaces: {level: warning}
truthy: {level: warning, allowed-values: ['true', 'false']}
235 changes: 235 additions & 0 deletions roles/backup_nextcloud/LICENSE

Large diffs are not rendered by default.

139 changes: 139 additions & 0 deletions roles/backup_nextcloud/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
[![Ansible-lint status](https://github.com/aalaesar/backup_nextcloud/actions/workflows/ansible-lint.yml/badge.svg)](https://github.com/aalaesar/backup_nextcloud/actions?workflow=Ansible%20Lint)
[![YAML-lint status](https://github.com/aalaesar/backup_nextcloud/actions/workflows/yamllint.yml/badge.svg)](https://github.com/aalaesar/backup_nextcloud/actions?workflow=Yaml%20Lint)
# backup_nextcloud

An ansible role that creates a backup of a Nextcloud server. The backup is kept on the server (unless you [fetch it](#fetching-backup-from-remote-to-local-machine)).

## Requirements

The roles requires the following tools to be available on the host:
- tar
- gzip
- rsync
- a mysql or postgreSQL client if the database has to be dumped.

You'll need enough space on the target file system, depending on the size of your nextcloud server.

## Role Variables

### Locating the nextcloud server

The role has to know where the server files are, how to access it and where to store the backup.

```yaml
nextcloud_backup_target_dir: "/opt/nextcloud_backups"
nextcloud_webroot: "/opt/nextcloud"
# nextcloud_data_dir: "/var/ncdata" # optional.
nextcloud_websrv_user: "www-data" # you may need to change this to the nextcloud file owner depending of your setup and OS
```

### Adjusting the backup owner
The backup owner can be adjusted with. This may be useful when operating user is different than nextcloud's process owner.

```yaml
nextcloud_backup_owner: "www-data" # user name who will get owner on backup_target_dir and final archive
nextcloud_backup_group: "www-data" # user group who will get owner on backup_target_dir and final archive
```

### Adjusting the backup name
The backup name can be adjusted with

```yaml
nextcloud_instance_name: "nextcloud" # a human identifier for the server
nextcloud_backup_suffix: "" # some arbitrary information at the end of the archive name
nextcloud_backup_format: "tgz" # extension of the archive. use a supported format used by the archive module (Choices: bz2, gz, tar, xz, zip)
```

Or you can change it completely by redefining

```yaml
nc_archive_name: "{{ nextcloud_instance_name }}_nextcloud-{{ nc_status.versionstring }}_{{ ansible_date_time.iso8601_basic_short }}{{ nextcloud_backup_suffix }}"
```

### Adjusting the backup content

The role will __always__:
- backup the server's config
- create a list of installed & enabled applications(along with the version numbers)

You can adjust the scope of the backup by enabling/disabling some flags defined in default:

```yaml
nextcloud_backup_download_server_archive: true
nextcloud_backup_app_data: true
nextcloud_backup_user: true
nextcloud_backup_database: true
```

### Adjusting nextcloud-server archive included in backup
Role can download the proper server archive from the nextcloud download site and add it to backup archive.
It can be turned on using: `nextcloud_backup_download_server_archive` variable.

### Adjusting app data backup

You may want to exclude some app_data folders from the backup.
But you cannot target a specific app to backup, this requires knowledge of the app's code.

```yaml
nextcloud_backup_app_data_exclude_folder:
- preview
```

By default the preview folder is excluded from the backup as it can be notoriously __large__

### Adjusting user backup

You can exclude a list of user(s) from the backup
```yaml
nextcloud_backup_exclude_users: []
```

You can also decide to include or not some side-folders.
```yaml
nextcloud_backup_user_files_trashbin: true
nextcloud_backup_user_files_versions: true
nextcloud_backup_user_uploads: true
nextcloud_backup_user_cache: true
```

### Fetching backup from remote to local machine
You can fetch created backup from remote by setting these variables.
WARNING: user which you are used in Ansible has to be set as [backup owner](#adjusting-the-backup-owner) due to Ansible limitation on using `become` with `ansible.builtin.fetch`
```yaml
nextcloud_backup_fetch_to_local: true
nextcloud_backup_fetch_local_path: "/local_path/nextcloud_backup"
```

### Other
You can leave the server in maintenance mode at the end of the process by turning false
```yaml
nextcloud_exit_maintenance_mode: true
```

## The Dependencies

None

## Example Playbook

### Running a full backup of your nextcloud server
```yaml
- hosts: nextcloud
roles:
- role: aalaesar.backup_nextcloud
```

### Making a partial backup with only the app_data
```yaml
- hosts: nextcloud
roles:
- role: aalaesar.backup_nextcloud
vars:
nextcloud_backup_suffix: _only_app_data
nextcloud_backup_user: false
nextcloud_backup_database: false
```

## License

GPL-3.0
40 changes: 40 additions & 0 deletions roles/backup_nextcloud/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
### APPLICATION SETTINGS ##
nextcloud_instance_name: "nextcloud"
nextcloud_backup_target_dir: "/opt/nextcloud_backups"
nextcloud_webroot: "/opt/nextcloud"
# nextcloud_data_dir: "/var/ncdata"
nextcloud_websrv_user: www-data

nextcloud_exit_maintenance_mode: true

### ARCHIVE PROPERTIES ###
nextcloud_backup_suffix: ""
nextcloud_backup_owner: "{{ nextcloud_websrv_user }}"
nextcloud_backup_group: "{{ nextcloud_websrv_user }}"
nextcloud_backup_file_mode: "0640"
nextcloud_backup_dir_mode: "0750"
nextcloud_backup_format: "tgz"

### NEXTCLOUD SERVER ARCHIVE DOWNLOAD ###
nextcloud_backup_download_server_archive: false

### APPS BACKUPS ###
nextcloud_backup_app_data: true
nextcloud_backup_app_data_exclude_folder:
- preview

### USER BACKUPS ###
nextcloud_backup_user: true
nextcloud_backup_exclude_users: []
nextcloud_backup_user_files_trashbin: true
nextcloud_backup_user_files_versions: true
nextcloud_backup_user_uploads: true
nextcloud_backup_user_cache: true

### DATABASE BACKUP ###
nextcloud_backup_database: true

### FETCH TO LOCAL MACHINE ###
nextcloud_backup_fetch_to_local: false
nextcloud_backup_fetch_local_path: "/tmp/nextcloud_backup"
30 changes: 30 additions & 0 deletions roles/backup_nextcloud/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
galaxy_info:
author: Aalaesar
role_name: backup_nextcloud
namespace: aalaesar
description: Create a backup of your nextcloud server with this ansible role

license: license GPL-3.0-only

min_ansible_version: "2.9"

platforms:
- name: EL
versions:
- all
- name: Debian
versions:
- all
- name: Ubuntu
versions:
- all

galaxy_tags:
- backup
- nextcloud
- storage
- selfhosted
- privacy

dependencies: []
18 changes: 18 additions & 0 deletions roles/backup_nextcloud/tasks/app_data.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
- name: The app_data backup folder exists
ansible.builtin.file:
path: "{{ nc_archive_path }}/data"
state: directory
owner: "{{ nextcloud_backup_owner }}"
group: "{{ nextcloud_backup_group }}"
mode: "{{ nextcloud_backup_dir_mode }}"

- name: Backup applications data
ansible.builtin.command: >-
rsync -r {{ _exclude_folders }}
{{ nextcloud_data_dir }}/appdata_{{ nc_id }}
{{ nc_archive_path }}/data
vars:
_exclude_folders: "{% for _folder in nextcloud_backup_app_data_exclude_folder %}--exclude={{ _folder }} {% endfor %}"
tags:
- skip_ansible_lint
33 changes: 33 additions & 0 deletions roles/backup_nextcloud/tasks/database.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
- name: The app_data backup folder exists
ansible.builtin.file:
path: "{{ nc_archive_path }}"
state: directory
owner: "{{ nextcloud_backup_owner }}"
group: "{{ nextcloud_backup_group }}"
mode: "{{ nextcloud_backup_dir_mode }}"

- name: Create a dump of the mysql database
ansible.builtin.shell: >-
mysqldump --single-transaction --default-character-set=utf8mb4
-h {{ _nc_dbhost.stdout }} -u {{ _nc_dbuser.stdout }} -p{{ _nc_dbpassword.stdout }}
{{ _nc_dbname.stdout }} > database_dump.bak.sql
args:
chdir: "{{ nc_archive_path }}"
no_log: true
when:
- _nc_dbtype.stdout == 'mysql'

- name: Create a dump of the postgreSQL database
ansible.builtin.command: >-
pg_dump {{ _nc_dbname.stdout }}
-h {{ _nc_dbhost.stdout }}
-U {{ _nc_dbuser.stdout }}
-f database_dump.bak.sql
args:
chdir: "{{ nc_archive_path }}"
no_log: true
environment:
PGPASSWORD: "{{ _nc_dbpassword.stdout }}"
when:
- _nc_dbtype.stdout == 'pgsql'
6 changes: 6 additions & 0 deletions roles/backup_nextcloud/tasks/fetching.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
- name: Fetch file from remote to local
become: false # Using become may cause OOM errors. (https://docs.ansible.com/ansible/latest/collections/ansible/builtin/fetch_module.html#notes)
ansible.builtin.fetch:
src: "{{ nc_archive_path }}.{{ nextcloud_backup_format }}"
dest: "{{ nextcloud_backup_fetch_local_path }}"
41 changes: 41 additions & 0 deletions roles/backup_nextcloud/tasks/files.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
- name: Backup target dir exists on the host
ansible.builtin.file:
path: "{{ nextcloud_backup_target_dir }}"
state: directory
owner: "{{ nextcloud_backup_owner }}"
group: "{{ nextcloud_backup_group }}"
mode: "{{ nextcloud_backup_dir_mode }}"

- name: Backup folder exists on the host
ansible.builtin.file:
path: "{{ nc_archive_path }}"
state: directory
owner: "{{ nextcloud_backup_owner }}"
group: "{{ nextcloud_backup_group }}"
mode: "{{ nextcloud_backup_dir_mode }}"

- name: Copy config in archive
ansible.builtin.shell: "rsync -r --exclude='*.sample.*' {{nextcloud_webroot}}/config/ {{ nc_archive_path }}/config/"
tags:
- skip_ansible_lint

- name: Download server files for current version
vars:
nc_server_dl_url: "https://download.nextcloud.com/server/releases/nextcloud-{{ nc_status.versionstring }}.zip"
ansible.builtin.get_url:
url: "{{ nc_server_dl_url }}"
checksum: "sha512:{{ nc_server_dl_url }}.sha512"
dest: "{{ nc_archive_path }}/nextcloud-{{ nc_status.versionstring }}.zip"
owner: "{{ nextcloud_backup_owner }}"
group: "{{ nextcloud_backup_group }}"
mode: "{{ nextcloud_backup_file_mode }}"
when: nextcloud_backup_download_server_archive

- name: Export the list of apps in the backup
ansible.builtin.copy:
content: "{{ _nc_app_list.stdout | from_json | to_nice_json }}"
dest: "{{ nc_archive_path }}/installed_apps.json"
owner: "{{ nextcloud_backup_owner }}"
group: "{{ nextcloud_backup_group }}"
mode: "{{ nextcloud_backup_file_mode }}"
Loading

0 comments on commit 7a71495

Please sign in to comment.