Paperless-ngx에서 한글파일 지원하도록 설정하기

Paperless-ngx는 셀프호스팅할수 있는 문서 관리 시스템으로, pdf, docx, odt 등 다양한 문서 형식을 지원한다.
하지만 대한민국에서 많이 사용하는 한글파일(.hwp, .hwpx)은 기본적으로 지원하지 않는다.
나는 Paperless-ngx의 email rule을 이용하여 받은 이메일의 첨부파일들을 자동으로 아카이빙하고 있는데,
많은 문서들이 한글 파일로 오고가는 상황에서 Paperless-ngx에서 처리할 수 없어 불편함이 많았다.

그래서 Paperless-ngx에서 한글파일을 지원하도록 설정을 해 보았고, 이 글에서는 그 방법을 공유하고자 한다.
ChatGPT의 많은 도움을 받았다. ChatGPT에게 많은 영광을 돌린다.

사전 준비 사항

본 튜토리얼은 Paperless-ngx + Tika + Gotenberg의 Docker stack을 기준으로 설명한다.
해당 docker-compose.yml 파일은 Paperless-ngx 공식 레포지토리에서 확인할 수 있다: https://github.com/paperless-ngx/paperless-ngx/blob/main/docker/compose/docker-compose.postgres-tika.yml
(위 docker-compose.yml 파일은 PostgreSQL을 사용하지만 데이터베이스의 종류는 상관없다. SQLite를 사용해도 무방하다.)

본 튜토리얼은 Paperless-ngx 버전 v2.17.1을 기준으로 작성되었다.

1. Tika, Gotenberg 커스텀 이미지 작성하기

본 튜토리얼에서는 Tika와 Gotenberg의 도커 이미지를 약간 수정하여 사용한다.
말이 빌드이지 사실상 아주 가벼운 dependency 추가 정도만 하기 때문에, Raspberry Pi와 같은 저사양 머신에서도 충분히 빌드할 수 있다.
아래 두 dockerfile들을 각각 docker-compose.yml과 같은 폴더에 파일을 생성하여 저장한다.

tika.dockerfile

ARG TIKA_VERSION=3.2.0.0       # 필요하면 빌드 시 --build-arg 로 바꿀 수 있음

FROM apache/tika:${TIKA_VERSION} AS tika-hwp
ARG TIKA_VERSION
USER root

# 1) 다운로드 도구
RUN apt-get update -qq && \
    apt-get install -y --no-install-recommends curl

# 2) HWP parser JAR 추가
RUN mkdir -p /opt/tika-extra && \
    curl -L -o /opt/tika-extra/tika-parser-hwp-${TIKA_VERSION}.jar \
      https://repo1.maven.org/maven2/org/apache/tika/tika-parser-hwp/${TIKA_VERSION}/tika-parser-hwp-${TIKA_VERSION}.jar

# 3) tika-server 가 읽을 CLASSPATH 설정
ENV TIKA_CLASSPATH="/opt/tika-extra/*"

Tika는 제일 처음 문서를 업로드받았을 때, 문서에서 메타데이터와 텍스트를 추출하는 역할을 한다.
본 Dockerfile은 Apache Tika의 공식 이미지를 기반으로 하며, tika-parser-hwp JAR 파일을 추가하여 한글 파일(.hwp, .hwpx)을 처리할 수 있도록 한다.

gotenberg.dockerfile

ARG GOTENBERG_VERSION=8      # 필요하면 빌드 시 --build-arg 로 바꿀 수 있음

FROM gotenberg/gotenberg:${GOTENBERG_VERSION}
USER root

# 1) Java runtime + wget (unchanged)
RUN apt-get update -qq && \
    apt-get install -y --no-install-recommends openjdk-17-jre-headless 

# 2) LibreOffice Java bridge - make sure we pull it from backports
RUN echo "deb http://deb.debian.org/debian bookworm-backports main" \
       >> /etc/apt/sources.list && \
    apt-get update -qq && \
    apt-get install -y --no-install-recommends -t bookworm-backports \
        libreoffice-java-common

# 3) Register the H2Orestart filter
RUN wget -qO /tmp/H2Orestart.oxt \
        https://github.com/ebandal/H2Orestart/releases/download/v0.7.4/H2Orestart.oxt && \
    JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 \
    unopkg add --shared --suppress-license /tmp/H2Orestart.oxt 

RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

USER gotenberg

Gotenberg는 문서 파일을 PDF로 변환하는 역할을 한다.
특히나 docx, odt 등의 파일을 변환하기 위해 LibreOffice를 사용하는데,
LibreOffice에서 hwp 및 hwpx 파일을 열 수 있는 Extension이 있다는 것에 영감을 받아, 기본 Gotenberg 이미지의 Libreoffice에 이 Extension을 설치하는 Dockerfile을 작성했다.
기본 Gotenberg 이미지에는 Libreoffice Java bridge가 포함되어 있지 않기 때문에, 이를 설치하는 약간 번거로운 작업이 필요하다.

2. Django 앱 작성

기본적으로 Paperless-ngx에서 문서를 업로드하면 document consumer가 파일 형식을 판별하여, 지원하지 않는 파일이면 먼저 오류를 띄워 버린다.
이를 수정하기 위해, HWP 파일을 정상적으로 받아들이도록 작은 Django 앱을 작성하여 Paperless-ngx에 등록한다.

docker-compose.yml이 있는 폴더에 hwp_tika라는 폴더를 생성하고, 그 안에 apps.py, __init__.py, signals.py 파일을 생성한다.
즉, 다음과 같은 구조가 된다:

.
├── docker-compose.yml
├── tika.dockerfile
├── gotenberg.dockerfile
└── hwp_tika
    ├── apps.py
    ├── __init__.py
    └── signals.py

apps.py, __init__.py, signals.py 파일의 내용은 다음과 같다:

# apps.py
from django.apps import AppConfig

class HwpTikaConfig(AppConfig):
    name = "hwp_tika"

    def ready(self):
        from documents.signals import document_consumer_declaration
        from .signals import hwp_consumer_declaration

        document_consumer_declaration.connect(hwp_consumer_declaration)
# __init__.py
default_app_config = "hwp_tika.apps.HwpTikaConfig"
# signals.py
from paperless_tika.parsers import TikaDocumentParser

def _get_parser(*args, **kwargs):
    return TikaDocumentParser(*args, **kwargs)

def hwp_consumer_declaration(sender, **kwargs):
    """
    Tell Paperless how to deal with Hangul Word Processor files.
    """
    return {
        "parser": _get_parser,
        "weight": 11,                    # >10 so it wins over the stock entry set
        "mime_types": {
            "application/x-hwp": ".hwp",
            "application/hwp":   ".hwp",
        },
    }

위 코드는 Paperless-ngx의 문서 consumer에 한글 파일을 처리할 수 있는 커스텀 consumer를 등록하는 역할을 한다.

3. Docker Compose 파일 및 환경변수 수정

이제 위에서 작성한 Tika, Gotenberg 이미지를 Paperless-ngx의 docker-compose.yml에 통합한다.
docker-compose.yml 파일을 열고, 다음과 같이 수정한다:

 gotenberg:
-    image: docker.io/gotenberg/gotenberg
+    build:
+        context: .
+        dockerfile: gotenberg.dockerfile

 tika:
-    image: docker.io/apache/tika
+    build:
+        context: .
+        dockerfile: tika.dockerfile

다음으로 환경변수를 수정하여 위에서 작성한 커스텀 Django 앱을 등록한다.
docker-compose.env 파일을 열고, 다음 줄을 추가한다 (혹은 docker-compose.yml 파일의 environment 섹션에 추가한다):

PAPERLESS_APPS=hwp_tika.apps.HwpTikaConfig

OIDC와 같이 다른 앱이 이미 등록되어 있었다면, 콤마(,)로 구분하여 추가한다.

4. 빌드 및 실행

이제 모든 준비가 끝났다. 다음 명령어로 Docker 이미지를 빌드하고 실행한다:

docker compose build
docker compose up -d

이제 Paperless-ngx가 실행되고, 한글 파일(.hwp, .hwpx)을 업로드할 수 있으며, 자동으로 PDF/A로 아카이빙된다.




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • Setting up GitLab OAuth for Mattermost using Authentik