commit 9ec8c3adf769f2e49854bab5b047bfdd029ae461 Author: muppeth Date: Thu Aug 22 15:04:11 2024 +0200 initial commit 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 }} +