{"id":20780508,"url":"https://github.com/elemental-lf/docker-unoconv","last_synced_at":"2026-03-19T17:29:40.636Z","repository":{"id":97906259,"uuid":"174539560","full_name":"elemental-lf/docker-unoconv","owner":"elemental-lf","description":"Generate previews of common office document formats","archived":false,"fork":false,"pushed_at":"2019-04-30T13:08:11.000Z","size":63430,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-21T04:41:34.843Z","etag":null,"topics":["libreoffice","office","previews","thumbnails","unoconv"],"latest_commit_sha":null,"homepage":"","language":"Rich Text Format","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/elemental-lf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-03-08T13:08:39.000Z","updated_at":"2020-04-01T17:41:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"03b162d7-16fd-4162-89ae-32558b9c8992","html_url":"https://github.com/elemental-lf/docker-unoconv","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/elemental-lf/docker-unoconv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elemental-lf%2Fdocker-unoconv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elemental-lf%2Fdocker-unoconv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elemental-lf%2Fdocker-unoconv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elemental-lf%2Fdocker-unoconv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elemental-lf","download_url":"https://codeload.github.com/elemental-lf/docker-unoconv/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elemental-lf%2Fdocker-unoconv/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29191991,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-07T07:37:03.739Z","status":"ssl_error","status_checked_at":"2026-02-07T07:37:03.029Z","response_time":63,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["libreoffice","office","previews","thumbnails","unoconv"],"created_at":"2024-11-17T13:37:30.586Z","updated_at":"2026-02-07T10:02:52.878Z","avatar_url":"https://github.com/elemental-lf.png","language":"Rich Text Format","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Travis CI status](https://img.shields.io/travis/elemental-lf/docker-unoconv/master.svg?style=plastic\u0026label=Travis%20CI)](https://travis-ci.org/elemental-lf/docker-unoconv)\n\n# docker-unoconv\n\nThis repository contains a Docker image which can be used to generate previews and thumbnails from files in common \noffice  document formats.  It uses [LibreOffice](https://www.libreoffice.org/) via \n[unoconv](https://github.com/unoconv/unoconv) for rendering and exposes several [Celery](http://www.celeryproject.org/) \ntasks to access this functionality. Documents are read and previews and thumbnails are written via\n[PyFilesystem](https://www.pyfilesystem.org/), support for accessing S3 object stores via \n[`fs-s3`](https://fs-s3fs.readthedocs.io/) is included. This image is intended to be deployed with Kubernetes but can\nalso be used with Docker.\n\n## Modes of operation\n\nWhen instantiating the image as a container the mode the container should be running in needs to be specified. There\nare two possible modes:\n\n* `celery-worker`: In this mode a Celery worker is started which publishes four tasks with the following signatures:\n    \n    * `unoconv.tasks.supported_import_format(*, mime_type: str = None, extension: str = None) -\u003e bool`\n    \n        Returns a boolean value indicating if a document format is supported. Either `mime_type` or `extension` or both\n        have to be set. The `extension` must include the leading dot.\n    \n    * `unoconv.tasks.generate_preview_jpg(*, input_fs_url: str, input_file: str, output_fs_url: str, output_file: str, \n       mime_type: str = None, extension: str = None, pixel_height: int = None, pixel_width: int = None,\n       maintain_ratio: bool = False, quality: int = None, timeout: int = UNOCONV_DEFAULT_TIMEOUT)`\n        \n        This tasks renders the first page (or slide) of a document as a JPEG image.\n         \n        * The document is read from `input_fs_url`:`input_file` and the JPEG image is written to `output_fs_url`:`output_file`.\n         \n        * `mime_type` and `extension` are interpreted just like as with `unoconv.tasks.supported_import_format`. \n          If `extension` is `None` the  task tries to guess it from the supplied `input_file` name.\n         \n        * `pixel_height` and `pixel_width` specify the dimensions of the resulting image and are optional (i.e. they \n          either must be set or both be `None`). The behaviour is different when `scale_height` or `scale_width`\n          are `True`, see below.\n          \n        * `maintain_ratio` activates automatic aspect ratio preserving scaling of the image. The image is scaled in such \n          a way that it fits into  the bonding box given by `pixel_height` and `pixel_width` while preserving the \n          aspect ratio. If `maintain_ratio` is `True` the image is rendered two times: once to determine the dimensions\n          of the original document and a second time with the calculated dimensions applied. \n          \n        * `quality` determines the quality of the resulting JPEG image by tuning the compression algorithm. Valid\n          values are between 1 (lowest quality, smallest file size) and 100 (highest quality, largest file size).\n        \n        * `timeout` specifies a timeout for the invoked `unoconv` command. \n        \n        Exceptions thrown:\n        \n        * `ValueError`: Input format is unsupported or the supplied dimensions are invalid\n        * `FileNotFoundError`: Input file was not found\n        * `RuntimeError`: All other cases\n        \n    * `unoconv.tasks.generate_preview_png(*, input_fs_url: str, input_file: str, output_fs_url: str, output_file: str,\n       mime_type: str = None, extension: str = None, pixel_height: int = None, pixel_width: int = None,\n       maintain_ratio: bool = False, compression: int = None, timeout: int = UNOCONV_DEFAULT_TIMEOUT)`\n        \n        This task works just like `unoconv.tasks.generate_preview_jpg` but generates a PNG image instead. It\n        uses the `compression` parameter instead of the `quality` parameter to tune the image compression algorithm:\n        \n        * Valid values for `compression` are between 1 (lowest compression) and 9 (highest compress). \n        \n    * `unoconv.tasks.generate_pdf(*, input_fs_url: str, input_file: str, output_fs_url: str,\n       output_file: str, mime_type: str = None, extension: str = None, paper_format: str = None,\n       paper_orientation: str = None, timeout: int = UNOCONV_DEFAULT_TIMEOUT)`\n        \n       Again this is similar to the last two task. But in this case a PDF document containing *all* pages (or slides)\n       is generated. Instead of image dimensions and compression ratios the `paper_format` and `paper_orientation`\n       can be specified:\n        \n        * Valid values for `paper_format` depend on the LibreOffice version. Some valid values are `A3`, `A4`, `A5`,\n          `B4`, `B5`, `LETTER`, and `LEGAL`. \n        * Valid values for `paper_orientation` are `PORTRAIT` and `LANDSCAPE`.\n        \n       If `paper_format` is specified without a `paper_orientation` LibreOffice assumes an orientation of `PORTRAIT`. So\n       even when only specifying `paper_format` both settings in the original document are overridden.    \n    \n    To configure the Celery workers to connect to the Celery backends the Celery configuration needs to be mounted as \n    `/celery-worker/config/celeryconfig.py` inside the container. It contains configuration variable assignments\n    as per the Celery [documentation](http://docs.celeryproject.org/en/latest/userguide/configuration.html). To\n    get the results of the tasks a result backend is needed.\n    \n    These tasks need to be called by name. It is possible to use `send_task` for this or to define a `signature` with\n    one of the names above:\n    \n    ```python\n    app = Celery()\n    supported_import_format = app.signature('unoconv.tasks.supported_import_format')\n    generate_preview_jpg = app.signature('unoconv.tasks.generate_preview_jpg')\n    generate_preview_png = app.signature('unoconv.tasks.generate_preview_png')\n    generate_pdf = app.signature('unoconv.tasks.generate_pdf')\n    ``` \n    \n* `unoconv-listener`: This mode starts `unoconv` as server process inside the container. This container is optional, but\n    as the startup of LibreOffice is expensive it speeds things up and uses fewer resources. If this container is \n    not present, the `celery-worker` container starts up an `unoconv` server and LibreOffice instance by itself each \n    time a request comes in and terminates it again when done. \n        \nThe mode needs to be supplied as single argument to the container's entry-point. This is done via the \nKubernetes `args` option in container specifications. When using `docker-compose` or Docker Swarm\nthis would be `command`.  \n\n## Usage with Kubernetes\n\nTo deploy `docker-unoconv` with Kubernetes it is best to use the provided Helm chart. It can be found in `charts/unoconv`.\nIf you're not using Helm the manifest templates in `charts/unoconv/templates` will still be a good starting point\nfor building your own manifests.\n\nThe Helm chart comes with a few configuration options:\n\nThe `unoconv` listener can be disabled by setting `containers.unoconvListener.enabled` to `false`. But normally it\nshould always be enabled.\n\n```yaml\ncontainers:\n  unoconvListener:\n    enabled: true\n```\n\nThe configuration for the Celery worker needs to be supplied under the key `containers.celeryWorker.config`. It is\ninjected into the container via a `ConfigMap`.\n\n```yaml\ncontainers:\n  celeryWorker:\n    config:\n      broker_url = 'amqp://guest:guest@rabbitmq:5672'\n      result_backend = 'rpc://'\n      tasks_queues = 'unoconv'\n```\n\nBy default the deployment consists of five pods. The Celery workers are just started with one worker process per pod, \nso they need to be scaled by increasing the number of `replicas`. This can be done automatically be enabling the \nhorizontal autoscaler below.\n\n```yaml\nreplicaCount: 5 \n```\nWith the standard settings the Helm chart will use the `latest` image. For production deployment it is recommended \nto specify a release version instead of using `latest`. In that case the `pullPolicy` should be set to `IfNotPresent`.\n\n```yaml\nimage:\n  repository: elementalnet/unoconv\n  tag: latest\n  pullPolicy: Always\n```\n\nTo access documents residing on a filesystem a data volume can be mounted into the Celery worker container:\n\n```yaml\ncontainers:\n  celeryWorker:\n    dataVolume:\n      enabled: false\n      # Mount path inside the Celery worker container\n      mountPath: /data\n      reference:\n        persistentVolumeClaim:\n          claimName: your-pvc\n```\nIt is also possible to specify resources. Currently both containers use the same resource allocation. This\nmight turn out to be suboptimal and separate resource specifications might be needed in the future. A horizontal\npod autoscaler can be enabled to adjust the number of `replicas` automatically.\n\n```yaml\nresources: {}\n  # limits:\n  #  cpu: 100m\n  #  memory: 128Mi\n  # requests:\n  #  cpu: 100m\n  #  memory: 128Mi\n\nhorizontalPodAutoscaler:\n  # Remember to set resources above if you enable this\n  enabled: false\n  minReplicas: 1\n  maxReplicas: 10\n  targetCPUUtilizationPercentage: 50\n```\n\nThe last three options relate to pod placement:\n\n```yaml\nnodeSelector: {}\n\ntolerations: []\n\naffinity: {}  \n```\n\n## Usage with Docker\n\nPlease see `tests/docker-compose.yaml` for an example on how to use this image with Docker.\n\n## Available images\n\nA pre-built Docker image is present on Docker Hub under https://hub.docker.com/r/elementalnet/unoconv. The current\nmaster branch is available under the tags `latest` and `master`. Releases are available with their respective\nversion as the tag. All images are built automatically via Travis CI.\n\n## Known Issues\n\n* During testing I've seen some crashes of `unoconv` which seem to be related to memory corruption. These are not\n  directly reproducible and seem to sometimes correlate with crashes of LibreOffice. Stability increased after\n  disabling the listener and so using a new LibreOffice instance for each new task.\n  \n* Again during testing I've seen AMQP heartbeat failures when some tasks which take over over second to complete.\n  The workaround was to disable heartbeats with `broker_heartbeat = None`. I'm not sure if this is related to the\n  test setup, the Celery configuration or a general problem.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felemental-lf%2Fdocker-unoconv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felemental-lf%2Fdocker-unoconv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felemental-lf%2Fdocker-unoconv/lists"}