From e8b54ec96765dfa48d9cffbaf5df8f84fa9c4a61 Mon Sep 17 00:00:00 2001 From: Jan Beilicke Date: Tue, 24 Mar 2020 00:38:20 +0100 Subject: [PATCH] Initial commit --- LICENSE | 19 +++ README.md | 31 +++++ defaults/main.yml | 35 ++++++ files/docker/proxy/Dockerfile | 3 + files/docker/proxy/uploadsize.conf | 2 + handlers/main.yml | 2 + meta/main.yml | 55 +++++++++ tasks/main.yml | 140 ++++++++++++++++++++++ templates/docker-compose.nextcloud.yml.j2 | 82 +++++++++++++ tests/inventory | 2 + tests/test.yml | 5 + vars/main.yml | 2 + 12 files changed, 378 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 defaults/main.yml create mode 100644 files/docker/proxy/Dockerfile create mode 100644 files/docker/proxy/uploadsize.conf create mode 100644 handlers/main.yml create mode 100644 meta/main.yml create mode 100644 tasks/main.yml create mode 100644 templates/docker-compose.nextcloud.yml.j2 create mode 100644 tests/inventory create mode 100644 tests/test.yml create mode 100644 vars/main.yml diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..86aa256 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +MIT License Copyright (c) 2020 Jan Beilicke + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c17ee1c --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +Nextcloud (Docker-Compose) +========================== + +Requirements +------------ + +- Ansible (implemented and tested with v2.9) +- Ubuntu or Debian server +- [Docker Engine](https://docs.docker.com/install/) + [Docker Compose](https://docs.docker.com/compose/install/) +- Optional: Traefik + +Role Variables +-------------- + +TODO + +Dependencies +------------ + +Example Playbook +---------------- + +License +------- + +MIT + +Author Information +------------------ + +This role was created in 2020 by [Jan Beilicke](https://jotbe.io). diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..a708a3c --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,35 @@ +--- +# defaults file for nextcloud +mariadb_root_password: changeme +mysql_host: mysqldb +mysql_database: nextcloud +nextcloud_mariadb_user: nextcloud +nextcloud_mariadb_password: nextcloud +nextcloud_admin_user: admin +nextcloud_admin_password: mynextcloud +nextcloud_trusted_domains: localhost +virtual_host: localhost +letsencrypt_host: +letsencrypt_email: +docker_user: deploy +smtp_host: +smtp_secure: +smtp_port: 25 +smtp_authtype: PLAIN +smtp_name: +smtp_password: +mail_from_address: +mail_domain: +nextcloud_overwrite_cli_url: +nextcloud_overwrite_host: +nextcloud_overwrite_protocol: +nextcloud_enable_restic_compose_backup: False +restic_aws_access_key_id: +restic_aws_secret_access_key: +restic_repository: +restic_password: +restic_keep_daily: 7 +restic_keep_weekly: 4 +restic_keep_monthly: 12 +restic_keep_yearly: 3 +restic_cron_schedule: "0 1 * * *" diff --git a/files/docker/proxy/Dockerfile b/files/docker/proxy/Dockerfile new file mode 100644 index 0000000..0c066d0 --- /dev/null +++ b/files/docker/proxy/Dockerfile @@ -0,0 +1,3 @@ +FROM jwilder/nginx-proxy:alpine + +COPY uploadsize.conf /etc/nginx/conf.d/uploadsize.conf \ No newline at end of file diff --git a/files/docker/proxy/uploadsize.conf b/files/docker/proxy/uploadsize.conf new file mode 100644 index 0000000..70a739d --- /dev/null +++ b/files/docker/proxy/uploadsize.conf @@ -0,0 +1,2 @@ +client_max_body_size 10G; +proxy_request_buffering off; \ No newline at end of file diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..3cdfcfd --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,2 @@ +--- +# handlers file for nextcloud \ No newline at end of file diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..a52e2b3 --- /dev/null +++ b/meta/main.yml @@ -0,0 +1,55 @@ +galaxy_info: + author: Jan Beilicke + description: Nextcloud as a Docker Compose service compatible with Traefik + company: jotbe.io + + # If the issue tracker for your role is not on github, uncomment the + # next line and provide a value + # issue_tracker_url: http://example.com/issue/tracker + + # Choose a valid license ID from https://spdx.org - some suggested licenses: + # - BSD-3-Clause (default) + # - MIT + # - GPL-2.0-or-later + # - GPL-3.0-only + # - Apache-2.0 + # - CC-BY-4.0 + license: MIT + + min_ansible_version: 2.4 + + # If this a Container Enabled role, provide the minimum Ansible Container version. + # min_ansible_container_version: + + # + # Provide a list of supported platforms, and for each platform a list of versions. + # If you don't wish to enumerate all versions for a particular platform, use 'all'. + # To view available platforms and versions (or releases), visit: + # https://galaxy.ansible.com/api/v1/platforms/ + # + # platforms: + # - name: Fedora + # versions: + # - all + # - 25 + # - name: SomePlatform + # versions: + # - all + # - 1.0 + # - 7 + # - 99.99 + + galaxy_tags: [] + # List tags for your role here, one per line. A tag is a keyword that describes + # and categorizes the role. Users find roles by searching for tags. Be sure to + # remove the '[]' above, if you add tags to this list. + # + # NOTE: A tag is limited to a single word comprised of alphanumeric characters. + # Maximum 20 tags per role. + +dependencies: + - geerlingguy.pip + - geerlingguy.docker + # List your role dependencies here, one per line. Be sure to remove the '[]' above, + # if you add dependencies to this list. + \ No newline at end of file diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..4988f0a --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,140 @@ +--- +# tasks file for nextcloud +- name: Ensure nextcloud config directory exists + file: + path: /home/{{ docker_user }}/nextcloud + state: directory + owner: '{{ docker_user }}' + group: '{{ docker_user }}' + +- name: Provide docker-compose.yml + template: + src: templates/docker-compose.nextcloud.yml.j2 + dest: /home/{{ docker_user }}/nextcloud/docker-compose.yml + owner: "{{ docker_user }}" + group: "{{ docker_user }}" + mode: '0644' + +- name: Output docker-compose.yml + shell: cat /home/{{ docker_user }}/nextcloud/docker-compose.yml + register: output + +- debug: + var: output + +- name: Provide database env vars + copy: + dest: /home/{{ docker_user }}/nextcloud/db.env + owner: "{{ docker_user }}" + group: "{{ docker_user }}" + mode: '0640' + content: | + MYSQL_ROOT_PASSWORD={{ mariadb_root_password }} + MYSQL_DATABASE={{ mysql_database }} + MYSQL_PASSWORD={{ nextcloud_mariadb_password }} + MYSQL_USER={{ nextcloud_mariadb_user }} + +- name: Provide Nextcloud env vars + copy: + dest: /home/{{ docker_user }}/nextcloud/nextcloud.env + owner: "{{ docker_user }}" + group: "{{ docker_user }}" + mode: '0640' + content: | + VIRTUAL_HOST={{ virtual_host }} + LETSENCRYPT_HOST={{ letsencrypt_host }} + LETSENCRYPT_EMAIL={{ letsencrypt_email }} + MYSQL_HOST={{ mysql_host }} + MYSQL_DATABASE={{ mysql_database }} + MYSQL_PASSWORD={{ nextcloud_mariadb_password }} + MYSQL_USER={{ nextcloud_mariadb_user }} + NEXTCLOUD_ADMIN_USER={{ nextcloud_admin_user }} + NEXTCLOUD_ADMIN_PASSWORD={{ nextcloud_admin_password }} + NEXTCLOUD_TRUSTED_DOMAINS={{ nextcloud_trusted_domains }} + SMTP_HOST={{ smtp_host }} + SMTP_SECURE={{ smtp_secure }} + SMTP_PORT={{ smtp_port }} + SMTP_AUTHTYPE={{ smtp_authtype }} + SMTP_NAME={{ smtp_name }} + SMTP_PASSWORD={{ smtp_password }} + MAIL_FROM_ADDRESS={{ mail_from_address }} + MAIL_DOMAIN={{ mail_domain }} + +- name: Provide restic-compose-backup env vars + copy: + dest: /home/{{ docker_user }}/nextcloud/restic-compose-backup.env + owner: "{{ docker_user }}" + group: "{{ docker_user }}" + mode: '0640' + content: | + AWS_ACCESS_KEY_ID={{ restic_aws_access_key_id }} + AWS_SECRET_ACCESS_KEY={{ restic_aws_secret_access_key }} + RESTIC_REPOSITORY={{ restic_repository }} + RESTIC_PASSWORD={{ restic_password }} + # snapshot prune rules + RESTIC_KEEP_DAILY={{ restic_keep_daily}} + RESTIC_KEEP_WEEKLY={{ restic_keep_weekly }} + RESTIC_KEEP_MONTHLY={{ restic_keep_monthly }} + RESTIC_KEEP_YEARLY={{ restic_keep_yearly }} + # Cron schedule. Run every day at 1am + CRON_SCHEDULE="{{ restic_cron_schedule }}" + when: nextcloud_enable_restic_compose_backup == true + +- name: "docker-compose: Teardown existing Nextcloud service" + docker_compose: + project_src: "/home/{{ docker_user }}/nextcloud/" + state: absent + tags: ['never', 'teardown'] + +- name: "docker-compose: Start Nextcloud service" + docker_compose: + project_src: "/home/{{ docker_user }}/nextcloud/" + register: output + tags: service_start + +- debug: + var: output + +- assert: + that: + - "output.ansible_facts['nextcloud-app']['nextcloud-app'].state.running" + +- name: Get container IP + set_fact: + nextcloud_ip: "{{ output.ansible_facts['nextcloud-app']['nextcloud-app'].networks.nextcloud_default.IPAddress }}" + +- name: "Waiting for Nextcloud container to become available" + become: false + wait_for: + host: "{{ nextcloud_ip }}" + port: 80 + +- name: "docker-compose: Set overwriteprotocol using occ" + shell: + chdir: /home/{{ docker_user }}/nextcloud/ + cmd: docker-compose exec -T -u www-data nextcloud-app /bin/bash -c './occ config:system:set overwriteprotocol --value="{{ nextcloud_overwrite_protocol }}"' + +- name: "docker-compose: Set overwrite.cli.url using occ" + shell: + chdir: /home/{{ docker_user }}/nextcloud/ + cmd: docker-compose exec -T -u www-data nextcloud-app /bin/bash -c './occ config:system:set overwrite.cli.url --value="{{ nextcloud_overwrite_cli_url }}"' + +- name: "docker-compose: Set overwritehost using occ" + shell: + cmd: docker-compose exec -T -u www-data nextcloud-app /bin/bash -c './occ config:system:set overwritehost --value="{{ nextcloud_overwrite_host }}"' + chdir: /home/{{ docker_user }}/nextcloud/ + +- name: "Waiting for Nextcloud service (443/TLS) to become available" + become: false + wait_for: + host: "{{ ansible_ssh_host }}" + port: 443 + delegate_to: localhost + +# - name: "Testing whether the Nextcloud homepage is available#" +# action: uri url=http://{{ ansible_ssh_host }} return_content=yes +# register: gl + +# - fail: +# msg: 'Graylog homepage is not available!' +# when: "'Graylog Web Interface' not in gl.content" diff --git a/templates/docker-compose.nextcloud.yml.j2 b/templates/docker-compose.nextcloud.yml.j2 new file mode 100644 index 0000000..a59a51d --- /dev/null +++ b/templates/docker-compose.nextcloud.yml.j2 @@ -0,0 +1,82 @@ +version: '3' + +networks: + traefik: + external: + name: traefik_traefik + +services: + mysqldb: + image: mariadb:10.4.11 + command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW + volumes: + - mysqldb:/var/lib/mysql + - /etc/localtime:/etc/localtime:ro + env_file: + - db.env +{% if nextcloud_enable_restic_compose_backup %} + labels: + - "restic-compose-backup.mariadb=true" +{% endif %} + restart: unless-stopped + + nextcloud-app: + image: nextcloud:apache + container_name: nextcloud-app + networks: + - traefik + - default + depends_on: + - mysqldb + volumes: + - nextcloud:/var/www/html + - /etc/localtime:/etc/localtime:ro + env_file: + - nextcloud.env + labels: + - "traefik.enable=true" + - "traefik.docker.network=traefik_traefik" + - "traefik.http.routers.nextcloud.rule=Host(`{{ nextcloud_virtual_host }}`)" + - "traefik.http.routers.nextcloud.entrypoints=websecure" + - "traefik.http.routers.nextcloud.tls=true" + - "traefik.http.routers.nextcloud.tls.certresolver=defaultresolver" + - "traefik.http.middlewares.nextcloud-rep.redirectregex.regex=https://(.*)/.well-known/(card|cal)dav" + - "traefik.http.middlewares.nextcloud-rep.redirectregex.replacement=https://$$1/remote.php/dav/" + - "traefik.http.middlewares.nextcloud-rep.redirectregex.permanent=true" + - "traefik.http.middlewares.nextcloud-header.headers.stsIncludeSubdomains=true" + - "traefik.http.middlewares.nextcloud-header.headers.stsSeconds=15552000" + - "traefik.http.routers.nextcloud.middlewares=nextcloud-rep,nextcloud-header" + - "traefik.frontend.headers.SSLRedirect=true" + - "traefik.frontend.headers.browserXSSFilter=true" + - "traefik.frontend.headers.contentTypeNosniff=true" + - "traefik.frontend.headers.forceSTSHeader=true" + - "traefik.frontend.headers.STSSeconds=315360000" + - "traefik.frontend.headers.STSIncludeSubdomains=true" + - "traefik.frontend.headers.STSPreload=true" + - "traefik.frontend.headers.frameDeny=true" + - "traefik.frontend.passHostHeader=true" +{% if nextcloud_enable_restic_compose_backup %} + - "restic-compose-backup.volumes=true" + - "restic-compose-backup.volumes.include=nextcloud" +{% endif %} + restart: unless-stopped + +{% if nextcloud_enable_restic_compose_backup %} + # The backup service + backup: + image: zettaio/restic-compose-backup:0.4.2 + env_file: + - restic-compose-backup.env + volumes: + # We need to communicate with docker + - /var/run/docker.sock:/tmp/docker.sock:ro + # Persistent storage of restic cache (greatly speeds up all restic operations) + - backup-cache:/cache +{% endif %} + +volumes: + mysqldb: + nextcloud: +{% if nextcloud_enable_restic_compose_backup %} + backup-cache: +{% endif %} \ No newline at end of file diff --git a/tests/inventory b/tests/inventory new file mode 100644 index 0000000..878877b --- /dev/null +++ b/tests/inventory @@ -0,0 +1,2 @@ +localhost + diff --git a/tests/test.yml b/tests/test.yml new file mode 100644 index 0000000..2680d4e --- /dev/null +++ b/tests/test.yml @@ -0,0 +1,5 @@ +--- +- hosts: localhost + remote_user: root + roles: + - nextcloud \ No newline at end of file diff --git a/vars/main.yml b/vars/main.yml new file mode 100644 index 0000000..b52587a --- /dev/null +++ b/vars/main.yml @@ -0,0 +1,2 @@ +--- +# vars file for nextcloud \ No newline at end of file