From 9ec8c3adf769f2e49854bab5b047bfdd029ae461 Mon Sep 17 00:00:00 2001 From: muppeth Date: Thu, 22 Aug 2024 15:04:11 +0200 Subject: [PATCH] initial commit --- .gitignore | 1 + Playbooks/invoiceninja.yml | 9 +++ README.md | 9 +++ defaults/main.yml | 162 +++++++++++++++++++++++++++++++++++++ handlers/main.yml | 8 ++ tasks/check.yml | 6 ++ tasks/configure.yml | 11 +++ tasks/installapp.yml | 17 ++++ tasks/installdeps.yml | 6 ++ tasks/main.yml | 14 ++++ templates/env.j2 | 59 ++++++++++++++ 11 files changed, 302 insertions(+) create mode 100644 .gitignore create mode 100644 Playbooks/invoiceninja.yml create mode 100644 README.md create mode 100644 defaults/main.yml create mode 100644 handlers/main.yml create mode 100644 tasks/check.yml create mode 100644 tasks/configure.yml create mode 100644 tasks/installapp.yml create mode 100644 tasks/installdeps.yml create mode 100644 tasks/main.yml create mode 100644 templates/env.j2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8000dd9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.vagrant diff --git a/Playbooks/invoiceninja.yml b/Playbooks/invoiceninja.yml new file mode 100644 index 0000000..c490055 --- /dev/null +++ b/Playbooks/invoiceninja.yml @@ -0,0 +1,9 @@ +--- + +- name: 'Invoiceninja Playbook' + hosts: 'invoiceninja_servers' + roles: + - mariadb + - nginx + - php-fpm + - invoiceninja diff --git a/README.md b/README.md new file mode 100644 index 0000000..dcac8ee --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# InvoiceNinja Ansible role + +*This role is maintained by Disroot.org team* + +This role takes care of installation of invoice ninja. Below some initial notes: + - **APP_KEY** - before running the role, make sure to generate APP_KEY for your installtion. You can do it by running for example: `echo "base64:$(openssl rand -base64 32)"` and pasting it to your host_vars under: `ninja_app_key` variable + - **Web Setup** - Unfortunatelly looks like there is no way to skip the initial setup of invoice ninja, and after successfully running the role, you will need to input db related data as well as create your initial user. + - **Update** - Running precompiled version of invoiceninja (as in this case ATM) allows for an automated in-app update process. This means there is no need for updating via commandline/ansible. For now it should be sufficient, however if needed the update process is fairly simple as well if we were to implement it via ansible. In anycase though, prior the update you should create a database backup. + diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..7bed272 --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,162 @@ +--- + +ninja_pkgs: + - openssl + - unzip +ninja_app_dir: '/var/www/invoiceninja' +ninja_app_username: 'www-data' +ninja_app_group: 'www-data' +ninja_version: 'v5.10.24' + +# Configuration +ninja_app_name: 'Invoice Ninja' +ninja_app_env: 'production' +ninja_app_key: 'base64:Z6akRUzWKWjAY5Erp75/EOXg1VwJRl3DpljzUpgCTlc=' # Generate app key with eg: `echo "base64:$(openssl rand -base64 32)"` + +ninja_app_debug: 'false' +ninja_app_url: 'https://invoice.example.com' +ninja_react_url: 'http://localhost:3001' +ninja_db_connection: 'mysql' +ninja_multi_db: 'false' +ninja_db_host: 'localhost' +ninja_db_name: 'ninjadb' +ninja_db_user: 'ninjaadmin' +ninja_db_passwd: 'changeme' +ninja_db_port: '3306' +ninja_demo_mode: 'false' +ninja_broadcast_driver: 'log' +ninja_log_channel: 'stack' +ninja_cache_driver: 'file' +ninja_queue_connection: 'sync' +ninja_session_driver: 'file' +ninja_session_lifetime: '120' +ninja_redis_host: '127.0.0.1' +ninja_redis_password: 'null' +ninja_redis_port: '6379' +ninja_mailer: 'smtp' +ninja_mail_host: 'mail.example.com' +ninja_mail_port: '587' +ninja_mail_username: 'contact@example.com' +ninja_mail_password: 'changeme' +ninja_mail_encryption: 'tls' +ninja_mail_addr: 'contact@example.com' +ninja_mail_from_user: 'InvoiceNinja' +ninja_environment: 'selfhost' +ninja_pdf_generator: 'hosted_ninja' +ninja_phantomjs_key: 'a-demo-key-with-low-quota-per-ip-address' +ninja_phantomjs_secret: 'secret' +ninja_update_secret: 'secret' +ninja_delete_pdf_days: '60' +ninja_delete_backup_days: '60' + +#PHP Vars +php_version: '8.2' +php_etc_path: '/etc/php' +install_php: 'true' +pool_listen: '/var/run/php/php{{ php_version }}-fpm.sock' + +php_pkgs: + - php{{ php_version }}-bcmath + - php{{ php_version }}-imagick + - php{{ php_version }}-soap + - php{{ php_version }}-gd + - php{{ php_version }}-mbstring + - php{{ php_version }}-common + - php{{ php_version }}-tokenizer + - php{{ php_version }}-xml + - php{{ php_version }}-curl + - php{{ php_version }}-zip + - php{{ php_version }}-gmp + - php{{ php_version }}-mysql + - php{{ php_version }}-intl + - php{{ php_version }}-fpm + - php{{ php_version }}-bz2 + +# MARIADB CONFIG +mariadb_root_password: 'changeme' +mariadb_default_config: + - name: 'client' + config: + - port = '{{ mariadb_client_port }}' + - socket = /var/run/mysqld/mysqld.sock + - default-character-set = utf8mb4 + - name: 'mysqld_safe' + config: + - safe_socket = /var/run/mysqld/mysqld.sock + - safe_nice = 0 + - name: 'mysqld' + config: + - user = mysql + - pid_file = /var/run/mysqld/mysqld.pid + - socket = /var/run/mysqld/mysqld.sock + - port = 3306 + - basedir = /usr + - datadir = "{{mariadb_datadir}}" + - tmpdir = /tmp + - init_connect ='SET collation_connection = utf8mb4_unicode_ci' + - init_connect ='SET NAMES utf8mb4' + - character-set-server = utf8mb4 + - collation-server = utf8mb4_unicode_ci + - skip_external_locking = True + - bind_address = {{ ninja_db_hostname }} + - key_buffer = 16M + - max_allowed_packet = 16M + - thread_stack = 192K + - thread_cache_size = 16 + - myisam_recover = BACKUP + - max_connections = 1000 + - query_cache_limit = 1M + - query_cache_size = 16M + - general_log_file = /var/log/mysql/mysql.log + - general_log = 0 + - slow_query_log = 1 + - slow_query_log_file = /var/log/mysql/mysql-slow.log + - long_query_time = 1 + - log_queries_not_using_indexes = False + - default_storage_engine = InnoDB + - innodb_buffer_pool_size = 1024M + - innodb_log_file_size = 128M + - innodb_log_buffer_size = 8M + - innodb_thread_concurrency = 64 + - innodb_read_io_threads = 16 + - innodb_write_io_threads = 16 + - innodb_file_per_table = 1 + - innodb_open_files = 400 + - innodb_io_capacity = 600 + - innodb_lock_wait_timeout = 60 + - innodb_flush_method = O_DIRECT + - innodb_doublewrite = 0 + - innodb_use_native_aio = 0 + - innodb_large_prefix = on + - server_id = 1 + - log_bin = /var/log/mysql/mysql-bin.log + - expire_logs_days = 2 + - max_binlog_size = 10M + - binlog_format = row + - query_cache_type = 1 + - query_cache_limit = 256K + - query_cache_min_res_unit = 2k + - query_cache_size = 300M + - tmp_table_size= 64M + - max_heap_table_size= 64M + + + - name: 'mysqldump' + config: + - quick + #- quotes-names + - max_allowed_packet = 16M + - name: 'isamchk' + config: + - key_buffer = 16M + +mariadb_databases: + - name: '{{ ninja_db_name }}' + collation: 'utf8mb4_unicode_ci' + encoding: 'utf8mb4' + +mariadb_users: + - name: '{{ ninja_db_user }}' + host: '{{ ninja_db_hostname }}' + password: '{{ ninja_db_passwd }}' + priv: '{{ ninja_db_name }}.*:ALL' diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..5b14a3a --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,8 @@ +--- + +- name: 'Restart invoiceninja' + systemd: + name: 'php{{ php_version }}-fpm.service' + state: 'restarted' + enabled: true + daemon_reload: 'yes' diff --git a/tasks/check.yml b/tasks/check.yml new file mode 100644 index 0000000..188dc3f --- /dev/null +++ b/tasks/check.yml @@ -0,0 +1,6 @@ +--- + +- name: '[CHECK] - Check if invoice ninja is installed' + shell: 'sudo -u {{ ninja_app_username }} php {{ ninja_app_dir }}/artisan' + ignore_errors: 'true' + register: ninja_installed diff --git a/tasks/configure.yml b/tasks/configure.yml new file mode 100644 index 0000000..96c46e5 --- /dev/null +++ b/tasks/configure.yml @@ -0,0 +1,11 @@ +--- + +- name: '[CONFIGURE] - Setup env file for invoiceninja' + template: + src: 'env.j2' + dest: '{{ ninja_app_dir }}/.env' + mode: 0644 + owner: '{{ ninja_app_username }}' + group: '{{ ninja_app_group }}' + notify: Restart invoiceninja + diff --git a/tasks/installapp.yml b/tasks/installapp.yml new file mode 100644 index 0000000..89ad24e --- /dev/null +++ b/tasks/installapp.yml @@ -0,0 +1,17 @@ +--- + +- name: '[Install] - Create app dir' + file: + path: '{{ ninja_app_dir }}' + state: 'directory' + owner: '{{ ninja_app_username }}' + group: '{{ ninja_app_group }}' + +- name: "[INSTALL] - Download InvoiceNinja release" + unarchive: + src: "https://github.com/invoiceninja/invoiceninja/releases/download/{{ ninja_version }}/invoiceninja.tar" + dest: "{{ ninja_app_dir }}" + owner: '{{ ninja_app_username }}' + group: '{{ ninja_app_group }}' + remote_src: yes + diff --git a/tasks/installdeps.yml b/tasks/installdeps.yml new file mode 100644 index 0000000..685c30d --- /dev/null +++ b/tasks/installdeps.yml @@ -0,0 +1,6 @@ +--- + +- name: '[Deps] - Install Dependencies' + apt: + name: '{{ ninja_pkgs }}' + update_cache: yes diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..e0c3772 --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,14 @@ +--- + +- name: 'Include checks task' + include_tasks: 'check.yml' + +- name: 'Include dependencies install task' + include_tasks: 'installdeps.yml' + +- name: 'Include install app task' + include_tasks: 'installapp.yml' + when: 'ninja_installed.rc == 1' + +- name: 'Include configure app task' + include_tasks: 'configure.yml' diff --git a/templates/env.j2 b/templates/env.j2 new file mode 100644 index 0000000..e79cc2f --- /dev/null +++ b/templates/env.j2 @@ -0,0 +1,59 @@ +APP_NAME="{{ ninja_app_name }}" +APP_ENV={{ ninja_app_env }} +APP_KEY={{ ninja_app_key }} +APP_DEBUG="{{ ninja_app_debug }}" + +APP_URL="{{ ninja_app_url }}" +REACT_URL={{ ninja_react_url }} + +DB_CONNECTION="{{ ninja_db_connection }}" +MULTI_DB_ENABLED={{ ninja_multi_db }} + +DB_HOST="{{ ninja_db_host }}" +DB_DATABASE="{{ ninja_db_name }}" +DB_USERNAME="{{ ninja_db_user }}" +DB_PASSWORD="{{ ninja_db_passwd }}" +DB_PORT="{{ ninja_db_port }}" + +DEMO_MODE={{ ninja_demo_mode }} + +BROADCAST_DRIVER={{ ninja_broadcast_driver }} +LOG_CHANNEL={{ ninja_log_channel }} +CACHE_DRIVER={{ ninja_cache_driver }} +QUEUE_CONNECTION={{ ninja_queue_connection }} +SESSION_DRIVER={{ ninja_session_driver }} +SESSION_LIFETIME={{ ninja_session_lifetime }} + +REDIS_HOST={{ ninja_redis_host }} +REDIS_PASSWORD={{ ninja_redis_password }} +REDIS_PORT={{ ninja_redis_port }} + +MAIL_MAILER="{{ ninja_mailer }}" +MAIL_HOST="{{ ninja_mail_host }}" +MAIL_PORT="{{ ninja_mail_port }}" +MAIL_USERNAME="{{ ninja_mail_username }}" +MAIL_PASSWORD="{{ ninja_mail_password }}" +MAIL_ENCRYPTION="{{ ninja_mail_encryption }}" +MAIL_FROM_ADDRESS="{{ ninja_mail_addr }}" +MAIL_FROM_NAME="{{ ninja_mail_from_user }}" + +POSTMARK_API_TOKEN= +REQUIRE_HTTPS="true" + +GOOGLE_MAPS_API_KEY= +ERROR_EMAIL= +TRUSTED_PROXIES= + +NINJA_ENVIRONMENT="{{ ninja_environment }}" + +#options - snappdf / phantom / hosted_ninja +PDF_GENERATOR={{ ninja_pdf_generator }} + +PHANTOMJS_KEY='{{ ninja_phantomjs_key }}' +PHANTOMJS_SECRET={{ ninja_phantomjs_secret }} + +UPDATE_SECRET={{ ninja_update_secret }} + +DELETE_PDF_DAYS={{ ninja_delete_pdf_days }} +DELETE_BACKUP_DAYS={{ ninja_delete_backup_days }} +