diff --git a/README.md b/README.md index fdfd5c4ed8..4193c07eb5 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,7 @@ If you have a spare domain name you can configure applications to be accessible * [Transmission](https://transmissionbt.com/) - BitTorrent client (with OpenVPN if you have a supported VPN provider) * [Trilium](https://github.com/zadam/trilium) - Hierarchical note taking application with focus on building large personal knowledge bases * [Tt-rss](https://tt-rss.org/) - free and open source web-based news feed (RSS/Atom) reader and aggregator +* [Twenty CMS](https://github.com/twentyhq/twenty) - The #1 Open-Source CRM * [Ubooquity](http://vaemendis.net/ubooquity/) - Book and comic server * [uTorrent](https://www.utorrent.com/) - The best torrent downloading app for beginners * [Vaultwarden](https://github.com/dani-garcia/vaultwarden) - Self-Hosting port of password manager diff --git a/nas.yml b/nas.yml index 0396147424..8ccdf92d6b 100644 --- a/nas.yml +++ b/nas.yml @@ -714,6 +714,10 @@ tags: - ttrss + - role: twenty + tags: + - twenty + - role: ubooquity tags: - ubooquity diff --git a/roles/twenty/defaults/main.yml b/roles/twenty/defaults/main.yml new file mode 100644 index 0000000000..725870ce66 --- /dev/null +++ b/roles/twenty/defaults/main.yml @@ -0,0 +1,67 @@ +--- +twenty_enabled: false +twenty_available_externally: false + +# directories +twenty_data_directory: "{{ docker_home }}/twenty" + +# network +twenty_port: "3014" +twenty_hostname: "twenty" +twenty_network_name: "twenty" + +# specs +twenty_memory: 4g +twenty_db_memory: 1g + +# docker +twenty_container_name: twenty +twenty_image_name: "twentycrm/twenty" +twenty_image_version: latest + +twenty_db_container_name: twenty-db +twenty_db_image_name: "twentycrm/twenty-postgres" +twenty_db_image_version: latest + +twenty_user_id: "1000" +twenty_group_id: "1000" + +# twenty +twenty_pg_database_url: "postgres://{{ twenty_db_user }}:{{ twenty_db_password }}@{{ twenty_db_container_name }}:{{ twenty_db_port }}/default" +twenty_db_user: "twenty" +twenty_db_password: "twenty" +twenty_db_port: "5432" +twenty_server_url: "https://{{ twenty_hostname }}.{{ ansible_nas_domain }}" +twenty_front_base_url: "https://{{ twenty_hostname }}.{{ ansible_nas_domain }}" + +twenty_enable_db_migrations: "true" + +twenty_sign_in_prefilled: "true" +twenty_storage_type: "local" +twenty_storage_s3_region: "eu-west3" +twenty_storage_s3_name: "my-bucket" +twenty_storage_s3_endpoint: "" +# Use openssl rand -base64 32 for each secret +twenty_access_token_secret: "replace_me_with_a_random_string_access" +twenty_login_token_secret: "replace_me_with_a_random_string_access" +twenty_refresh_token_secret: "replace_me_with_a_random_string_access" +twenty_file_token_secret: "replace_me_with_a_random_string_access" + + +twenty_env: + PORT: "3000" + PG_DATABASE_URL: "{{ twenty_pg_database_url }}" + SERVER_URL: "{{ twenty_server_url }}" + FRONT_BASE_URL: "{{ twenty_front_base_url }}" + + ENABLE_DB_MIGRATIONS: "{{ twenty_enable_db_migrations }}" + + SIGN_IN_PREFILLED: "{{ twenty_sign_in_prefilled }}" + STORAGE_TYPE: "{{ twenty_storage_type }}" + # STORAGE_S3_REGION: "{{ twenty_storage_s3_region }}" + # STORAGE_S3_NAME: "{{ twenty_storage_s3_name }}" + # STORAGE_S3_ENDPOINT: "{{ twenty_storage_s3_endpoint }}" + ACCESS_TOKEN_SECRET: "{{ twenty_access_token_secret }}" + LOGIN_TOKEN_SECRET: "{{ twenty_login_token_secret }}" + REFRESH_TOKEN_SECRET: "{{ twenty_refresh_token_secret }}" + FILE_TOKEN_SECRET: "{{ twenty_file_token_secret }}" diff --git a/roles/twenty/docs/twenty.md b/roles/twenty/docs/twenty.md new file mode 100644 index 0000000000..23b500f2b4 --- /dev/null +++ b/roles/twenty/docs/twenty.md @@ -0,0 +1,11 @@ +# Twenty CMS + +Homepage: [https://github.com/twentyhq/twenty](https://github.com/twentyhq/twenty) + +The #1 Open-Source CRM. Modern, powerful, affordable platform to manage your customer relationships + +## Usage + +Set `twenty_enabled: true` in your `inventories//group_vars/nas.yml` file. + +Twenty CMS web interface can be found at [http://ansible_nas_host_or_ip:8127](http://ansible_nas_host_or_ip:3014). diff --git a/roles/twenty/molecule/default/molecule.yml b/roles/twenty/molecule/default/molecule.yml new file mode 100644 index 0000000000..3fd9126d0e --- /dev/null +++ b/roles/twenty/molecule/default/molecule.yml @@ -0,0 +1,7 @@ +--- +provisioner: + inventory: + group_vars: + all: + twenty_enabled: true + twenty_data_directory: /tmp/twenty diff --git a/roles/twenty/molecule/default/side_effect.yml b/roles/twenty/molecule/default/side_effect.yml new file mode 100644 index 0000000000..5430cecb0b --- /dev/null +++ b/roles/twenty/molecule/default/side_effect.yml @@ -0,0 +1,10 @@ +--- +- name: Stop + hosts: all + become: true + tasks: + - name: "Include {{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }} role" + ansible.builtin.include_role: + name: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') | basename }}" + vars: + twenty_enabled: false diff --git a/roles/twenty/molecule/default/verify.yml b/roles/twenty/molecule/default/verify.yml new file mode 100644 index 0000000000..f8fd0d83ee --- /dev/null +++ b/roles/twenty/molecule/default/verify.yml @@ -0,0 +1,26 @@ +--- +- name: Verify + hosts: all + gather_facts: false + tasks: + - name: Include vars + ansible.builtin.include_vars: + file: ../../defaults/main.yml + + - name: Get twenty db container state + community.docker.docker_container: + name: "{{ twenty_db_container_name }}" + register: result_db + + - name: Get twenty container state + community.docker.docker_container: + name: "{{ twenty_container_name }}" + register: result + + - name: Check if twenty containers are running + ansible.builtin.assert: + that: + - result_db.container['State']['Status'] == "running" + - result_db.container['State']['Restarting'] == false + - result.container['State']['Status'] == "running" + - result.container['State']['Restarting'] == false diff --git a/roles/twenty/molecule/default/verify_stopped.yml b/roles/twenty/molecule/default/verify_stopped.yml new file mode 100644 index 0000000000..694ab010c6 --- /dev/null +++ b/roles/twenty/molecule/default/verify_stopped.yml @@ -0,0 +1,26 @@ +--- +- name: Verify + hosts: all + gather_facts: false + tasks: + - name: Include vars + ansible.builtin.include_vars: + file: ../../defaults/main.yml + + - name: Try and stop and remove twenty + community.docker.docker_container: + name: "{{ twenty_container_name }}" + state: absent + register: result + + - name: Try and stop and remove twenty db + community.docker.docker_container: + name: "{{ twenty_db_container_name }}" + state: absent + register: result_db + + - name: Check if twenty is stopped + ansible.builtin.assert: + that: + - not result.changed + - not result_db.changed diff --git a/roles/twenty/requirements.yml b/roles/twenty/requirements.yml new file mode 120000 index 0000000000..9a736435ab --- /dev/null +++ b/roles/twenty/requirements.yml @@ -0,0 +1 @@ +../../requirements.yml \ No newline at end of file diff --git a/roles/twenty/tasks/main.yml b/roles/twenty/tasks/main.yml new file mode 100644 index 0000000000..f468b5de37 --- /dev/null +++ b/roles/twenty/tasks/main.yml @@ -0,0 +1,87 @@ +--- +- name: Start Twenty + block: + - name: Create Twenty Directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + mode: 0777 + with_items: + - "{{ twenty_data_directory }}" + - "{{ twenty_data_directory }}/data" + + - name: Create Twenty DB Directories + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: "1001" + group: "1001" + with_items: + - "{{ twenty_data_directory }}/db-data" + + - name: Create Twenty Network + community.docker.docker_network: + name: "{{ twenty_network_name }}" + + - name: Create Twenty Db Container + community.docker.docker_container: + container_default_behavior: no_defaults + name: "{{ twenty_db_container_name }}" + image: "{{ twenty_db_image_name }}:{{ twenty_db_image_version }}" + pull: true + networks: + - name: "{{ twenty_network_name }}" + network_mode: "{{ twenty_network_name }}" + volumes: + - "{{ twenty_data_directory }}/db-data:/bitnami/postgresql" + env: + POSTGRES_PASSWORD: "{{ twenty_db_password }}" + healthcheck: + test: pg_isready -U twenty -d default + interval: 5s + timeout: 5s + retries: 10 + restart_policy: always + memory: "{{ twenty_db_memory }}" + + - name: Create Twenty Docker Container + community.docker.docker_container: + container_default_behavior: no_defaults + name: "{{ twenty_container_name }}" + image: "{{ twenty_image_name }}:{{ twenty_image_version }}" + pull: true + networks: + - name: "{{ twenty_network_name }}" + network_mode: "{{ twenty_network_name }}" + volumes: + - "{{ twenty_data_directory }}/data:/app/.local-storage" + ports: + - "{{ twenty_port }}:3000" + env: "{{ twenty_env }}" + restart_policy: unless-stopped + memory: "{{ twenty_memory }}" + labels: + traefik.enable: "{{ twenty_available_externally | string }}" + traefik.http.routers.twenty.rule: "Host(`{{ twenty_hostname }}.{{ ansible_nas_domain }}`)" + # traefik.http.routers.twenty.tls.certresolver: "letsencrypt" + # traefik.http.routers.twenty.tls.domains[0].main: "{{ ansible_nas_domain }}" + # traefik.http.routers.twenty.tls.domains[0].sans: "*.{{ ansible_nas_domain }}" + traefik.http.services.twenty.loadbalancer.server.port: "3000" + healthcheck: + test: curl --fail http://localhost:3000/healthz + interval: 5s + timeout: 5s + retries: 10 + when: twenty_enabled is true + +- name: Stop Twenty + block: + - name: Stop Twenty + community.docker.docker_container: + name: "{{ twenty_container_name }}" + state: absent + - name: Stop Twenty Db + community.docker.docker_container: + name: "{{ twenty_db_container_name }}" + state: absent + when: twenty_enabled is false diff --git a/website/docs/applications/content-management/twenty.md b/website/docs/applications/content-management/twenty.md new file mode 100644 index 0000000000..350039ad81 --- /dev/null +++ b/website/docs/applications/content-management/twenty.md @@ -0,0 +1,14 @@ +--- +title: "Twenty CMS" +description: "The #1 Open-Source CRM. Modern, powerful, affordable platform to manage your customer relationships" +--- + +Homepage: [https://github.com/twentyhq/twenty](https://github.com/twentyhq/twenty) + +The #1 Open-Source CRM. Modern, powerful, affordable platform to manage your customer relationships + +## Usage + +Set `twenty_enabled: true` in your `inventories//group_vars/nas.yml` file. + +Twenty CMS web interface can be found at [http://ansible_nas_host_or_ip:3014](http://ansible_nas_host_or_ip:3014).