Code Monkey home page Code Monkey logo

ansible's Introduction

Status Event
Code Testing Weekly schedule
Code Testing Last PR

Ansible Role: paperless_ngx

Installs and configures paperless-ngx EDMS.

1. Requirements

1.1. Ansible

ansible_version_minimum: "2.12" or newer is required.

The following Ansible collections need to be installed (via ansible-galaxy collection install)

  • community.general
  • ansible.posix

1.2. Supported operating systems

  • Debian (>=11)
  • Ubuntu (>=focal)

2. Role Variables

Most configuration variables from paperless-ngx itself are available and accept their respective arguments. Every PAPERLESS_* configuration variable is lowercased and instead prefixed with paperless_ngx_conf_* in defaults/main.yml.

For a full listing including explanations and allowed values, see the current documentation.

The following sections are devided into:

  • Role specific variables
  • Original paperless-ngx configuration variables

2.1. Role specific variables

Name Default Value Description
paperless_ngx_db_type sqlite Available db types are sqlite and postgresql. If postgresql is chosen then the other db_ vars must be configured too.
paperless_ngx_dependency_install_tmp_dir /tmp/ Directory for temporary dependency installation files
paperless_ngx_dir_force_permission_exclude [] Which directories should be skipped from permission check/setting. See docs.
paperless_ngx_dir_installation /opt/paperless-ngx The directory where paperless-ngx static installation files are written to.
paperless_ngx_dir_python /opt/python/{{ paperless_ngx_python_version_short }} The directory where python binaries are compiled to.
paperless_ngx_dir_runtime_data /var/lib/paperless-ngx The directory where the runtime data will be stored.
paperless_ngx_dir_virtualenv "{{ paperless_ngx_dir_installation }}/.venv" The directory for the needed python venv.
paperless_ngx_jbig2enc_enabled true Whether to install and use jbig2enc for OCRmyPDF.
paperless_ngx_jbig2enc_lossy false Run jbig2enc in lossy mode or not.
paperless_ngx_jbig2enc_version 0.29 Which version to install.
paperless_ngx_redis_host localhost Redis host
paperless_ngx_redis_port 6379 Redis port
paperless_ngx_system_group paperlessngx The group to which the system user belongs.
paperless_ngx_system_user paperlessngx The user that will execute the services and own the data.
paperless_ngx_system_user_additional_groups [] Optionally add the system user to more groups. For example to read TLS certificates that can be read by the group ssl-cert.
paperless_ngx_version latest Sofware version to install. Use latest or any specific version in the format '2.0.0'. Only paperless_ngx_version_minimum: '2.0.0' and higher supported.
``

2.2. Paperless-ngx configuration variables

All the upcoming vars correspond with the vars from paperless-ngx docs. The following list of variables is sorted alphabetically to simplify maintenance of this role. In the official documentation, these are assigned to corresponding categories.

To save reading space a few abbreviations are used in the table down below:

  • I - Implemented in this role? [Y/N]
  • O - Variable is meant to be overridden? [Y/N] If No it should not be altered.
  • H - Hint
  • V - Version of paperless-ngx that introduced this var.
Name Default Value I O H V
paperless_ngx_conf_account_allow_signups false Y Y 2.5
paperless_ngx_conf_account_default_http_protocol https Y Y 2.5
paperless_ngx_conf_account_email_verification optional Y Y 2.6
paperless_ngx_conf_account_session_remember false Y Y 2.7
paperless_ngx_conf_admin_mail root@localhost Y Y
paperless_ngx_conf_admin_password Y Y The superuser password. If not defined by the user, a random password will be generated -> see section below about passwords.
paperless_ngx_conf_admin_user admin Y Y
paperless_ngx_conf_allowed_hosts "*" Y Y
paperless_ngx_conf_app_logo None Y Y 2.4
paperless_ngx_conf_app_title None Y Y 2.4
paperless_ngx_conf_apps None Y Y 2.5
paperless_ngx_conf_audit_log_enabled false Y Y 2.0
paperless_ngx_conf_auto_login_username "" Y Y
paperless_ngx_conf_bind_addr "[::]" Y Y
paperless_ngx_conf_consumer_asn_barcode_prefix ASN Y Y 1.12
paperless_ngx_conf_consumer_collate_double_sided_subdir_name "double-sided" Y Y 1.17
paperless_ngx_conf_consumer_collate_double_sided_tiff_support false Y Y 1.17
paperless_ngx_conf_consumer_barcode_dpi 300 Y Y 1.16
paperless_ngx_conf_consumer_barcode_scanner "PYZBAR" Y Y 1.14
paperless_ngx_conf_consumer_barcode_string 'PATCHT' Y Y
paperless_ngx_conf_consumer_barcode_tiff_support false Y Y
paperless_ngx_conf_consumer_barcode_upscale 0.0 Y Y 1.16
paperless_ngx_conf_consumer_delete_duplicates false Y Y
paperless_ngx_conf_consumer_enable_asn_barcode false Y Y 1.12
paperless_ngx_conf_consumer_enable_barcodes false Y Y
paperless_ngx_conf_consumer_enable_collate_double_sided false Y Y 1.17
paperless_ngx_conf_consumer_enable_tag_barcode false Y Y 2.5
paperless_ngx_conf_consumer_ignore_patterns [".DS_STORE/", "._", ".stfolder/", ".stversions/", ".localized/*", "desktop.ini"] Y Y
paperless_ngx_conf_consumer_inotify_delay 0.5 Y Y
paperless_ngx_conf_consumer_polling_delay 5 Y Y
paperless_ngx_conf_consumer_polling_retry_count 5 Y Y
paperless_ngx_conf_consumer_polling 0 Y Y
paperless_ngx_conf_consumer_recursive false Y Y
paperless_ngx_conf_consumer_subdirs_as_tags false Y Y
paperless_ngx_conf_consumer_tag_barcode_mapping '{"TAG:(.*)": "\\g<1>"}' Y Y 2.5
paperless_ngx_conf_consumption_dir "{{ paperless_ngx_dir_runtime_data }}/consumption" Y Y
paperless_ngx_conf_convert_binary convert Y Y
paperless_ngx_conf_convert_memory_limit 0 Y Y
paperless_ngx_conf_convert_tmpdir "" Y Y
paperless_ngx_conf_cookie_prefix "" Y Y
paperless_ngx_conf_cors_allowed_hosts http://localhost:8000 Y Y
paperless_ngx_conf_csrf_trusted_origins Y Y
paperless_ngx_conf_data_dir "{{ paperless_ngx_dir_runtime_data }}/data" Y Y
paperless_ngx_conf_date_order "DMY" Y Y
paperless_ngx_conf_db_timeout Y Y
paperless_ngx_conf_dbengine Y N Not used by the role
paperless_ngx_conf_dbhost localhost Y Y
paperless_ngx_conf_dbname paperlessngx Y Y
paperless_ngx_conf_dbpass "" Y Y The db password. If not defined by the user, a random password will be generated -> see section below about passwords.
paperless_ngx_conf_dbport 5432 Y Y
paperless_ngx_conf_dbsslcert None Y Y 1.14
paperless_ngx_conf_dbsslkey None Y Y 1.14
paperless_ngx_conf_dbsslmode prefer Y Y
paperless_ngx_conf_dbsslrootcert None Y Y 1.14
paperless_ngx_conf_dbuser paperlessngx Y Y
paperless_ngx_conf_disable_regular_login false Y Y 2.6
paperless_ngx_conf_email_certificate_location None Y Y 1.17
paperless_ngx_conf_email_from {{ paperless_ngx_conf_email_host_user }} Y Y 2.0
paperless_ngx_conf_email_host "localhost" Y Y 2.0
paperless_ngx_conf_email_host_user "" Y Y 2.0
paperless_ngx_conf_email_host_password "" Y Y 2.0
paperless_ngx_conf_email_port 25 Y Y 2.0
paperless_ngx_conf_email_task_cron "*/10 * * * *" Y Y 1.12
paperless_ngx_conf_email_use_ssl false Y Y 2.0
paperless_ngx_conf_email_use_tls false Y Y 2.0
paperless_ngx_conf_enable_compression true Y Y 1.13
paperless_ngx_conf_enable_flower false Y Y Whether to start flower or not. See using flower for more information 1.10
paperless_ngx_conf_enable_http_remote_user false Y Y
paperless_ngx_conf_enable_http_remote_user_api false Y Y 2.5
paperless_ngx_conf_enable_nltk 1 Y Y 1.11
paperless_ngx_conf_enable_update_check Y Y Will be removed in the future
paperless_ngx_conf_filename_date_order "" Y Y
paperless_ngx_conf_filename_format_remove_none false Y Y
paperless_ngx_conf_filename_format "" Y Y
paperless_ngx_conf_force_script_name "" Y Y
paperless_ngx_conf_gs_binary gs Y Y
paperless_ngx_conf_http_remote_user_header_name HTTP_REMOTE_USER Y Y
paperless_ngx_conf_ignore_dates "" Y Y
paperless_ngx_conf_index_task_cron "0 0 * * *" Y Y 1.12
paperless_ngx_conf_logging_dir "{{ paperless_ngx_dir_runtime_data }}/log"
paperless_ngx_conf_logout_redirect_url Y Y
paperless_ngx_conf_logrotate_max_backups 20 Y Y
paperless_ngx_conf_logrotate_max_size 1024 * 1024 Y Y
paperless_ngx_conf_max_image_pixels None Y Y 2.6
paperless_ngx_conf_media_root "{{ paperless_ngx_dir_runtime_data }}/media" Y Y
paperless_ngx_conf_nltk_dir /usr/share/nltk_data Y Y 1.11
paperless_ngx_conf_number_of_suggested_dates 3 Y Y
paperless_ngx_conf_ocr_clean clean Y Y
paperless_ngx_conf_ocr_color_conversion_strategy "RGB" Y Y 2.1
paperless_ngx_conf_ocr_deskew true Y Y
paperless_ngx_conf_ocr_image_dpi "" Y Y
paperless_ngx_conf_ocr_language eng Y Y
paperless_ngx_conf_ocr_languages [eng,deu,fra,ita,spa] Y Y
paperless_ngx_conf_ocr_max_image_pixels Y Y
paperless_ngx_conf_ocr_mode skip Y Y
paperless_ngx_conf_ocr_output_type pdfa Y Y
paperless_ngx_conf_ocr_pages 0 Y Y
paperless_ngx_conf_ocr_rotate_pages_threshold 12 Y Y
paperless_ngx_conf_ocr_rotate_pages true Y Y
paperless_ngx_conf_ocr_skip_archive_file "never" Y Y 1.14
paperless_ngx_conf_ocr_user_args [optimize=1] Y Y
paperless_ngx_conf_port 8000 Y Y
paperless_ngx_conf_post_consume_script "" Y Y
paperless_ngx_conf_pre_consume_script "" Y Y
paperless_ngx_conf_proxy_ssl_header None Y Y 1.14
paperless_ngx_conf_redis redis://{{ paperless_ngx_redis_host }}:{{ paperless_ngx_redis_port }} Y N
paperless_ngx_conf_redis_prefix "" Y Y 1.17
paperless_ngx_conf_sanity_task_cron "30 0 * * sun" Y Y 1.12
paperless_ngx_conf_secret_key "" Y Y If not defined by the user, a random password will be generated -> see section below about passwords.
paperless_ngx_conf_social_auto_signup false Y Y 2.5
paperless_ngx_conf_socialaccount_allow_signups true Y Y 2.5
paperless_ngx_conf_socialaccount_providers "{}" Y Y 2.5
paperless_ngx_conf_static_url /static/ Y Y
paperless_ngx_conf_staticdir ../static Y N
paperless_ngx_conf_supervisord_working_dir None Y Y 2.5
paperless_ngx_conf_task_workers 1 Y Y
paperless_ngx_conf_threads_per_worker paperless_ngx_conf_task_workers Y Y
paperless_ngx_conf_thumbnail_font_name /usr/share/fonts/liberation/LiberationSerif-Regular.ttf Y Y
paperless_ngx_conf_tika_enabled false Y Y
paperless_ngx_conf_tika_endpoint http://localhost:9998 Y Y
paperless_ngx_conf_tika_gotenberg_endpoint http://localhost:3000 Y Y
paperless_ngx_conf_time_zone Europe/London Y Y
paperless_ngx_conf_train_task_cron "5 */1 * * *" Y Y 1.12
paperless_ngx_conf_trash_dir "{{ paperless_ngx_dir_runtime_data }}/trash" Y Y
paperless_ngx_conf_trusted_proxies "" Y Y 1.14
paperless_ngx_conf_url http://localhost:8000 Y Y
paperless_ngx_conf_use_x_forward_host False Y Y 1.14
paperless_ngx_conf_use_x_forward_port False Y Y 1.14
paperless_ngx_conf_usermap_gid Y Y System users gid
paperless_ngx_conf_usermap_uid Y Y System users id
paperless_ngx_conf_webserver_workers 1 Y Y
paperless_ngx_conf_worker_timeout 1800 Y Y

3. Usage advices

3.1. Updating Paperless-ngx

If you installed Paperless-ngx with the help of this role and you want to update to a newer version than all you have to do is to run this role again (if you chose latest as the version identifier). If you specified a specific version to install than all you need to do is to change this value to a newer one and run the role again.

This role will not update anything else than Paperless-ngx. So updates for the operating system and depended packages need to be handled seperately.

PLEASE THINK ABOUT BACKUPS before you upgrade.

3.2. Backup/Restore

Please be aware that this role does not offer any mechanism of backup or restore. This is intention. To seperate concerns this role is only focused towards 'deployments' of the software artifacts and its configuration. An example of a working backup strategy can be found here: Link to example backup strategy

3.3. Generated password

The role uses Ansible's password lookup:

  • If a password is generated by the role, ansible stores it locally in pngx_instances/{{ incentory_hostname }}/ (relative to the working directory)
  • if the file already exist, it reuse its content
  • see the ansible password lookup documentation for more info

3.4. Separation of static (~ installation) and dynamic (~ runtime) data

This role checks that you do not set one of the data dirs (like consumption etc.) as a subdirectory of the installation path. For making my life easier this role deletes the installation folder and creates a complete new one when upgrading. This is fresh and clean. Also this way you are kept from unwanted deletions of your data during upgrades.

3.5. PostgreSQL usage

If you want to use Paperless-ngx together with PostgreSQL a running instance of PostgreSQL is required. This role does not automatically install such a database instance for you. However, here is you can read an example how to set up such an instance from scretch: Link to example playbook

4. Dependencies

No dependencies

5. Example Playbooks

minimal_runnable_playbook.yml:

- hosts: all
    roles:
        - { role: paperless_ngx.paperless_ngx }
    vars:
        var1:
        var2:
        ...

6. Contributing

We encourage you to contribute to this role! Please check out the contributing guide for guidelines about how to proceed.

7. License

MIT

ansible's People

Contributors

ajkavanagh avatar c0nsultant avatar dependabot[bot] avatar felbinger avatar gamerbene19 avatar github-actions[bot] avatar jonaswinkler avatar klonfish avatar muued avatar qcasey avatar s4nf4n avatar shamoon avatar sim22 avatar stevenengland avatar stumpylog avatar tribut avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

ansible's Issues

OS packages missing during installation

Hi there,

it seems that there are missing packages during the installation. Status quo:

- name: install base dependencies
  ansible.builtin.apt:
    update_cache: true
    pkg:
      # paperless-ngx
      - python3-pip
      - python3-dev
      - fonts-liberation
      - imagemagick
      - optipng
      - gnupg
      - libpq-dev
      - libmagic-dev
      - mime-support
      - libzbar0
      - poppler-utils
      # OCRmyPDF
      - unpaper
      - ghostscript
      - icc-profiles-free
      - qpdf
      - liblept5
      - libxml2
      - pngquant
      - zlib1g
      - tesseract-ocr
      # Dev
      - sudo
      - build-essential
      - python3-setuptools
      - python3-wheel
      - python3-venv
      - git
      - python3-jmespath

This differs from the instructions here: https://docs.paperless-ngx.com/setup/#bare_metal

At least I found default-libmysqlclient-dev being a very needed package. Otherwise the pip dependency installation task fails with:

    :stderr:   error: subprocess-exited-with-error
  
      × python setup.py egg_info did not run successfully.
      │ exit code: 1
      ╰─> [16 lines of output]
          /bin/sh: 1: mysql_config: not found
          /bin/sh: 1: mariadb_config: not found
          /bin/sh: 1: mysql_config: not found
          Traceback (most recent call last):
            File "<string>", line 2, in <module>
            File "<pip-setuptools-caller>", line 34, in <module>
            File "/tmp/pip-install-853bk2d2/mysqlclient_730a1d807bf14991b1f30e4563f4e54b/setup.py", line 15, in <module>
              metadata, options = get_config()
            File "/tmp/pip-install-853bk2d2/mysqlclient_730a1d807bf14991b1f30e4563f4e54b/setup_posix.py", line 70, in get_config
              libs = mysql_config("libs")
            File "/tmp/pip-install-853bk2d2/mysqlclient_730a1d807bf14991b1f30e4563f4e54b/setup_posix.py", line 31, in mysql_config
              raise OSError("{} not found".format(_mysql_config_path))
          OSError: mysql_config not found
          mysql_config --version
          mariadb_config --version
          mysql_config --libs
          [end of output]
  
      note: This error originates from a subprocess, and is likely not a problem with pip.
    error: metadata-generation-failed
  
    × Encountered error while generating package metadata.
    ╰─> See above for output.
  
    note: This is an issue with the package mentioned above, not pip.

tika service seems to be unreachable

Hey everybody,

though, Tika is enabled via

paperless_ngx_conf_tika_enabled: true

the service seems to be unreachable on the host, the ansible playbook is running on.

Error occurred while consuming document some-email.eml: Could not parse content with tika server at http://localhost:9998: [Errno 111] Connection refused

How can I check if Tika is running?

Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user

Hi there,

when a task as an unpriviliged user and the task is executed with become_user different to root then the following error occurs (applies to this roles task named "create paperlessng venv")

TASK [paperless-ngx : create paperlessng venv] *****************************************************************************************************************************************************************************************************************************fatal: [paperless_ngx]: FAILED! =>
  msg: |-
    Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user (rc: 1, err: chmod: invalid mode: 'A+user:paperlessng:rx:allow'
    Try 'chmod --help' for more information.
    }). For information on working around this, see https://docs.ansible.com/ansible-core/2.13/user_guide/become.html#risks-of-becoming-an-unprivileged-user

A short workaround on this is to install the "acl" package. But I did not yet investigate the sideeffects of doing so. I don't know yet if this is a good idea to handle this scenario in general.

Reconfigure paperlessng_listen_address on second playbook run

Hello Team,
At first let me thank you for this Ansible role. I was writing one of my own and almost finished when I found this project. It's great. Thank you for it.

I've found an unexpected behaviour though which I would like to address here. I installed paperless-ngx on a host using the following playbook:

---
- hosts: paperless-ngx.example.com
  tasks:
    - name: Make sure pip3 is installed
      apt:
       name: python3-pip
       state: latest

    - name: Include role ansible-role-paperless-ngx
      include_role:
        name: ansible-role-paperless-ngx
      vars:
        paperlessng_secret_key: >-
          lookup('community.general.random_string', base64=True, length=64)
        paperlessng_listen_address: 127.0.0.1

Paperless is listening on socket 127.0.0.1:8000:

# ss -ltn
State          Recv-Q         Send-Q                 Local Address:Port                 Peer Address:Port         Process         
LISTEN         0              2048                       127.0.0.1:8000                      0.0.0.0:*                            
LISTEN         0              511                        127.0.0.1:6379                      0.0.0.0:*                            
LISTEN         0              128                          0.0.0.0:22                        0.0.0.0:*

Now I changed the listening address to paperlessng_listen_address: 0.0.0.0 and ran the playbook again. But the service keeps listening on 127.0.0.1:8000. I would expect to change the socket with the second run.

My guess is, that the services just needs to be reloaded or rather restarted. Can someone confirm this behaviour and is it possible to fix it?

Best regards,
Tronde

Future of this repo?

Hi guys,

do you have any plans to further support this Ansible role? I absolutely love the work you're doing with paperless-ngx and would absolutely get it if it is too much work to also support this role any further. But a statement would be great.

Anyway. As a part of a learning journey I recreated the role in my personal space. I will definitely keep on working on the role for a while because there is so much to learn :-) And because I am highly interested in a deterministic installation of paperless-ngx for LXC. So if you do not plan to fully support a Ansible role anymore I could imagine to dig into that whole thing even deeper and might maintain it for longer / broader purpose. Let me know what you think.

KR

molecule create fails at TASK [ansible : change owner and permissions of paperless-ngx]

When using a up to date ansible version molecule create (and possibly every playbook) fails at TASK [ansible : change owner and permissions of paperless-ngx] with error message:

TASK [ansible : change owner and permissions of paperless-ngx] *****************
failed: [ansible-paperless-ngx-systemd-ubuntu-20.04] (item=chown -R paperlessng:paperlessng /opt/ansible.ngl3rz19tempgit) => {"ansible_loop_var": "item", "changed": false, "item": "chown -R paperlessng:paperlessng /opt/ansible.ngl3rz19tempgit", "msg": "Unsupported parameters for (ansible.legacy.command) module: warn. Supported parameters include: chdir, removes, stdin_add_newline, _raw_params, _uses_shell, executable, argv, stdin, strip_empty_ends, creates."}
failed: [ansible-paperless-ngx-systemd-ubuntu-20.04] (item=find /opt/ansible.ngl3rz19tempgit -type d -exec chmod 0750 {} ;) => {"ansible_loop_var": "item", "changed": false, "item": "find /opt/ansible.ngl3rz19tempgit -type d -exec chmod 0750 {} ;", "msg": "Unsupported parameters for (ansible.legacy.command) module: warn. Supported parameters include: stdin, chdir, creates, stdin_add_newline, _raw_params, argv, executable, strip_empty_ends, removes, _uses_shell."}
failed: [ansible-paperless-ngx-systemd-ubuntu-20.04] (item=find /opt/ansible.ngl3rz19tempgit -type f -exec chmod 0640 {} ;) => {"ansible_loop_var": "item", "changed": false, "item": "find /opt/ansible.ngl3rz19tempgit -type f -exec chmod 0640 {} ;", "msg": "Unsupported parameters for (ansible.legacy.command) module: warn. Supported parameters include: executable, removes, creates, stdin_add_newline, _raw_params, _uses_shell, argv, stdin, chdir, strip_empty_ends."}

That is because the warn argument was deprecated (and removed):
ansible/ansible#70746 (comment)
ansible/ansible#70504

TASK Compare versions of installed ansible and required ansible does not recognize ansible-core package

Hi,
I was trying to use Fedora 37 with ansible-core package installed as Ansible controller to run this role to install paperless-ngx to a Debian node. The playbook failed at the task mentioned in the title of this issue.

What Ansible version do you use?

$ ansible-playbook --version
ansible-playbook [core 2.14.3]
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/home/tronde/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.11/site-packages/ansible
  ansible collection location = /home/tronde/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible-playbook
  python version = 3.11.2 (main, Feb  8 2023, 00:00:00) [GCC 12.2.1 20221121 (Red Hat 12.2.1-4)] (/usr/bin/python3)
  jinja version = 3.0.3
  libyaml = True

What does the playbook looks like?

$ cat setup_paperless_ngx.yml 
---
- hosts: paperless-t1
  debugger: on_failed
  vars_files:
    - files/my.vars
  tasks:
    - name: Include role ansible-role-paperless-ngx
      include_role:
        name: ansible-role-paperless-ngx

Information from debugger

TASK [ansible-role-paperless-ngx : Compare versions of installed ansible and required ansible] ***
fatal: [paperless-t1]: FAILED! => {"msg": "The conditional check '_ansible_installed_version.stdout is version_compare(ansible_version_minimum, '>=')' failed. The error was: Input version value cannot be empty"}
[paperless-t1] TASK: ansible-role-paperless-ngx : Compare versions of installed ansible and required ansible (debug)> p task.args
{'msg': '"You must update Ansible to at least 4.0.0 to use this role."\n',
 'that': '_ansible_installed_version.stdout is '
         "version_compare(ansible_version_minimum, '>=')"}
[paperless-t1] TASK: ansible-role-paperless-ngx : Compare versions of installed ansible and required ansible (debug)> p task_vars['ansible_version_minimum']
'4.0.0'
[paperless-t1] TASK: ansible-role-paperless-ngx : Compare versions of installed ansible and required ansible (debug)> p task_vars['_ansible_installed_version.stdout']
***KeyError:KeyError('_ansible_installed_version.stdout')
[paperless-t1] TASK: ansible-role-paperless-ngx : Compare versions of installed ansible and required ansible (debug)> p task_vars['_ansible_installed_version']
{'changed': False,
 'cmd': "python3 -m pip show ansible | grep Version | cut -d ' ' -f 2",
 'delta': '0:00:00.540653',
 'end': '2023-03-27 21:52:17.238333',
 'failed': False,
 'msg': '',
 'rc': 0,
 'start': '2023-03-27 21:52:16.697680',
 'stderr': 'WARNING: Package(s) not found: ansible',
 'stderr_lines': ['WARNING: Package(s) not found: ansible'],
 'stdout': '',
 'stdout_lines': []}
[paperless-t1] TASK: ansible-role-paperless-ngx : Compare versions of installed ansible and required ansible (debug)>

Since I have installed ansible-core from the RPM repository of my distribution and not via pip the version check failed and cannot succeed.

I'm not sure whether this is a Bug or a missing Feature. As the ansible community package depends on the ansible-core package [0] and Ansible 7.x is based on ansible-core 2.14 [1] my installation should meet the requirements.

I appreciate if you take the time to look into it. Do you think you can change the role, so it will work with ansible-core?

Best regards,
Tronde

[0] Releases and maintenance
[1] Ansible community changelogs

Python Default Environment Jammy > 3.9

Hello Team,

Thanks alot for this Ansible role.
Though I couldnt help but notice that the default python version is 3.10.4 (https://packages.ubuntu.com/jammy/amd64/python3)
This collides with the Max version of Python allowed in the latest version of paperless-ngx being 3.9 according to the following lines in the requirements.txt:

importlib-resources==5.10.0 ; python_version < '3.9'
backports.zoneinfo==0.2.1 ; python_version < '3.9'

Thus it crashes with the following error message.

fatal: [paperless-01
]: FAILED! => {
  "changed": false,
  "cmd": [
    "/opt/paperless-ngx/.venv/bin/pip3",
    "install",
    "--upgrade",
    "-r",
    "/opt/paperless-ngx/requirements.txt"
  ],
  "msg": "stdout: Looking in indexes: https://pypi.python.org/simple, https://www.piwheels.org/simple\nIgnoring backports.zoneinfo: markers 'python_version < \"3.9\"' don't match your environment\nIgnoring importlib-resources: markers 'python_version < \"3.9\"' don't match your environment\nIgnoring zipp: markers 'python_version < \"3.9\"' don't match your environment\nCollecting aioredis==1.3.1\n  Downloading https://www.piwheels.org/simple/aioredis/aioredis-1.3.1-py3-none-any.whl (65 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 65.3/65.3 kB 2.2 MB/s eta 0:00:00\nCollecting amqp==5.1.1\n  Downloading https://www.piwheels.org/simple/amqp/amqp-5.1.1-py3-none-any.whl (50 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 50.8/50.8 kB 8.5 MB/s eta 0:00:00\nCollecting anyio==3.6.2\n  Downloading https://www.piwheels.org/simple/anyio/anyio-3.6.2-py3-none-any.whl (80 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.6/80.6 kB 3.5 MB/s eta 0:00:00\nCollecting asgiref==3.5.2\n  Downloading https://www.piwheels.org/simple/asgiref/asgiref-3.5.2-py3-none-any.whl (22 kB)\nCollecting async-timeout==4.0.2\n  Downloading https://www.piwheels.org/simple/async-timeout/async_timeout-4.0.2-py3-none-any.whl (5.8 kB)\nCollecting attrs==22.1.0\n  Downloading https://www.piwheels.org/simple/attrs/attrs-22.1.0-py2.py3-none-any.whl (58 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 58.8/58.8 kB 11.2 MB/s eta 0:00:00\nCollecting autobahn==22.7.1\n  Downloading autobahn-22.7.1.tar.gz (476 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 476.8/476.8 kB 7.3 MB/s eta 0:00:00\n  Preparing metadata (setup.py): started\n  Preparing metadata (setup.py): finished with status 'done'\nCollecting automat==22.10.0\n  Downloading https://www.piwheels.org/simple/automat/Automat-22.10.0-py2.py3-none-any.whl (26 kB)\nCollecting billiard==3.6.4.0\n  Downloading https://www.piwheels.org/simple/billiard/billiard-3.6.4.0-py3-none-any.whl (89 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 89.5/89.5 kB 3.9 MB/s eta 0:00:00\nCollecting celery[redis]==5.2.7\n  Downloading https://www.piwheels.org/simple/celery/celery-5.2.7-py3-none-any.whl (405 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 405.6/405.6 kB 9.7 MB/s eta 0:00:00\nCollecting certifi==2022.9.24\n  Downloading https://www.piwheels.org/simple/certifi/certifi-2022.9.24-py3-none-any.whl (161 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 161.1/161.1 kB 13.2 MB/s eta 0:00:00\nCollecting cffi==1.15.1\n  Downloading cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (441 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 441.8/441.8 kB 16.8 MB/s eta 0:00:00\nCollecting channels==3.0.5\n  Downloading https://www.piwheels.org/simple/channels/channels-3.0.5-py3-none-any.whl (38 kB)\nCollecting channels-redis==3.4.1\n  Downloading https://www.piwheels.org/simple/channels-redis/channels_redis-3.4.1-py3-none-any.whl (20 kB)\nCollecting charset-normalizer==2.1.1\n  Downloading https://www.piwheels.org/simple/charset-normalizer/charset_normalizer-2.1.1-py3-none-any.whl (39 kB)\nCollecting click==8.1.3\n  Downloading https://www.piwheels.org/simple/click/click-8.1.3-py3-none-any.whl (96 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 96.6/96.6 kB 3.9 MB/s eta 0:00:00\nCollecting click-didyoumean==0.3.0\n  Downloading https://www.piwheels.org/simple/click-didyoumean/click_didyoumean-0.3.0-py3-none-any.whl (2.7 kB)\nCollecting click-plugins==1.1.1\n  Downloading https://www.piwheels.org/simple/click-plugins/click_plugins-1.1.1-py2.py3-none-any.whl (7.5 kB)\nCollecting click-repl==0.2.0\n  Downloading https://www.piwheels.org/simple/click-repl/click_repl-0.2.0-py3-none-any.whl (5.2 kB)\nCollecting coloredlogs==15.0.1\n  Downloading https://www.piwheels.org/simple/coloredlogs/coloredlogs-15.0.1-py2.py3-none-any.whl (46 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 46.0/46.0 kB 8.6 MB/s eta 0:00:00\nCollecting concurrent-log-handler==0.9.20\n  Downloading https://www.piwheels.org/simple/concurrent-log-handler/concurrent_log_handler-0.9.20-py2.py3-none-any.whl (25 kB)\nCollecting constantly==15.1.0\n  Downloading https://www.piwheels.org/simple/constantly/constantly-15.1.0-py2.py3-none-any.whl (7.9 kB)\nCollecting cryptography==38.0.1\n  Downloading cryptography-38.0.1-cp36-abi3-manylinux_2_28_x86_64.whl (4.2 MB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.2/4.2 MB 31.0 MB/s eta 0:00:00\nCollecting daphne==3.0.2\n  Downloading https://www.piwheels.org/simple/daphne/daphne-3.0.2-py3-none-any.whl (26 kB)\nCollecting dateparser==1.1.3\n  Downloading https://www.piwheels.org/simple/dateparser/dateparser-1.1.3-py2.py3-none-any.whl (292 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 292.7/292.7 kB 6.2 MB/s eta 0:00:00\nCollecting deprecated==1.2.13\n  Downloading https://www.piwheels.org/simple/deprecated/Deprecated-1.2.13-py2.py3-none-any.whl (9.5 kB)\nCollecting deprecation==2.1.0\n  Downloading https://www.piwheels.org/simple/deprecation/deprecation-2.1.0-py2.py3-none-any.whl (11 kB)\nCollecting django==4.1.3\n  Downloading https://www.piwheels.org/simple/django/Django-4.1.3-py3-none-any.whl (8.1 MB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.1/8.1 MB 4.4 MB/s eta 0:00:00\nCollecting django-celery-results==2.4.0\n  Downloading https://www.piwheels.org/simple/django-celery-results/django_celery_results-2.4.0-py3-none-any.whl (36 kB)\nCollecting django-cors-headers==3.13.0\n  Downloading https://www.piwheels.org/simple/django-cors-headers/django_cors_headers-3.13.0-py3-none-any.whl (13 kB)\nCollecting django-extensions==3.2.1\n  Downloading https://www.piwheels.org/simple/django-extensions/django_extensions-3.2.1-py3-none-any.whl (229 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 229.4/229.4 kB 10.8 MB/s eta 0:00:00\nCollecting django-filter==22.1\n  Downloading https://www.piwheels.org/simple/django-filter/django_filter-22.1-py3-none-any.whl (80 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.9/80.9 kB 20.9 MB/s eta 0:00:00\nCollecting djangorestframework==3.14.0\n  Downloading https://www.piwheels.org/simple/djangorestframework/djangorestframework-3.14.0-py3-none-any.whl (1.1 MB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 4.9 MB/s eta 0:00:00\nCollecting filelock==3.8.0\n  Downloading https://www.piwheels.org/simple/filelock/filelock-3.8.0-py3-none-any.whl (10 kB)\nCollecting flower==1.2.0\n  Downloading https://www.piwheels.org/simple/flower/flower-1.2.0-py2.py3-none-any.whl (410 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 410.7/410.7 kB 7.5 MB/s eta 0:00:00\nCollecting gunicorn==20.1.0\n  Downloading https://www.piwheels.org/simple/gunicorn/gunicorn-20.1.0-py3-none-any.whl (81 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 81.0/81.0 kB 24.3 MB/s eta 0:00:00\nCollecting h11==0.14.0\n  Downloading https://www.piwheels.org/simple/h11/h11-0.14.0-py3-none-any.whl (58 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 58.3/58.3 kB 10.4 MB/s eta 0:00:00\nCollecting hiredis==2.0.0\n  Downloading hiredis-2.0.0.tar.gz (75 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 75.8/75.8 kB 14.4 MB/s eta 0:00:00\n  Preparing metadata (setup.py): started\n  Preparing metadata (setup.py): finished with status 'done'\nCollecting httptools==0.5.0\n  Downloading httptools-0.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (414 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 414.1/414.1 kB 41.8 MB/s eta 0:00:00\nCollecting humanfriendly==10.0\n  Downloading https://www.piwheels.org/simple/humanfriendly/humanfriendly-10.0-py2.py3-none-any.whl (89 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 89.9/89.9 kB 4.7 MB/s eta 0:00:00\nCollecting humanize==4.4.0\n  Downloading https://www.piwheels.org/simple/humanize/humanize-4.4.0-py3-none-any.whl (106 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 106.6/106.6 kB 14.8 MB/s eta 0:00:00\nCollecting hyperlink==21.0.0\n  Downloading https://www.piwheels.org/simple/hyperlink/hyperlink-21.0.0-py2.py3-none-any.whl (74 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 74.6/74.6 kB 11.4 MB/s eta 0:00:00\nCollecting idna==3.4\n  Downloading https://www.piwheels.org/simple/idna/idna-3.4-py3-none-any.whl (61 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 61.5/61.5 kB 20.4 MB/s eta 0:00:00\nCollecting imap-tools==0.57.0\n  Downloading https://www.piwheels.org/simple/imap-tools/imap_tools-0.57.0-py3-none-any.whl (31 kB)\nCollecting img2pdf==0.4.4\n  Downloading https://www.piwheels.org/simple/img2pdf/img2pdf-0.4.4-py3-none-any.whl (47 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 47.3/47.3 kB 9.9 MB/s eta 0:00:00\nCollecting incremental==22.10.0\n  Downloading https://www.piwheels.org/simple/incremental/incremental-22.10.0-py2.py3-none-any.whl (16 kB)\nCollecting inotify-simple==1.3.5\n  Downloading https://www.piwheels.org/simple/inotify-simple/inotify_simple-1.3.5-py3-none-any.whl (9.4 kB)\nCollecting inotifyrecursive==0.3.5\n  Downloading https://www.piwheels.org/simple/inotifyrecursive/inotifyrecursive-0.3.5-py3-none-any.whl (8.0 kB)\nCollecting joblib==1.2.0\n  Downloading https://www.piwheels.org/simple/joblib/joblib-1.2.0-py3-none-any.whl (297 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 298.0/298.0 kB 4.8 MB/s eta 0:00:00\nCollecting kombu==5.2.4\n  Downloading https://www.piwheels.org/simple/kombu/kombu-5.2.4-py3-none-any.whl (189 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 189.2/189.2 kB 9.9 MB/s eta 0:00:00\nCollecting langdetect==1.0.9\n  Downloading https://www.piwheels.org/simple/langdetect/langdetect-1.0.9-py3-none-any.whl (994 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 994.5/994.5 kB 16.8 MB/s eta 0:00:00\nCollecting lxml==4.9.1\n  Downloading lxml-4.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (6.9 MB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.9/6.9 MB 73.1 MB/s eta 0:00:00\nCollecting msgpack==1.0.4\n  Downloading msgpack-1.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (316 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 317.0/317.0 kB 52.4 MB/s eta 0:00:00\nCollecting mysqlclient==2.1.1\n  Downloading mysqlclient-2.1.1.tar.gz (88 kB)\n     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 88.1/88.1 kB 16.0 MB/s eta 0:00:00\n  Preparing metadata (setup.py): started\n  Preparing metadata (setup.py): finished with status 'error'\n\n:stderr:   error: subprocess-exited-with-error\n  \n  × python setup.py egg_info did not run successfully.\n  │ exit code: 1\n  ╰─> [16 lines of output]\n      /bin/sh: 1: mysql_config: not found\n      /bin/sh: 1: mariadb_config: not found\n      /bin/sh: 1: mysql_config: not found\n      Traceback (most recent call last):\n        File \"<string>\", line 2, in <module>\n        File \"<pip-setuptools-caller>\", line 34, in <module>\n        File \"/tmp/pip-install-l8m3bn71/mysqlclient_68a01191185a430d9d8ee71cfecff845/setup.py\", line 15, in <module>\n          metadata, options = get_config()\n        File \"/tmp/pip-install-l8m3bn71/mysqlclient_68a01191185a430d9d8ee71cfecff845/setup_posix.py\", line 70, in get_config\n          libs = mysql_config(\"libs\")\n        File \"/tmp/pip-install-l8m3bn71/mysqlclient_68a01191185a430d9d8ee71cfecff845/setup_posix.py\", line 31, in mysql_config\n          raise OSError(\"{} not found\".format(_mysql_config_path))\n      OSError: mysql_config not found\n      mysql_config --version\n      mariadb_config --version\n      mysql_config --libs\n      [end of output]\n  \n  note: This error originates from a subprocess, and is likely not a problem with pip.\nerror: metadata-generation-failed\n\n× Encountered error while generating package metadata.\n╰─> See above for output.\n\nnote: This is an issue with the package mentioned above, not pip.\nhint: See above for details.\n"
}

Is there anything I can help with to fix this?

Improve documentation for Install/Upgrade path

Seeing as this might start getting a bit more use, I have noticed there are some vars set within one of the steps that defines what tasks are actioned or not. This is something I will work on, just adding here for tracking/visibility/memory.

- name: register current state
  set_fact:
    fresh_installation: '{{ not paperlessng_current_commitfile.stat.exists }}'
    update_installation: false
    reconfigure_only: false

As is above it will do a fresh install, but if any of those change then the role will fail as it may or may no have done the prerequisites.

It is 1am so apologies if it does not make sense, will take a look in the morning and see if this issue reads ok. If not I will edit.

Failed to find required executable \"virtualenv\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

hi,

just tried the tests/test.yaml playbook within a fresh debian11 vagrant VM.
I created the venv via create_venv script and then activated it:

ansible-playbook tests/test.yml
TASK [paperless_ngx.paperless_ngx : Install latest pip] ***************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"changed": false, "msg": "Failed to find required executable \"virtualenv\" in paths: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}

PLAY RECAP ************************************************************************************************************************************************************************************
localhost                  : ok=51   changed=11   unreachable=0    failed=1    skipped=14   rescued=0    ignored=0   

(.venv) root@debian11:/home/vagrant/paperless-ngx# which virtualenv
/home/vagrant/paperless-ngx/.venv/bin/virtualenv

at this point, "virtualenv" is available for the root user (executing the playbook) but not the paperless user where
the venv is to be created. Guess the "virtualenv" package must be added to the regular debian package dependencies,
too.

Path of static dir cannot be changed

I am not sure if you intend to support it but:
If you change the location for

paperlessng_staticdir: "{{ paperlessng_directory }}/static"

Then the webserver will serve nothing as the installation does not copy the content from the source static dir to the target static dir.

Problem with checks for installed versions when initial installation failed

Hi there, when an initial installation failed somewhere after # 5 there is a chain of problems originating from this code:

# 1
- name: check for existing paperless-ngx version file
  ansible.builtin.stat:
    path: "{{ paperlessng_directory }}/.installed_version"
  register: paperlessng_current_commitfile

# 2
- name: get the current installed version as commit
  ansible.builtin.command:
    cmd: cat {{ paperlessng_directory }}/.installed_version
  changed_when: paperlessng_current_commit.stdout != paperlessng_commit | string
  failed_when: false
  ignore_errors: true
  register: paperlessng_current_commit
  when: paperlessng_current_commitfile.stat.exists

# 3
- name: register current state
  ansible.builtin.set_fact:
    fresh_installation: "{{ not paperlessng_current_commitfile.stat.exists }}"
    update_installation: false
    reconfigure_only: false
# 4
- name: register current existing state
  ansible.builtin.set_fact:
    update_installation: "{{ paperlessng_current_commit.stdout != paperlessng_commit | string }}"
    reconfigure_only: "{{ paperlessng_current_commit.stdout == paperlessng_commit | string }}"
  when: not fresh_installation

[...]

# 5
    - name: store commit hash of installed version
      ansible.builtin.copy:
        content: "{{ paperlessng_commit }}"
        dest: "{{ paperlessng_directory }}/.installed_version"
        owner: "{{ paperlessng_system_user }}"
        group: "{{ paperlessng_system_group }}"
        mode: "0440"

-# 5 registers a "installed" version very early. I think it should be executed at the end of the playbook. Because otherwise:

-# 1 checks for this "installed" version and then subsequent tasks like # 2, # 3, # 4 will do as if there was a complete installation which leads to wrong assumptions later in the role when checks for fresh_installation etc. are executed.

Like in my case:

TASK [paperless-ngx : configure paperless superuser] ***********************************************************************************************************************************************************************************************************************fatal: [paperless_ngx]: FAILED! => changed=false 
  cmd:
  - /opt/paperless-ngx/.venv/bin/python3
  - /opt/paperless-ngx/src/manage.py
  - manage_superuser
  delta: '0:00:00.040121'
  end: '2022-12-23 09:16:45.750421'
  msg: non-zero return code
  rc: 1
  start: '2022-12-23 09:16:45.710300'
  stderr: |-
    Traceback (most recent call last):
      File "/opt/paperless-ngx/src/manage.py", line 9, in <module>
        from django.core.management import execute_from_command_line
    ModuleNotFoundError: No module named 'django'
  stderr_lines: <omitted>
  stdout: ''
  stdout_lines: <omitted>

Because tasks before this one were skipped.

Debian 12 install virtualenv

Hey,

With a fresh Debian 12, the following error occurs during the first installation:

python3 -m pip.__main__ install --upgrade virtualenv
error: externally-managed-environment

× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
    python3-xyz, where xyz is the package you are trying to
    install.
    
    If you wish to install a non-Debian-packaged Python package,
    create a virtual environment using python3 -m venv path/to/venv.
    Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
    sure you have python3-full installed.
    
    If you wish to install a non-Debian packaged Python application,
    it may be easiest to use pipx install xyz, which will manage a
    virtual environment for you. Make sure you have pipx installed.
    
    See /usr/share/doc/python3.11/README.venv for more information.

note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.

The problem is due to the workaround for Ubuntu 20.04 .
This should not be used with Debian.

Install of latest version fails in Ubuntu 22.04 (latest LTS)

When I try to install the latest version of paperless (1.17). The install fails with

Error log
stdout:
Looking in indexes: https://pypi.python.org/simple, https://www.piwheels.org/simple
Ignoring backports.zoneinfo: markers 'python_version < \"3.9\"' don't match your environment
Ignoring importlib-resources: markers 'python_version < \"3.9\"' don't match your environment
Ignoring typing-extensions: markers 'python_version < \"3.10\"' don't match your environment
Ignoring zipp: markers 'python_version < \"3.10\"' don't match your environment
Collecting amqp==5.1.1 (from -r /opt/paperless-ngx/requirements.txt (line 3))
  Downloading https://www.piwheels.org/simple/amqp/amqp-5.1.1-py3-none-any.whl (50 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 50.8/50.8 kB 596.0 kB/s eta 0:00:00
Collecting anyio==3.7.1 (from -r /opt/paperless-ngx/requirements.txt (line 4))
  Downloading https://www.piwheels.org/simple/anyio/anyio-3.7.1-py3-none-any.whl (80 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.9/80.9 kB 847.8 kB/s eta 0:00:00
Collecting asgiref==3.7.2 (from -r /opt/paperless-ngx/requirements.txt (line 5))
  Downloading https://www.piwheels.org/simple/asgiref/asgiref-3.7.2-py3-none-any.whl (24 kB)
Collecting async-timeout==4.0.2 (from -r /opt/paperless-ngx/requirements.txt (line 6))
  Downloading https://www.piwheels.org/simple/async-timeout/async_timeout-4.0.2-py3-none-any.whl (5.8 kB)
Collecting billiard==4.1.0 (from -r /opt/paperless-ngx/requirements.txt (line 8))
  Downloading https://www.piwheels.org/simple/billiard/billiard-4.1.0-py3-none-any.whl (86 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 86.7/86.7 kB 913.5 kB/s eta 0:00:00
Collecting bleach==6.0.0 (from -r /opt/paperless-ngx/requirements.txt (line 9))
  Downloading https://www.piwheels.org/simple/bleach/bleach-6.0.0-py3-none-any.whl (162 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 162.5/162.5 kB 1.7 MB/s eta 0:00:00
Collecting brotli==1.0.9 (from -r /opt/paperless-ngx/requirements.txt (line 10))
  Downloading Brotli-1.0.9-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (2.7 MB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.7/2.7 MB 7.6 MB/s eta 0:00:00
Collecting celery[redis]==5.3.1 (from -r /opt/paperless-ngx/requirements.txt (line 11))
  Downloading https://www.piwheels.org/simple/celery/celery-5.3.1-py3-none-any.whl (418 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 418.0/418.0 kB 4.3 MB/s eta 0:00:00
Collecting certifi==2023.7.22 (from -r /opt/paperless-ngx/requirements.txt (line 12))
  Downloading https://www.piwheels.org/simple/certifi/certifi-2023.7.22-py3-none-any.whl (158 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 158.3/158.3 kB 925.9 kB/s eta 0:00:00
Collecting cffi==1.15.1 (from -r /opt/paperless-ngx/requirements.txt (line 13))
  Downloading cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (441 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 441.8/441.8 kB 5.9 MB/s eta 0:00:00
Collecting channels==4.0.0 (from -r /opt/paperless-ngx/requirements.txt (line 14))
  Downloading https://www.piwheels.org/simple/channels/channels-4.0.0-py3-none-any.whl (28 kB)
Collecting channels-redis==4.1.0 (from -r /opt/paperless-ngx/requirements.txt (line 15))
  Downloading https://www.piwheels.org/simple/channels-redis/channels_redis-4.1.0-py3-none-any.whl (18 kB)
Collecting charset-normalizer==3.2.0 (from -r /opt/paperless-ngx/requirements.txt (line 16))
  Obtaining dependency information for charset-normalizer==3.2.0 from https://files.pythonhosted.org/packages/a4/65/057bf29660aae6ade0816457f8db4e749e5c0bfa2366eb5f67db9912fa4c/charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata
  Downloading charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (31 kB)
Collecting click==8.1.6 (from -r /opt/paperless-ngx/requirements.txt (line 17))
  Downloading https://www.piwheels.org/simple/click/click-8.1.6-py3-none-any.whl (97 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 97.9/97.9 kB 505.6 kB/s eta 0:00:00
Collecting click-didyoumean==0.3.0 (from -r /opt/paperless-ngx/requirements.txt (line 18))
  Downloading https://www.piwheels.org/simple/click-didyoumean/click_didyoumean-0.3.0-py3-none-any.whl (2.7 kB)
Collecting click-plugins==1.1.1 (from -r /opt/paperless-ngx/requirements.txt (line 19))
  Downloading https://www.piwheels.org/simple/click-plugins/click_plugins-1.1.1-py2.py3-none-any.whl (7.5 kB)
Collecting click-repl==0.3.0 (from -r /opt/paperless-ngx/requirements.txt (line 20))
  Downloading https://www.piwheels.org/simple/click-repl/click_repl-0.3.0-py3-none-any.whl (10 kB)
Collecting coloredlogs==15.0.1 (from -r /opt/paperless-ngx/requirements.txt (line 21))
  Downloading https://www.piwheels.org/simple/coloredlogs/coloredlogs-15.0.1-py2.py3-none-any.whl (46 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 46.0/46.0 kB 434.6 kB/s eta 0:00:00
Collecting concurrent-log-handler==0.9.24 (from -r /opt/paperless-ngx/requirements.txt (line 22))
  Downloading https://www.piwheels.org/simple/concurrent-log-handler/concurrent_log_handler-0.9.24-py3-none-any.whl (24 kB)
Collecting cryptography==40.0.1 (from -r /opt/paperless-ngx/requirements.txt (line 23))
  Downloading cryptography-40.0.1-cp36-abi3-manylinux_2_28_x86_64.whl (3.7 MB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 3.7/3.7 MB 11.8 MB/s eta 0:00:00
Collecting dateparser==1.1.8 (from -r /opt/paperless-ngx/requirements.txt (line 24))
  Downloading https://www.piwheels.org/simple/dateparser/dateparser-1.1.8-py2.py3-none-any.whl (293 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 293.8/293.8 kB 3.7 MB/s eta 0:00:00
Collecting deprecation==2.1.0 (from -r /opt/paperless-ngx/requirements.txt (line 25))
  Downloading https://www.piwheels.org/simple/deprecation/deprecation-2.1.0-py2.py3-none-any.whl (11 kB)
Collecting django==4.1.10 (from -r /opt/paperless-ngx/requirements.txt (line 26))
  Downloading https://www.piwheels.org/simple/django/Django-4.1.10-py3-none-any.whl (8.1 MB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.1/8.1 MB 8.9 MB/s eta 0:00:00
Collecting django-celery-results==2.5.1 (from -r /opt/paperless-ngx/requirements.txt (line 27))
  Downloading https://www.piwheels.org/simple/django-celery-results/django_celery_results-2.5.1-py3-none-any.whl (36 kB)
Collecting django-compression-middleware==0.5.0 (from -r /opt/paperless-ngx/requirements.txt (line 28))
  Downloading https://www.piwheels.org/simple/django-compression-middleware/django_compression_middleware-0.5.0-py2.py3-none-any.whl (8.2 kB)
Collecting django-cors-headers==4.2.0 (from -r /opt/paperless-ngx/requirements.txt (line 29))
  Downloading https://www.piwheels.org/simple/django-cors-headers/django_cors_headers-4.2.0-py3-none-any.whl (12 kB)
Collecting django-extensions==3.2.3 (from -r /opt/paperless-ngx/requirements.txt (line 30))
  Downloading https://www.piwheels.org/simple/django-extensions/django_extensions-3.2.3-py3-none-any.whl (229 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 229.9/229.9 kB 3.2 MB/s eta 0:00:00
Collecting django-filter==23.2 (from -r /opt/paperless-ngx/requirements.txt (line 31))
  Downloading https://www.piwheels.org/simple/django-filter/django_filter-23.2-py3-none-any.whl (91 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 91.9/91.9 kB 1.0 MB/s eta 0:00:00
Collecting django-guardian==2.4.0 (from -r /opt/paperless-ngx/requirements.txt (line 32))
  Downloading https://www.piwheels.org/simple/django-guardian/django_guardian-2.4.0-py3-none-any.whl (106 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 106.1/106.1 kB 10.3 MB/s eta 0:00:00
Collecting djangorestframework==3.14.0 (from -r /opt/paperless-ngx/requirements.txt (line 33))
  Downloading https://www.piwheels.org/simple/djangorestframework/djangorestframework-3.14.0-py3-none-any.whl (1.1 MB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 1.1/1.1 MB 5.9 MB/s eta 0:00:00
Collecting djangorestframework-guardian==0.3.0 (from -r /opt/paperless-ngx/requirements.txt (line 34))
  Downloading https://www.piwheels.org/simple/djangorestframework-guardian/djangorestframework_guardian-0.3.0-py2.py3-none-any.whl (6.9 kB)
Collecting exceptiongroup==1.1.2 (from -r /opt/paperless-ngx/requirements.txt (line 35))
  Downloading https://www.piwheels.org/simple/exceptiongroup/exceptiongroup-1.1.2-py3-none-any.whl (14 kB)
Collecting filelock==3.12.2 (from -r /opt/paperless-ngx/requirements.txt (line 36))
  Downloading https://www.piwheels.org/simple/filelock/filelock-3.12.2-py3-none-any.whl (10 kB)
Collecting flower==2.0.0 (from -r /opt/paperless-ngx/requirements.txt (line 37))
  Downloading https://www.piwheels.org/simple/flower/flower-2.0.0-py2.py3-none-any.whl (383 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 383.5/383.5 kB 12.2 MB/s eta 0:00:00
Collecting gunicorn==21.2.0 (from -r /opt/paperless-ngx/requirements.txt (line 38))
  Downloading https://www.piwheels.org/simple/gunicorn/gunicorn-21.2.0-py3-none-any.whl (80 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 80.2/80.2 kB 9.9 MB/s eta 0:00:00
Collecting h11==0.14.0 (from -r /opt/paperless-ngx/requirements.txt (line 39))
  Downloading https://www.piwheels.org/simple/h11/h11-0.14.0-py3-none-any.whl (58 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 58.3/58.3 kB 6.6 MB/s eta 0:00:00
Collecting hiredis==2.2.3 (from -r /opt/paperless-ngx/requirements.txt (line 40))
  Downloading hiredis-2.2.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (165 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 165.9/165.9 kB 16.3 MB/s eta 0:00:00
Collecting httpcore==0.17.3 (from -r /opt/paperless-ngx/requirements.txt (line 41))
  Downloading https://www.piwheels.org/simple/httpcore/httpcore-0.17.3-py3-none-any.whl (74 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 74.5/74.5 kB 6.8 MB/s eta 0:00:00
Collecting httptools==0.6.0 (from -r /opt/paperless-ngx/requirements.txt (line 42))
  Obtaining dependency information for httptools==0.6.0 from https://files.pythonhosted.org/packages/cf/09/b17fbf88d5c285e7cd8162539ba6f95c778dcd47e44240aa14afd0982bb8/httptools-0.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata
  Downloading httptools-0.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.6 kB)
Collecting httpx==0.24.1 (from -r /opt/paperless-ngx/requirements.txt (line 43))
  Downloading https://www.piwheels.org/simple/httpx/httpx-0.24.1-py3-none-any.whl (75 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 75.4/75.4 kB 16.7 MB/s eta 0:00:00
Collecting humanfriendly==10.0 (from -r /opt/paperless-ngx/requirements.txt (line 44))
  Downloading https://www.piwheels.org/simple/humanfriendly/humanfriendly-10.0-py2.py3-none-any.whl (89 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 89.9/89.9 kB 16.5 MB/s eta 0:00:00
Collecting humanize==4.7.0 (from -r /opt/paperless-ngx/requirements.txt (line 45))
  Downloading https://www.piwheels.org/simple/humanize/humanize-4.7.0-py3-none-any.whl (113 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 113.6/113.6 kB 21.7 MB/s eta 0:00:00
Collecting idna==3.4 (from -r /opt/paperless-ngx/requirements.txt (line 46))
  Downloading https://www.piwheels.org/simple/idna/idna-3.4-py3-none-any.whl (61 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 61.5/61.5 kB 16.5 MB/s eta 0:00:00
Collecting imap-tools==1.1.0 (from -r /opt/paperless-ngx/requirements.txt (line 47))
  Downloading https://www.piwheels.org/simple/imap-tools/imap_tools-1.1.0-py3-none-any.whl (31 kB)
Collecting img2pdf==0.4.4 (from -r /opt/paperless-ngx/requirements.txt (line 48))
  Downloading https://www.piwheels.org/simple/img2pdf/img2pdf-0.4.4-py3-none-any.whl (47 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 47.3/47.3 kB 12.1 MB/s eta 0:00:00
Collecting inotify-simple==1.3.5 (from -r /opt/paperless-ngx/requirements.txt (line 50))
  Downloading https://www.piwheels.org/simple/inotify-simple/inotify_simple-1.3.5-py3-none-any.whl (9.4 kB)
Collecting inotifyrecursive==0.3.5 (from -r /opt/paperless-ngx/requirements.txt (line 51))
  Downloading https://www.piwheels.org/simple/inotifyrecursive/inotifyrecursive-0.3.5-py3-none-any.whl (8.0 kB)
Collecting joblib==1.3.1 (from -r /opt/paperless-ngx/requirements.txt (line 52))
  Downloading https://www.piwheels.org/simple/joblib/joblib-1.3.1-py3-none-any.whl (301 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 302.0/302.0 kB 11.6 MB/s eta 0:00:00
Collecting kombu==5.3.1 (from -r /opt/paperless-ngx/requirements.txt (line 53))
  Downloading https://www.piwheels.org/simple/kombu/kombu-5.3.1-py3-none-any.whl (198 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 198.5/198.5 kB 11.8 MB/s eta 0:00:00
Collecting langdetect==1.0.9 (from -r /opt/paperless-ngx/requirements.txt (line 54))
  Downloading https://www.piwheels.org/simple/langdetect/langdetect-1.0.9-py3-none-any.whl (994 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 994.5/994.5 kB 12.1 MB/s eta 0:00:00
Collecting lxml==4.9.3 (from -r /opt/paperless-ngx/requirements.txt (line 55))
  Obtaining dependency information for lxml==4.9.3 from https://files.pythonhosted.org/packages/3c/d2/11533f0bc47ff4d828a20cfb702f3453fe714bd5b475fcdc8cec6e6b7dcf/lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl.metadata
  Downloading lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl.metadata (3.8 kB)
Collecting msgpack==1.0.5 (from -r /opt/paperless-ngx/requirements.txt (line 56))
  Downloading msgpack-1.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (316 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 316.8/316.8 kB 19.2 MB/s eta 0:00:00
Collecting mysqlclient==2.2.0 (from -r /opt/paperless-ngx/requirements.txt (line 57))
  Downloading mysqlclient-2.2.0.tar.gz (89 kB)
    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 89.5/89.5 kB 11.4 MB/s eta 0:00:00
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Getting requirements to build wheel: started
  Getting requirements to build wheel: finished with status 'error'

:stderr:   error: subprocess-exited-with-error
  
  × Getting requirements to build wheel did not run successfully.
  │ exit code: 1
  ╰─> [24 lines of output]
      /bin/sh: 1: pkg-config: not found
      /bin/sh: 1: pkg-config: not found
      Trying pkg-config --exists mysqlclient
      Command 'pkg-config --exists mysqlclient' returned non-zero exit status 127.
      Trying pkg-config --exists mariadb
      Command 'pkg-config --exists mariadb' returned non-zero exit status 127.
      Traceback (most recent call last):
        File \"/opt/paperless-ngx/.venv/lib/python3.10/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py\", line 353, in <module>
          main()
        File \"/opt/paperless-ngx/.venv/lib/python3.10/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py\", line 335, in main
          json_out['return_val'] = hook(**hook_input['kwargs'])
        File \"/opt/paperless-ngx/.venv/lib/python3.10/site-packages/pip/_vendor/pyproject_hooks/_in_process/_in_process.py\", line 118, in get_requires_for_build_wheel
          return hook(config_settings)
        File \"/tmp/pip-build-env-lo3uqz9g/overlay/lib/python3.10/site-packages/setuptools/build_meta.py\", line 355, in get_requires_for_build_wheel
          return self._get_build_requires(config_settings, requirements=['wheel'])
        File \"/tmp/pip-build-env-lo3uqz9g/overlay/lib/python3.10/site-packages/setuptools/build_meta.py\", line 325, in _get_build_requires
          self.run_setup()
        File \"/tmp/pip-build-env-lo3uqz9g/overlay/lib/python3.10/site-packages/setuptools/build_meta.py\", line 341, in run_setup
          exec(code, locals())
        File \"<string>\", line 154, in <module>
        File \"<string>\", line 48, in get_config_posix
        File \"<string>\", line 27, in find_package_name
      Exception: Can not find valid pkg-config name.
      Specify MYSQLCLIENT_CFLAGS and MYSQLCLIENT_LDFLAGS env vars manually
      [end of output]
  
  note: This error originates from a subprocess, and is likely not a problem with pip.
error: subprocess-exited-with-error

× Getting requirements to build wheel did not run successfully.
│ exit code: 1
╰─> See above for output.

note: This error originates from a subprocess, and is likely not a problem with pip.

during "Install paperless-ngx python requirements" step. From my research it seems like mysqlclient 2.2.0 added a dependency on pkg-config.

I tried looking in this repo for the dependencies of paperless to see if I could figure out which package upgrade caused the issue, but I did not find them.

I have not tried out adding/installing pkg-config yet, but I will do so and report back once I did.

Potential idempotency issue: Role cannot complete when {{ paperless_ngx_dir_runtime_data }} was deleted

Hi,
I deleted the {{ paperless_ngx_dir_runtime_data }} which was /var/lib/paperless-ngx in my case. I run this role a second time to recreate it including all sub folders. The playbook run failed at task "Check that all services are running". The services didn't start because the folders are missing.

How to reproduce?

sudo systemctl stop paperless*.service
sudo rm -rf /var/lib/paperless-ngx

Next, run the Ansible playbook using this role again.

Expected behavior

I would expect that the role creates the missing directories (again) and configures paperless as declared using the role variables.

Is it a bug or a feature?

I'm not sure whether this role should be able to "repair" broken installations or not. I would expect it to. Could you please triage this issue and state whether it's a bug or not? If you believe it's not a bug please say why you think so as I would like to understand.

Best regards,
Joerg

Use rebuilt ansible role to follow conventions & enable easier maintenance.

Hello Folks,

I was going to submit this to the original paperless-ng repo, but it seems like that has had no action from the original author for quite some time. I've re-written the entire ansible role to conform to latest ansible specs, and have cleaned up a lot of the original work. This is currently published on ansible-galaxy for paperless-ng, but would like to include in NGX, as I am planning on moving to NGX when it gets a bit more stable.

The ansible playbook is here: https://github.com/r-pufky/ansible_paperlessng

Any new work added in this repo would need to be evaluated and added for import if missing.

no_log option set to true makes it very hard to find issues

Hi there,

when using this role it is kind of hard to troubleshoot misconfigurations when excessive configuration blocks like this one have set their no_log property to true:

- name: configure paperless-ngx
  ansible.builtin.lineinfile:
    path: "{{ paperlessng_directory }}/paperless.conf.template"
    regexp: ^#?{{ item.regexp }}=
    line: "{{ item.line }}"
  with_items:
   <alotofitemshere>

I know there are good reasons to hide these logs. But I needed to manually turn on logging just to recognize I had a type in a variable.

Non ideal ideas so far:

  • Splitting the configuration via lineinfile in smaller chunks
  • Make a separete task with no_log: true only for really sensitive options

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.