{"id":13740412,"url":"https://github.com/dbmdz/iiif-server-hymir","last_synced_at":"2026-01-14T03:25:53.621Z","repository":{"id":13141135,"uuid":"63786754","full_name":"dbmdz/iiif-server-hymir","owner":"dbmdz","description":"Hymir is a Java based IIIF Server. It is based on \"IIIF Image API Java Libraries\" and \"IIIF Presentation API Java Libraries\" projects (see https://github.com/dbmdz)","archived":false,"fork":false,"pushed_at":"2025-12-11T22:38:49.000Z","size":16044,"stargazers_count":31,"open_issues_count":20,"forks_count":10,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-12-13T04:18:14.902Z","etag":null,"topics":["iiif","iiif-image","iiif-presentation","iiif-server","mirador"],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dbmdz.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2016-07-20T14:10:46.000Z","updated_at":"2025-10-13T03:16:16.000Z","dependencies_parsed_at":"2023-02-19T10:00:19.263Z","dependency_job_id":"1a650288-cb50-4a4c-8562-ad8e09f69fcb","html_url":"https://github.com/dbmdz/iiif-server-hymir","commit_stats":null,"previous_names":[],"tags_count":50,"template":false,"template_full_name":null,"purl":"pkg:github/dbmdz/iiif-server-hymir","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbmdz%2Fiiif-server-hymir","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbmdz%2Fiiif-server-hymir/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbmdz%2Fiiif-server-hymir/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbmdz%2Fiiif-server-hymir/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dbmdz","download_url":"https://codeload.github.com/dbmdz/iiif-server-hymir/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dbmdz%2Fiiif-server-hymir/sbom","scorecard":{"id":329019,"data":{"date":"2025-08-11","repo":{"name":"github.com/dbmdz/iiif-server-hymir","commit":"a541214e0760c3ce471f298a282e33b40ad5a12c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.8,"checks":[{"name":"Code-Review","score":5,"reason":"Found 4/8 approved changesets -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":1,"reason":"2 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 1","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:16: update your workflow using https://app.stepsecurity.io/secureworkflow/dbmdz/iiif-server-hymir/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/dbmdz/iiif-server-hymir/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/dbmdz/iiif-server-hymir/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/dbmdz/iiif-server-hymir/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/dbmdz/iiif-server-hymir/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:68: update your workflow using https://app.stepsecurity.io/secureworkflow/dbmdz/iiif-server-hymir/ci.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:85: update your workflow using https://app.stepsecurity.io/secureworkflow/dbmdz/iiif-server-hymir/ci.yml/main?enable=pin","Info:   0 out of   7 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/ci.yml:43"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 26 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"44 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-vmq6-5m68-f53m","Warn: Project is vulnerable to: GHSA-6v67-2wr5-gvf4","Warn: Project is vulnerable to: GHSA-gm62-rw4g-vrc4","Warn: Project is vulnerable to: GHSA-pr98-23f8-jwxv","Warn: Project is vulnerable to: GHSA-h46c-h94j-95f3","Warn: Project is vulnerable to: GHSA-4265-ccf5-phj5","Warn: Project is vulnerable to: GHSA-4g9r-vxhx-9pgx","Warn: Project is vulnerable to: GHSA-cgwf-w82q-5jrr","Warn: Project is vulnerable to: GHSA-j288-q9x7-2f5v","Warn: Project is vulnerable to: GHSA-27hp-xhwr-wr2m","Warn: Project is vulnerable to: GHSA-3p2h-wqq4-wf4h","Warn: Project is vulnerable to: GHSA-5j33-cvvr-w245","Warn: Project is vulnerable to: GHSA-7w75-32cg-r6g2","Warn: Project is vulnerable to: GHSA-83qj-6fr2-vhqg","Warn: Project is vulnerable to: GHSA-ff77-26x5-69cr","Warn: Project is vulnerable to: GHSA-h2fw-rfh5-95r3","Warn: Project is vulnerable to: GHSA-h3gc-qfqq-6h8f","Warn: Project is vulnerable to: GHSA-wc4r-xq3c-5cf3","Warn: Project is vulnerable to: GHSA-wm9w-rjj3-j356","Warn: Project is vulnerable to: GHSA-v682-8vv8-vpwr","Warn: Project is vulnerable to: GHSA-rc42-6c7j-7h5r","Warn: Project is vulnerable to: GHSA-f3jh-qvm4-mg39","Warn: Project is vulnerable to: GHSA-q3v6-hm2v-pw99","Warn: Project is vulnerable to: GHSA-mg83-c7gq-rv5c","Warn: Project is vulnerable to: GHSA-c4q5-6c82-3qpw","Warn: Project is vulnerable to: GHSA-4gc7-5j7h-4qph","Warn: Project is vulnerable to: GHSA-4wp7-92pw-q264","Warn: Project is vulnerable to: GHSA-9cmq-m9j5-mvww","Warn: Project is vulnerable to: GHSA-2rmj-mq67-h97g","Warn: Project is vulnerable to: GHSA-2wrp-6fg6-hmc5","Warn: Project is vulnerable to: GHSA-4wrc-f8pq-fpqp","Warn: Project is vulnerable to: GHSA-ccgv-vj62-xf9h","Warn: Project is vulnerable to: GHSA-hgjh-9rj2-g67j","Warn: Project is vulnerable to: GHSA-cx7f-g6mp-7hqm","Warn: Project is vulnerable to: GHSA-g5vr-rgqm-vf78","Warn: Project is vulnerable to: GHSA-w3c8-7r8f-9jp8","Warn: Project is vulnerable to: GHSA-vc8w-jr9v-vj7f","Warn: Project is vulnerable to: GHSA-3mc7-4q67-w48m","Warn: Project is vulnerable to: GHSA-98wm-3w3q-mw94","Warn: Project is vulnerable to: GHSA-9w3m-gqgf-c4p9","Warn: Project is vulnerable to: GHSA-c4r9-r8fh-9vj2","Warn: Project is vulnerable to: GHSA-hhhw-99gj-p3c3","Warn: Project is vulnerable to: GHSA-mjmj-j48q-9wg2","Warn: Project is vulnerable to: GHSA-w37g-rhq8-7m4j"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-18T03:08:36.003Z","repository_id":13141135,"created_at":"2025-08-18T03:08:36.003Z","updated_at":"2025-08-18T03:08:36.003Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408841,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["iiif","iiif-image","iiif-presentation","iiif-server","mirador"],"created_at":"2024-08-03T04:00:47.506Z","updated_at":"2026-01-14T03:25:53.606Z","avatar_url":"https://github.com/dbmdz.png","language":"Java","funding_links":[],"categories":["Image Servers"],"sub_categories":["IIIF Extensions"],"readme":"# Hymir IIIF Server\n\n[![Javadocs](https://javadoc.io/badge/de.digitalcollections/iiif-server-hymir.svg)](https://javadoc.io/doc/de.digitalcollections/iiif-server-hymir)\n[![License](https://img.shields.io/github/license/dbmdz/iiif-server-hymir.svg)](LICENSE)\n[![GitHub release](https://img.shields.io/github/release/dbmdz/iiif-server-hymir.svg)](https://github.com/dbmdz/iiif-server-hymir/releases)\n[![Maven Central](https://img.shields.io/maven-central/v/de.digitalcollections/iiif-server-hymir.svg)](https://search.maven.org/search?q=a:iiif-server-hymir)\n\nHymir is a Java based IIIF Server. It is based on our [IIIF API Java Libraries](https://github.com/dbmdz/iiif-apis) (Java implementations of the [IIIF specifications](http://iiif.io/technical-details/)). It can be used to serve images, presentation manifests, presentation collections and presentation annotation lists.\n\n## Features\n\n- IIIF Image API 2.1 compliant (see \u003ca href=\"http://iiif.io/api/image/2.1/\"\u003ehttp://iiif.io/api/image/2.1/\u003c/a\u003e).\n- IIIF Presentation API 2.1 compliant (see \u003ca href=\"http://iiif.io/api/presentation/2.1/\"\u003ehttp://iiif.io/api/presentation/2.1/\u003c/a\u003e).\n- On the fly image processing. No additional pregenerated (pyramid zoom) images are needed. No additional storage consumption.\n- Can simply be run as a standalone IIIF server from the JAR, no application server necessary\n- Spring based modular, extendable, easy to maintain enterprise architecture.\n- Highly customizable image storage and identifier resolving: Access to images over project specific Resolver-plugin mechanism.\n- Support for Filesystem- and HTTP-Image-Repositories (own protocols can be added by providing specific resolver)\n- Pluggable Manifest generation: implement your own mapping from project specific structure metadata to a standard Manifest object.\n- Embedded IIIF Image Viewer (for out of the box viewing of served images): OpenSeadragon 2.4.0 (see \"Usage\" below)\n- Embedded IIIF Presentation Viewer: Mirador 2.7.0 (see \"Usage\" below)\n- Direct Manifest access (see \"Usage\" below)\n\n### Supported image formats\n\n| Format    | Reading  | Writing | Dependencies                               | Comment    |\n| --------- | -------- | ------- | ------------------------------------------ | ---------- |\n|   JPEG    |   [x]    |   [x]   |   libturbojpeg (optional, but recommended) |            |\n|  JPEG2000 |   [x]    |   [ ]   |   libopenjp2 (\u003e= 2.3 recommended)          |            |\n|    TIFF   |   [x]    |   [x]   |                                            |            |\n|    PNG    |   [x]    |   [x]   |                                            | Due to possible transparency (alpha channel) in PNG it is not possible to use a PNG source file and deliver it as JPG. PNG delivered as PNG is possible. |\n|    GIF    |   [x]    |   [x]   |                                            |            |\n\n\n## Prerequisites\n\n- Server with minimum 4GB RAM.\n- Java 11\n\n## Installation\n\nDownload `hymir-\u003cversion\u003e-exec.jar` from the GitHub [releases](https://github.com/dbmdz/iiif-server-hymir/releases) page.\n\n### Using the TurboJPEG backend for JPEG files\n\nBy default, a Java-based image processing backend is used. If you want better\nperformance, it is recommended to use the native image processing backend\nthat is based on TurboJPEG. For this, you will have to install the TurboJPEG\nnative library, on Ubuntu `libturbojpeg`.\n\nDebian:\n\n```sh\n$ sudo apt-get install libturbojpeg\n```\n\n### Adding JPEG2000 support\n\nBy default, a Java-based image processing backend is used which has no support for JPEG2000.\nFor adding JPEG2000 support, you will have to install the libopenjp2 native library.\n\nDebian:\n\n```sh\n$ sudo apt-cache search libopenjp2\nlibopenjp2-7 - Kompressions-/Dekompressions-Bibliothek für das Bildformat JPEG 2000\nlibopenjp2-tools - Kommandozeilenwerkzeuge zur Verwendung der JPEG 2000-Bibliothek\nlibopenjp2-7-dev - development files for OpenJPEG, a JPEG 2000 image library\n$ sudo apt-get install libopenjp2-7\n```\n\n### Creating logging directories\n\nCreate directories for\n\n- hymir application logging (configured in logback-spring.xml), e.g. `/var/log/hymir`\n- hymir access logs (default: `/var/log/digitalcollections`)\n\nExample (use more restricted access rights than in this example):\n\n```sh\n$ sudo mkdir /var/log/hymir\n$ sudo chmod 777 /var/log/hymir\n$ sudo mkdir /var/log/digitalcollections\n$ sudo chmod 777 /var/log/digitalcollections\n```\n\n## Usage\n\nRun the downloaded application:\n\n- locally for testing (default active configuration profile is \"local\"):\n\n```sh\n$ java -jar hymir-\u003cversion\u003e-exec.jar\n```\n\nLogging: to console\n\nImage, manifest, collection and annotation list file resolving: see [here](src/main/resources/application.yml#L49) (using directories under `/var/local/iiif`)\n\nApplication configuration: see [here](src/main/resources/application.yml) (`local` profile section at beginning of file)\n\n- in production\n\n```sh\n$ java -jar hymir-\u003cversion\u003e-exec.jar --spring.profiles.active=PROD\n```\n\nLogging: to file `./hymir.log` in [Logstash](https://www.elastic.co/de/products/logstash)-JSON format\n\nImage, manifest, collection and annotation list file resolving: see [here](src/main/resources/application.yml#L49) (using directories under `/var/local/iiif`)\n\nApplication configuration: see [here](src/main/resources/application.yml) (`PROD` profile section overriding some values at bottom of file)\n\n- in production with custom logging configuration file:\n\n```sh\n$ java -jar hymir-\u003cversion\u003e-exec.jar --logging.config=file:/etc/hymir/logback-spring.xml  --spring.profiles.active=PROD\n```\n\nRead \u003chttps://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html\u003e and \u003chttps://logback.qos.ch/manual/configuration.html\u003e.\n\n- in production with custom configuration file `application.yml`:\n\n(Custom `application.yml` placed beside jar-file. No explicit command line option needed.)\n\n```sh\n$ java -jar hymir-\u003cversion\u003e-exec.jar --spring.profiles.active=PROD\n```\n\n- in production with a custom server port (e.g. port 8080):\n\n```sh\n$ java -jar hymir-\u003cversion\u003e-exec.jar --server.port=8080 --spring.profiles.active=PROD\n```\n\nComplete parametrized example:\n\n```sh\n$ java -jar hymir-\u003cversion\u003e-exec.jar --logging.config=file:/etc/hymir/logback-spring.xml --server.port=8080 --spring.profiles.active=PROD\n```\n\n(and `application.yml` beside jar file).\n\nAccess Hymir GUI (e.g. http://localhost:9000/).\n\n## Configuration\n\n### Running Hymir behind a proxy server\n\nIf you are running Hymir behind a proxy server, it is important to configure the proxy server to set the `X-Forwarded-For` and `X-Forwarded-Proto` headers, because they are used e.g. in rendering absolute URLs in `info.json` response content.\n\nFor NGinx this can be configured like this:\n\n```\nproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\nproxy_set_header X-Forwarded-Proto $scheme;\n```\n\n### Image and presentation manifest resolving\n\nBased on unique resource identifiers the server tries to resolve identifiers to a `file:` or `http:` path.\nThe resolving rules (one rule per line) are configurable with regular expressions in YML-files.\n\nYou can pass the path to your custom resolving rules with the `--spring.config.additional-location=/path/to/rules.yml` option.\n\nExample:\n\n```sh\n$ java -jar hymir-\u003cversion\u003e-exec.jar --spring.config.additional-location=file:/etc/hymir/rules.yml\n```\n\nExample file `/etc/hymir/rules.yml`:\n\n```yaml\nresourceRepository:\n  resolved:\n    patterns:\n      # This configuration file defines a list of patterns with one ore more substitutions.\n      # These are used for resolving IDs to a concrete URI, e.g. on the file system, the\n      # classpath or even a remote HTTP endpoint.\n      # You can specify multiple substitutions, the resolver will try to match them against\n      # the desired MIME type and return all that matches\n      # The repository will then verify which of these URIs are actually readable and return\n      # the first matching substitution.\n      # In the example below, we have two MIME types (tiff/jpeg) and for JPEG two resolutions\n      # in decreasing order of quality, so that the higher-resolution image will be chosen\n      # if it is available.\n      # An image pattern resolving example:\n      - pattern: ^(\\d{8})_(\\d{5})$\n        substitutions:\n          - 'file:/var/local/iiif/images/$1/original/image_$1_$2.tif'\n          - 'file:/var/local/iiif/images/$1/300/image_$1_$2.jpg'\n          - 'file:/var/local/iiif/images/$1/150/image_$1_$2.jpg'\n\n      # An manifest pattern resolving example:\n      - pattern: ^(\\d{8})$\n        substitutions:\n          - 'file:/var/local/iiif/presentation/manifests/manifest_$1.json'\n\n      # For the official IIIF Image API Validator\n      - pattern: 67352ccc-d1b0-11e1-89ae-279075081939\n        substitutions:\n          - 'classpath:validation.jp2'\n          - 'classpath:validation.png'\n\n      # Collection manifests ('collection-' pattern-prefix is statically added to requested collection name to disambigued from other patterns)\n      - pattern: ^collection-(.*)$\n        substitutions:\n          - 'file:/var/local/iiif/presentation/collections/$1.json'\n```\n\n### Serve images\n\nSee \u003chttps://iiif.io/api/image/2.1/\u003e\n\nIn the simplest case you just want to serve images of a directory.\n\nExample:\n\nLet's assume you have a bunch of jpg-files residing in the directory \"/var/local/iiif/images\" for objects with identifiers `00000001`, `00000002` and so on. The `images`-directory contains a directory for each object in which in turn all images of an object reside.\n\nThe files are named \"image_00000001_00001.jpg\", \"image_00000001_00002.jpg\", ... thus containing the object id and the image number in the filename.\n\nAn example for an entry in the `rules.yml`  (including matching just for identifiers and numbered images with digits) then just could look like this:\n\n```yaml\n- pattern: ^(\\d{8})_(\\d{5})$\n  substitutions:\n    - 'file:/var/local/iiif/images/$1/image_$1_$2.jpg'\n```\n\nAn IIIF Image API url example for this pattern: `http://localhost:9000/image/v2/00000005_00012/full/full/0/default.jpg`\n\n#### Change Image API URL prefix\n\nBy default the url prefix of the IIIF Image API endpoint is `/image/v2/`.\n\nYou can configure another url prefix on server startup using system property `custom.iiif.image.urlPrefix`.\n\nExample:\n\n```sh\n$ java -jar target/hymir-\u003cversion\u003e-exec.jar --custom.iiif.image.urlPrefix='/iiifImage/' --spring.config.additional-location=file:/etc/hymir/rules.yml --spring.profiles.active=local\n```\n\nResulting URL: `http://localhost:9000/iiifImage/00113391_00001/full/300,/0/default.jpg`\n\n### Serve IIIF Presentation manifests\n\nSee \u003chttps://iiif.io/api/presentation/2.1/#manifest\u003e\n\nIn the simplest case you just want to serve static (pregenerated) IIIF Presentation manifest json-files of a directory.\n\nExample:\n\nLet's assume you have a bunch of json-files residing in the directory \"/var/local/iiif/presentation/manifests\" for the objects with identifiers `00000001`, `00000002` and so on.\n\nThe files are named \"manifest_00000001.json\", \"manifest_00000002.json\", ... containing the object id in the filename.\n\nAn example for an entry in the `rules.yml` (including matching just for identifiers with digits) then could look like this:\n\n```yaml\n- pattern: ^(\\d{8})$\n  substitutions:\n    - 'file:/var/local/iiif/presentation/manifests/manifest_$1.json'\n```\n\nAn IIIF Presentation API url for a manifest example: `http://localhost:9000/presentation/v2/00000002/manifest`\n\n#### Change Presentation API URL prefix\n\nBy default the url prefix of the IIIF Presentation API endpoint is `/presentation/v2/`.\n\nYou can configure another url prefix on server startup using system property `custom.iiif.presentation.urlPrefix`.\n\nExample:\n\n```sh\n$ java -jar hymir-\u003cversion\u003e-exec.jar --custom.iiif.presentation.urlPrefix='/iiifPresentation/' --spring.config.additional-location=file:/etc/hymir/rules.yml --spring.profiles.active=local\n```\n\nResulting URL: `http://localhost:9000/iiifPresentation/00113391/manifest`\n\n### Serve IIIF Presentation collections\n\nSee \u003chttps://iiif.io/api/presentation/2.1/#collection\u003e\n\nIn the simplest case you just want to serve static (pregenerated) IIIF Presentation collection json-files of a directory.\n\nExample:\n\nLet's assume you have a bunch of json-files residing in the directory \"/var/local/iiif/presentation/collections\" for collections with a specific name, e.g. `newspapers`.\n\nThe files are named e.g. `newspapers.json`, `medieval_manuscripts.json`, ... containing the collection name in the filename.\n\nAn example for an entry in the `rules.yml` then just could look like this:\n\n```yaml\n- pattern: ^collection-(.*)$\n  substitutions:\n    - 'file:/var/local/iiif/presentation/collections/$1.json'\n```\n\nAn IIIF Presentation API url for a collection example: `http://localhost:9000/presentation/v2/collection/newspapers`\n\nImplementation background: To get a regex resolvable pattern that can be differentiated from patterns for manifest json-files (same mimetype), Hymir adds the static prefix `collection-` to the given identifier for collections. (This does not appear in the identifier in the url, just in the rules.yml regex)\n\n### Logging\n\nDefault logging configuration is specified in the file `logback-spring.xml` packaged in the exectable Hymir JAR-file. The default logging file is configured as `./hymir.log` in Logstash-JSON-format.\n\nIf you want human readable logging to console use `--spring.profiles.active=local` on start command line or define a custom `logback-spring.xml` config location (see \"Usage\" section above).\n\nExample: Custom config file with human readable logging\n\n```sh\n$ java -jar hymir-\u003cversion\u003e-exec.jar --logging.config=file:/etc/hymir/logback-spring.xml\n```\n\nExample file `/etc/hymir/logback-spring.xml`:\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cconfiguration\u003e\n  \u003c!-- see https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html#_profile_specific_configuration --\u003e\n  \u003cspringProfile name=\"PROD\"\u003e\n    \u003cappender name=\"default\" class=\"ch.qos.logback.core.rolling.RollingFileAppender\"\u003e\n      \u003cfile\u003e/var/log/hymir/hymir.log\u003c/file\u003e\n      \u003crollingPolicy class=\"ch.qos.logback.core.rolling.TimeBasedRollingPolicy\"\u003e\n        \u003cfileNamePattern\u003e/var/log/hymir/hymir.%d{yyyy-MM-dd}.log\u003c/fileNamePattern\u003e\n      \u003c/rollingPolicy\u003e\n      \u003crollingPolicy class=\"ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy\"\u003e\n        \u003cfileNamePattern\u003e/var/log/hymir/hymir.%d{yyyy-MM}.%i.log.gz\u003c/fileNamePattern\u003e\n        \u003cmaxFileSize\u003e100MB\u003c/maxFileSize\u003e\n        \u003cmaxHistory\u003e90\u003c/maxHistory\u003e\n        \u003ctotalSizeCap\u003e5GB\u003c/totalSizeCap\u003e\n      \u003c/rollingPolicy\u003e\n      \u003cencoder\u003e\n        \u003cpattern\u003e[%d{ISO8601} %5p] %40.40c:%4L [%-8t] - %m%n\u003c/pattern\u003e\n      \u003c/encoder\u003e\n      \u003c!--\n      \u003cencoder class=\"net.logstash.logback.encoder.LogstashEncoder\"\u003e\n        \u003ccustomFields\u003e{\"service\":\"hymir-server\", \"group\":\"rest\", \"instance\":\"${instance.name:-default}\"}\u003c/customFields\u003e\n      \u003c/encoder\u003e\n      --\u003e\n    \u003c/appender\u003e\n  \u003c/springProfile\u003e\n\n  \u003cspringProfile name=\"local\"\u003e\n    \u003cappender name=\"default\" class=\"ch.qos.logback.core.ConsoleAppender\"\u003e\n      \u003cencoder\u003e\n        \u003cpattern\u003e[%d{ISO8601} %5p] %40.40c:%4L [%-8t] - %m%n\u003c/pattern\u003e\n      \u003c/encoder\u003e\n    \u003c/appender\u003e\n  \u003c/springProfile\u003e\n\n  \u003clogger name=\"de.digitalcollections.iiif.hymir.presentation.backend\" level=\"error\" /\u003e\n  \u003clogger name=\"de.digitalcollections.iiif.hymir.presentation.business\" level=\"error\" /\u003e\n  \u003clogger name=\"de.digitalcollections.commons\" level=\"error\" /\u003e\n\n  \u003croot level=\"info\"\u003e\n    \u003cappender-ref ref=\"default\" /\u003e\n  \u003c/root\u003e\n\n\u003c/configuration\u003e\n```\n\n### Custom configuration file `application.yml`\n\nThe default configuration of the server comes packaged in the executable JAR-file of Hymir.\nTo customize (override) the default configuration parameters, simply put your custom `application.yml` file beside (in the same directory of) the Hymir JAR-file.\n\nYour custom `application.yml` does not have to replace all default properties. It can contain only the properties you want to change.\n\nTo get the default configuration file, you should download the `hymir-\u003crelease-version\u003e.jar` file (NOT containing `-exec` in filename) from \u003chttps://github.com/dbmdz/iiif-server-hymir/releases\u003e and unpack the contained `application.yml` with:\n\n```sh\n$ jar xfv hymir-\u003cversion\u003e.jar application.yml\n```\n\nNow put the file beside the executable Hymir jar and edit it according to your requirements.\n\n#### Configure custom HTTP-Response-Header\n\nIf you already put your custom `application.yml` file in place (see above), it is possible to set custom HTTP response headers in responses for\n\n- all requests to Image and Presentation API urls\n- Image API: image requests\n- Image API: info.json requests\n- Presentation API: manifest requests (includes canvas and range requests)\n- Presentation API: collection requests\n- Presentation API: Annotation list requests\n\nCustomized response headers are placed in the `custom.iiif.headers`-section of your `application.yml` configuration file, e.g.:\n\n```yml\ncustom:\n  iiif:\n    headers:\n      all:\n        - name: 'served by'\n          value: 'hymir'\n      image:\n        image:\n          - name: 'cache-control'\n            value: 'max-age=86400'\n        info:\n          - name: 'header1'\n            value: 'value1'\n      presentation:\n        manifest:\n          - name: 'mani1'\n            value: 'mani-value1'\n          - name: 'mani2'\n            value: 'mani-value2'\n        collection: null\n        annotationList: null\n```\n\nIf you want to override a header that is set by default (e.g. `Access-Control-Allow-Origin=*`), you just have to configure it with another value, e.g.:\n\n```yml\ncustom:\n  iiif:\n    headers:\n      image:\n        info:\n          - name: 'Access-Control-Allow-Origin'\n            value: 'https://yourdomain.org'\n```\n\n(Given example is a bad practice in the IIIF context, as it contradicts the \"interoperability\" idea of IIIF...)\n\n## Administration\n\n### Monitoring\n\nMonitoring endpoints under http://localhost:9001/monitoring, authentication by default: `admin/secret` (configurable in `application.yml`)\n\nTo change monitoring port, e.g. to `8081` use `management.server.port` option:\n\n```sh\n$ java -jar hymir-\u003cversion\u003e-exec.jar --management.server.port=8081\n```\n\n### Out Of Memory handling\n\nIn case the IIIF server runs out of memory it should quit - use java options for this. (To be restarted automatically install it as systemd service, see below.)\n\n```sh\n$ java -jar hymir-\u003cversion\u003e-exec.jar -XX:+ExitOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError\n```\n\n### Configure IIIF service as systemd service\n\nIn Linux production environments it is a best practice to install the IIIF server as a systemd service / daemon.\n\nTherefore create a user `iiif`, a service file, add it as service and enable it:\n\n```sh\n$ sudo nano /etc/systemd/system/iiif-hymir.service\n[Unit]\nDescription=IIIF Hymir Server\nAfter=syslog.target\n\n[Service]\nUser=iiif\nExecStart=/usr/bin/java -jar /opt/hymir-\u003cversion\u003e-exec.jar \\\n    -XX:+ExitOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError \\\n    --spring.config.additional-location=file:/etc/hymir/rules.yml \\\n    --spring.profiles.active=PROD \\\n    --logging.config=file:/etc/hymir/logback-spring.xml \\\n    --server.port=8080 \\\n    --management.server.port=8081\nSuccessExitStatus=143\n\n[Install]\nWantedBy=multi-user.target\n\n$ sudo systemctl daemon-reload\n$ sudo systemctl enable iiif-hymir.service\n$ sudo systemctl start iiif-hymir.service\n```\n\n## Users\n\n- Bavarian State Library, Project \"bavarikon\": \u003ca href=\"http://www.bavarikon.de/\"\u003ehttps://www.bavarikon.de/\u003c/a\u003e\n- Bavarian State Library, Project \"Digital East Asian Collections\": \u003ca href=\"https://ostasien.digitale-sammlungen.de/\"\u003ehttps://ostasien.digitale-sammlungen.de/\u003c/a\u003e\n- Bavarian State Library, Project digiPress: \u003ca href=\"https://digipress.digitale-sammlungen.de/\"\u003ehttps://digipress.digitale-sammlungen.de/\u003c/a\u003e\n- Bavarian State Library, iiif-Bookshelf: \u003ca href=\"https://iiif.digitale-sammlungen.de/\"\u003ehttps://iiif.digitale-sammlungen.de/\u003c/a\u003e\n\n## Development\n\n* Install git client\n* Install Java JDK 11 or above\n* Install Apache Maven buildttool\n\n```sh\n$ cd ~/development\n$ git clone git@github.com:dbmdz/iiif-server-hymir.git\n$ cd iiif-server-hymir\n$ mvn clean install\n```\n\nExecutable JAR-file is in `target` directory.\n\nOn systems without installed `libturbojpeg` test fail.\nTo build without tests, execute:\n\n```sh\n$ mvn clean install -DskipTests=true\n```\n\nTo install `libturbojpeg` on Debian based systems:\n\n```sh\n$ sudo apt install libturbojpeg\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdbmdz%2Fiiif-server-hymir","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdbmdz%2Fiiif-server-hymir","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdbmdz%2Fiiif-server-hymir/lists"}