<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://subinsong.com/ko-kr/feed.xml" rel="self" type="application/atom+xml"/><link href="https://subinsong.com/ko-kr/" rel="alternate" type="text/html"/><updated>2026-03-02T17:35:14+00:00</updated><id>https://subinsong.com/feed.xml</id><title type="html">blank</title><entry><title type="html">Paperless-ngx에서 한글파일 지원하도록 설정하기</title><link href="https://subinsong.com/ko-kr/blog/2025/paperless-ngx%EC%97%90%EC%84%9C-%ED%95%9C%EA%B8%80%ED%8C%8C%EC%9D%BC-%EC%A7%80%EC%9B%90%ED%95%98%EB%8F%84%EB%A1%9D-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0/" rel="alternate" type="text/html" title="Paperless-ngx에서 한글파일 지원하도록 설정하기"/><published>2025-07-10T00:00:00+00:00</published><updated>2025-07-10T00:00:00+00:00</updated><id>https://subinsong.com/blog/2025/paperless-ngx%EC%97%90%EC%84%9C-%ED%95%9C%EA%B8%80%ED%8C%8C%EC%9D%BC-%EC%A7%80%EC%9B%90%ED%95%98%EB%8F%84%EB%A1%9D-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0</id><content type="html" xml:base="https://subinsong.com/blog/2025/paperless-ngx%EC%97%90%EC%84%9C-%ED%95%9C%EA%B8%80%ED%8C%8C%EC%9D%BC-%EC%A7%80%EC%9B%90%ED%95%98%EB%8F%84%EB%A1%9D-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0/"><![CDATA[<p><a href="https://docs.paperless-ngx.com/">Paperless-ngx</a>는 셀프호스팅할수 있는 문서 관리 시스템으로, pdf, docx, odt 등 다양한 문서 형식을 지원한다. <br/> 하지만 대한민국에서 많이 사용하는 한글파일(.hwp, .hwpx)은 기본적으로 지원하지 않는다. <br/> 나는 Paperless-ngx의 email rule을 이용하여 받은 이메일의 첨부파일들을 자동으로 아카이빙하고 있는데,<br/> 많은 문서들이 한글 파일로 오고가는 상황에서 Paperless-ngx에서 처리할 수 없어 불편함이 많았다.</p> <p>그래서 Paperless-ngx에서 한글파일을 지원하도록 설정을 해 보았고, 이 글에서는 그 방법을 공유하고자 한다.<br/> ChatGPT의 많은 도움을 받았다. ChatGPT에게 많은 영광을 돌린다.</p> <h2 id="사전-준비-사항">사전 준비 사항</h2> <p>본 튜토리얼은 Paperless-ngx + Tika + Gotenberg의 Docker stack을 기준으로 설명한다.<br/> 해당 <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> 파일은 Paperless-ngx 공식 레포지토리에서 확인할 수 있다: <a href="https://github.com/paperless-ngx/paperless-ngx/blob/main/docker/compose/docker-compose.postgres-tika.yml">https://github.com/paperless-ngx/paperless-ngx/blob/main/docker/compose/docker-compose.postgres-tika.yml</a><br/> (위 <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> 파일은 PostgreSQL을 사용하지만 데이터베이스의 종류는 상관없다. SQLite를 사용해도 무방하다.)</p> <p>본 튜토리얼은 Paperless-ngx 버전 <code class="language-plaintext highlighter-rouge">v2.17.1</code>을 기준으로 작성되었다.</p> <h2 id="1-tika-gotenberg-커스텀-이미지-작성하기">1. Tika, Gotenberg 커스텀 이미지 작성하기</h2> <p>본 튜토리얼에서는 Tika와 Gotenberg의 도커 이미지를 약간 수정하여 사용한다.<br/> 말이 빌드이지 사실상 아주 가벼운 dependency 추가 정도만 하기 때문에, Raspberry Pi와 같은 저사양 머신에서도 충분히 빌드할 수 있다.<br/> 아래 두 dockerfile들을 각각 <code class="language-plaintext highlighter-rouge">docker-compose.yml</code>과 같은 폴더에 파일을 생성하여 저장한다.</p> <h3 id="tikadockerfile"><code class="language-plaintext highlighter-rouge">tika.dockerfile</code></h3> <div class="language-dockerfile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">ARG</span><span class="s"> TIKA_VERSION=3.2.0.0       # 필요하면 빌드 시 --build-arg 로 바꿀 수 있음</span>

<span class="k">FROM</span><span class="w"> </span><span class="s">apache/tika:${TIKA_VERSION}</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="s">tika-hwp</span>
<span class="k">ARG</span><span class="s"> TIKA_VERSION</span>
<span class="k">USER</span><span class="s"> root</span>

<span class="c"># 1) 다운로드 도구</span>
<span class="k">RUN </span>apt-get update <span class="nt">-qq</span> <span class="o">&amp;&amp;</span> <span class="se">\
</span>    apt-get <span class="nb">install</span> <span class="nt">-y</span> <span class="nt">--no-install-recommends</span> curl

<span class="c"># 2) HWP parser JAR 추가</span>
<span class="k">RUN </span><span class="nb">mkdir</span> <span class="nt">-p</span> /opt/tika-extra <span class="o">&amp;&amp;</span> <span class="se">\
</span>    curl <span class="nt">-L</span> <span class="nt">-o</span> /opt/tika-extra/tika-parser-hwp-<span class="k">${</span><span class="nv">TIKA_VERSION</span><span class="k">}</span>.jar <span class="se">\
</span>      https://repo1.maven.org/maven2/org/apache/tika/tika-parser-hwp/<span class="k">${</span><span class="nv">TIKA_VERSION</span><span class="k">}</span>/tika-parser-hwp-<span class="k">${</span><span class="nv">TIKA_VERSION</span><span class="k">}</span>.jar

<span class="c"># 3) tika-server 가 읽을 CLASSPATH 설정</span>
<span class="k">ENV</span><span class="s"> TIKA_CLASSPATH="/opt/tika-extra/*"</span>
</code></pre></div></div> <p>Tika는 제일 처음 문서를 업로드받았을 때, 문서에서 메타데이터와 텍스트를 추출하는 역할을 한다.<br/> 본 Dockerfile은 Apache Tika의 공식 이미지를 기반으로 하며, <code class="language-plaintext highlighter-rouge">tika-parser-hwp</code> JAR 파일을 추가하여 한글 파일(.hwp, .hwpx)을 처리할 수 있도록 한다.</p> <h3 id="gotenbergdockerfile"><code class="language-plaintext highlighter-rouge">gotenberg.dockerfile</code></h3> <div class="language-dockerfile highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">ARG</span><span class="s"> GOTENBERG_VERSION=8      # 필요하면 빌드 시 --build-arg 로 바꿀 수 있음</span>

<span class="k">FROM</span><span class="s"> gotenberg/gotenberg:${GOTENBERG_VERSION}</span>
<span class="k">USER</span><span class="s"> root</span>

<span class="c"># 1) Java runtime + wget (unchanged)</span>
<span class="k">RUN </span>apt-get update <span class="nt">-qq</span> <span class="o">&amp;&amp;</span> <span class="se">\
</span>    apt-get <span class="nb">install</span> <span class="nt">-y</span> <span class="nt">--no-install-recommends</span> openjdk-17-jre-headless 

<span class="c"># 2) LibreOffice Java bridge - make sure we pull it from backports</span>
<span class="k">RUN </span><span class="nb">echo</span> <span class="s2">"deb http://deb.debian.org/debian bookworm-backports main"</span> <span class="se">\
</span>       <span class="o">&gt;&gt;</span> /etc/apt/sources.list <span class="o">&amp;&amp;</span> <span class="se">\
</span>    apt-get update <span class="nt">-qq</span> <span class="o">&amp;&amp;</span> <span class="se">\
</span>    apt-get <span class="nb">install</span> <span class="nt">-y</span> <span class="nt">--no-install-recommends</span> <span class="nt">-t</span> bookworm-backports <span class="se">\
</span>        libreoffice-java-common

<span class="c"># 3) Register the H2Orestart filter</span>
<span class="k">RUN </span>wget <span class="nt">-qO</span> /tmp/H2Orestart.oxt <span class="se">\
</span>        https://github.com/ebandal/H2Orestart/releases/download/v0.7.4/H2Orestart.oxt <span class="o">&amp;&amp;</span> <span class="se">\
</span>    <span class="nv">JAVA_HOME</span><span class="o">=</span>/usr/lib/jvm/java-17-openjdk-amd64 <span class="se">\
</span>    unopkg add <span class="nt">--shared</span> <span class="nt">--suppress-license</span> /tmp/H2Orestart.oxt 

<span class="k">RUN </span><span class="nb">rm</span> <span class="nt">-rf</span> /var/lib/apt/lists/<span class="k">*</span> /tmp/<span class="k">*</span> /var/tmp/<span class="k">*</span>

<span class="k">USER</span><span class="s"> gotenberg</span>
</code></pre></div></div> <p>Gotenberg는 문서 파일을 PDF로 변환하는 역할을 한다.<br/> 특히나 docx, odt 등의 파일을 변환하기 위해 LibreOffice를 사용하는데,<br/> <a href="https://github.com/ebandal/H2Orestart">LibreOffice에서 hwp 및 hwpx 파일을 열 수 있는 Extension</a>이 있다는 것에 영감을 받아, 기본 Gotenberg 이미지의 Libreoffice에 이 Extension을 설치하는 Dockerfile을 작성했다.<br/> 기본 Gotenberg 이미지에는 Libreoffice Java bridge가 포함되어 있지 않기 때문에, 이를 설치하는 약간 번거로운 작업이 필요하다.</p> <h2 id="2-django-앱-작성">2. Django 앱 작성</h2> <p>기본적으로 Paperless-ngx에서 문서를 업로드하면 document consumer가 파일 형식을 판별하여, 지원하지 않는 파일이면 먼저 오류를 띄워 버린다.<br/> 이를 수정하기 위해, HWP 파일을 정상적으로 받아들이도록 작은 Django 앱을 작성하여 Paperless-ngx에 등록한다.</p> <p><code class="language-plaintext highlighter-rouge">docker-compose.yml</code>이 있는 폴더에 <code class="language-plaintext highlighter-rouge">hwp_tika</code>라는 폴더를 생성하고, 그 안에 <code class="language-plaintext highlighter-rouge">apps.py</code>, <code class="language-plaintext highlighter-rouge">__init__.py</code>, <code class="language-plaintext highlighter-rouge">signals.py</code> 파일을 생성한다.<br/> 즉, 다음과 같은 구조가 된다:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.
├── docker-compose.yml
├── tika.dockerfile
├── gotenberg.dockerfile
└── hwp_tika
    ├── apps.py
    ├── __init__.py
    └── signals.py
</code></pre></div></div> <p><code class="language-plaintext highlighter-rouge">apps.py</code>, <code class="language-plaintext highlighter-rouge">__init__.py</code>, <code class="language-plaintext highlighter-rouge">signals.py</code> 파일의 내용은 다음과 같다:</p> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># apps.py
</span><span class="kn">from</span> <span class="n">django.apps</span> <span class="kn">import</span> <span class="n">AppConfig</span>

<span class="k">class</span> <span class="nc">HwpTikaConfig</span><span class="p">(</span><span class="n">AppConfig</span><span class="p">):</span>
    <span class="n">name</span> <span class="o">=</span> <span class="sh">"</span><span class="s">hwp_tika</span><span class="sh">"</span>

    <span class="k">def</span> <span class="nf">ready</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="kn">from</span> <span class="n">documents.signals</span> <span class="kn">import</span> <span class="n">document_consumer_declaration</span>
        <span class="kn">from</span> <span class="n">.signals</span> <span class="kn">import</span> <span class="n">hwp_consumer_declaration</span>

        <span class="n">document_consumer_declaration</span><span class="p">.</span><span class="nf">connect</span><span class="p">(</span><span class="n">hwp_consumer_declaration</span><span class="p">)</span>
</code></pre></div></div> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># __init__.py
</span><span class="n">default_app_config</span> <span class="o">=</span> <span class="sh">"</span><span class="s">hwp_tika.apps.HwpTikaConfig</span><span class="sh">"</span>
</code></pre></div></div> <div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># signals.py
</span><span class="kn">from</span> <span class="n">paperless_tika.parsers</span> <span class="kn">import</span> <span class="n">TikaDocumentParser</span>

<span class="k">def</span> <span class="nf">_get_parser</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="k">return</span> <span class="nc">TikaDocumentParser</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">hwp_consumer_declaration</span><span class="p">(</span><span class="n">sender</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
    <span class="sh">"""</span><span class="s">
    Tell Paperless how to deal with Hangul Word Processor files.
    </span><span class="sh">"""</span>
    <span class="k">return</span> <span class="p">{</span>
        <span class="sh">"</span><span class="s">parser</span><span class="sh">"</span><span class="p">:</span> <span class="n">_get_parser</span><span class="p">,</span>
        <span class="sh">"</span><span class="s">weight</span><span class="sh">"</span><span class="p">:</span> <span class="mi">11</span><span class="p">,</span>                    <span class="c1"># &gt;10 so it wins over the stock entry set
</span>        <span class="sh">"</span><span class="s">mime_types</span><span class="sh">"</span><span class="p">:</span> <span class="p">{</span>
            <span class="sh">"</span><span class="s">application/x-hwp</span><span class="sh">"</span><span class="p">:</span> <span class="sh">"</span><span class="s">.hwp</span><span class="sh">"</span><span class="p">,</span>
            <span class="sh">"</span><span class="s">application/hwp</span><span class="sh">"</span><span class="p">:</span>   <span class="sh">"</span><span class="s">.hwp</span><span class="sh">"</span><span class="p">,</span>
        <span class="p">},</span>
    <span class="p">}</span>
</code></pre></div></div> <p>위 코드는 Paperless-ngx의 문서 consumer에 한글 파일을 처리할 수 있는 커스텀 consumer를 등록하는 역할을 한다.</p> <h2 id="3-docker-compose-파일-및-환경변수-수정">3. Docker Compose 파일 및 환경변수 수정</h2> <p>이제 위에서 작성한 Tika, Gotenberg 이미지를 Paperless-ngx의 <code class="language-plaintext highlighter-rouge">docker-compose.yml</code>에 통합한다.<br/> <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> 파일을 열고, 다음과 같이 수정한다:</p> <div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="na">gotenberg</span><span class="pi">:</span>
<span class="pi">-</span>    <span class="na">image</span><span class="pi">:</span> <span class="s">docker.io/gotenberg/gotenberg</span>
<span class="na">+    build</span><span class="pi">:</span>
<span class="na">+        context</span><span class="pi">:</span> <span class="s">.</span>
<span class="na">+        dockerfile</span><span class="pi">:</span> <span class="s">gotenberg.dockerfile</span>

 <span class="s">tika</span><span class="err">:</span>
<span class="pi">-</span>    <span class="na">image</span><span class="pi">:</span> <span class="s">docker.io/apache/tika</span>
<span class="na">+    build</span><span class="pi">:</span>
<span class="na">+        context</span><span class="pi">:</span> <span class="s">.</span>
<span class="na">+        dockerfile</span><span class="pi">:</span> <span class="s">tika.dockerfile</span>
</code></pre></div></div> <p>다음으로 환경변수를 수정하여 위에서 작성한 커스텀 Django 앱을 등록한다.<br/> <code class="language-plaintext highlighter-rouge">docker-compose.env</code> 파일을 열고, 다음 줄을 추가한다 (혹은 <code class="language-plaintext highlighter-rouge">docker-compose.yml</code> 파일의 <code class="language-plaintext highlighter-rouge">environment</code> 섹션에 추가한다):</p> <pre><code class="language-env">PAPERLESS_APPS=hwp_tika.apps.HwpTikaConfig
</code></pre> <p>OIDC와 같이 다른 앱이 이미 등록되어 있었다면, 콤마(<code class="language-plaintext highlighter-rouge">,</code>)로 구분하여 추가한다.</p> <h2 id="4-빌드-및-실행">4. 빌드 및 실행</h2> <p>이제 모든 준비가 끝났다. 다음 명령어로 Docker 이미지를 빌드하고 실행한다:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker compose build
docker compose up <span class="nt">-d</span>
</code></pre></div></div> <p>이제 Paperless-ngx가 실행되고, 한글 파일(.hwp, .hwpx)을 업로드할 수 있으며, 자동으로 PDF/A로 아카이빙된다.</p>]]></content><author><name></name></author><category term="homeserver"/><category term="self-hosting"/><category term="paperless-ngx"/><summary type="html"><![CDATA[Paperless-ngx에서 한글파일(.hwp, .hwpx)을 지원하도록 설정하는 방법에 대한 가이드]]></summary></entry><entry><title type="html">Authentik을 이용하여 Matttermost에 GitLab OAuth 설정하기</title><link href="https://subinsong.com/ko-kr/blog/2025/configuring-gitlab-oauth-for-mattermost-with-authentik/" rel="alternate" type="text/html" title="Authentik을 이용하여 Matttermost에 GitLab OAuth 설정하기"/><published>2025-07-09T00:00:00+00:00</published><updated>2025-07-09T00:00:00+00:00</updated><id>https://subinsong.com/blog/2025/configuring-gitlab-oauth-for-mattermost-with-authentik</id><content type="html" xml:base="https://subinsong.com/blog/2025/configuring-gitlab-oauth-for-mattermost-with-authentik/"><![CDATA[<p>현재 <a href="https://mmlab.snu.ac.kr/">우리 연구실</a>에서는 <a href="https://mattermost.com/">Mattermost</a>를 협업 툴로 사용하고 있다. <br/> 최근의 연구실의 홈페이지, 웹메일, 위키, Mattermost 계정을 통합하기 위해 <a href="https://goauthentik.io/">Authentik</a>을 도입했다. <br/> 홈페이지, 웹메일, 위키는 모두 OIDC provider를 이용해 설정을 완료했으나, Mattermost에서 OIDC를 사용하려면 유료 라이센스를 구매해야 하는 문제점이 있었다. <br/> Mattermost의 무료 team edition에서 지원하는 SSO provider는 GitLab OAuth뿐이다. (참고: <a href="https://docs.mattermost.com/onboard/sso-gitlab.html">https://docs.mattermost.com/onboard/sso-gitlab.html</a>)</p> <p>그래서, Authentik의 OIDC provider를 마치 GitLab OAuth처럼 보이도록 설정하여 Mattermost와 연동하는 방법을 정리했다. <br/> 온라인에서 몇몇 자료를 찾을 수 있었지만, Mattermost와 Authentik 버전이 다 조금씩 달라서 설정에 어려움을 겪었다.</p> <p>본 글에 나온 내용은 Mattermost 10.9.1 버전과 Authentik 2025.6.3 버전을 기준으로 작성되었다. <br/> 또한, 본 튜토리얼대로 하려면 Authentik 앞에 <strong>reverse proxy를 반드시 사용해야 한다.</strong> (path rewrite 때문) <br/> 참고로 우리 연구실의 Authentik은 <a href="https://caddyserver.com/">Caddy</a> v2 reverse proxy를 사용하고 있고, 본 튜토리얼도 이를 기준으로 작성되었다. <br/> Traefik이나 Nginx 등 다른 reverse proxy를 사용한다면, 그에 맞춰 설정 파일을 변형하여 작성하길 바란다.</p> <p>참고: 본 튜토리얼은 Authentik OAuth2 provider의 <a href="https://docs.goauthentik.io/docs/add-secure-apps/providers/oauth2/github-compatibility">GitHub-compatible endpoint</a>를 활용한다.</p> <h2 id="1-authentik-설정">1. Authentik 설정</h2> <h3 id="application-생성">Application 생성</h3> <p>관리자 인터페이스에서, 좌측 사이드바의 “Applications” 메뉴를 클릭한 후, “Create” 버튼을 클릭한 후, 다음과 같이 입력한다:</p> <ul> <li><strong>이름</strong>: Mattermost</li> <li><strong>슬러그</strong>: mattermost</li> </ul> <p>아래쪽의 “Create” 버튼을 클릭하여 Application 생성을 완료한다.</p> <p><img src="/assets/img/image-20250709171158672.png" alt="image-20250709171158672" width="100%"/></p> <h3 id="provider-생성">Provider 생성</h3> <p>다음으로, 좌측 사이드바의 “Providers” 메뉴를 클릭 -&gt; “Create”를 클릭한다.</p> <p>“OAuth2/OpenID Provider”를 선택하고 아래쪽의 “Finish” 버튼을 누른다.</p> <p>다음 탭에서 다음 정보들을 입력하고 저장한다:</p> <ul> <li><strong>이름</strong>: Provider for Mattermost (혹은 임의의 이름)</li> <li><strong>인가 플로우</strong>: 임의로 설정. 저는 <code class="language-plaintext highlighter-rouge">default-provider-authorization-explicit-consent (Authorize Application)</code>로 설정했습니다</li> <li><strong>리디렉션 URI/Origin (정규표현식)</strong> <ul> <li><code class="language-plaintext highlighter-rouge">https://mattermost.my.domain/signup/gitlab/complete</code></li> <li><code class="language-plaintext highlighter-rouge">https://mattermost.my.domain/login/gitlab/complete</code></li> <li><code class="language-plaintext highlighter-rouge">mattermost.my.domain</code>을 자신의 mattermost 서버 도메인으로 바꿔 입력한다.</li> </ul> </li> <li><strong>고급 프로토콜 설정 &gt; 스코프 (scopes)</strong> : 전부 다 빼도 된다. 왜냐하면 우리는 Authentik의 GitHub-compatible endpoint를 사용할 것이고 이에 따른 <a href="https://docs.goauthentik.io/docs/add-secure-apps/providers/oauth2/github-compatibility#special-scopes-for-github-compatibility">특별 scope</a>들만 요청되기 때문이다.</li> <li><strong>클라이언트 ID</strong>와 <strong>클라이언트 비밀</strong>은 다음 단계에서 사용될 것이기 때문에 잘 기록해 둔다.</li> </ul> <p><img src="/assets/img/Screenshot%20From%202025-07-09%2017-22-42-obfuscated.png" alt="Screenshot From 2025-07-09 17-22-42-obfuscated" width="100%"/></p> <h3 id="application에-provider-추가">Application에 Provider 추가</h3> <p>다시 좌측의 Applications 메뉴 -&gt; Mattermost 선택 -&gt; 수정 -&gt; Provider에 “Provider for Mattermost”를 선택한다.</p> <h2 id="2-mattermost-gitlab-auth-설정">2. Mattermost GitLab Auth 설정</h2> <p>Mattermost의 관리자 UI -&gt; Authentication -&gt; GitLab 메뉴로 들어간다.</p> <ul> <li><strong>Enable authentication with GitLab:</strong> True</li> <li><strong>Application ID:</strong> 1단계에서 기록한 클라이언트 ID</li> <li><strong>Application Secret Key:</strong> 1단계에서 기록한 클라이언트 비밀</li> <li><strong>GitLab Site URL:</strong> Authentik URL (예: <code class="language-plaintext highlighter-rouge">https://sso.my.domain</code>)</li> </ul> <p>저장한다.</p> <h2 id="3-reverse-proxy-설정">3. Reverse Proxy 설정</h2> <p>Authentik의 reverse proxy 설정파일을 수정하여, path rewrite 룰을 추가한다.</p> <p>아래는 Caddy reverse proxy의 경우에 사용되는 Caddyfile의 예시이다:</p> <pre><code class="language-caddyfile">sso.my.domain {
    uri replace /api/v4/user /user  1                         # User API Endpoint
    uri replace /oauth/authorize /login/oauth/authorize 1     # Auth Endpoint
    uri replace /oauth/token /login/oauth/access_token 1      # Token Endpoint
    uri replace /login/login/oauth /oauth 1
    reverse_proxy localhost:9000
}
</code></pre> <h2 id="4-mattermost에서-gitlab-oauth로-로그인하기">4. Mattermost에서 GitLab OAuth로 로그인하기</h2> <p>기존 Mattermost 유저 여부에 따라서 로그인 방법이 달라진다.</p> <h3 id="기존-mattermost-유저가-아닌-경우">기존 Mattermost 유저가 아닌 경우</h3> <p>Mattermost 로그인 페이지에서 “Log in with GitLab” 버튼을 클릭하여 Authentik 로그인 페이지로 이동한다. <br/> Authentik에서 로그인한 후 (혹은 회원가입 후), Mattermost로 리디렉션된다. 이때 자동으로 Mattermost 계정이 생성된다.</p> <h3 id="기존-mattermost-유저인-경우">기존 Mattermost 유저인 경우</h3> <p>대부분의 SSO를 지원하는 애플리케이션들의 경우 관리자가 일괄적으로 모든 유저들을 SSO로 전환할 수 있는 기능이 있지만… <del>킹받게도</del> Mattermost에는 그런 기능이 없다.<br/> 각 유저가 직접 프로필 설정에서 GitLab OAuth로 전환해야 한다.<br/> 다음은 내가 전환을 부탁하기 위해 랩 구성원들에게 보낸 메시지 내용이다. 이 내용을 참고해서 각 유저가 계정을 전환하면 된다:</p> <ol> <li>Mattermost(PC)의 우측 최상단의 자신의 프로필 이미지 클릭 -&gt; Profile <ul> <li>데스크탑 앱 및 모바일 앱에서는 설정 불가, 반드시 PC 브라우저에서만 가능</li> </ul> </li> <li>좌측 사이드바의 Security/보안 클릭</li> <li>우측 메뉴 맨 하단의 “Sign-in Method/접속 방식” 우측의 “Edit/편집” 클릭</li> <li>“Switch to Using GitLab SSO” 클릭</li> <li>화면에서 시키는대로 현재 Mattermost 계정 비밀번호 입력하고 “Switch Account to Gitlab SSO” 클릭</li> <li>SSO 사이트로 리다이렉트되면, 자신의 SSO 아이디/비밀번호로 로그인</li> <li>계정 전환이 완료되면, 이때부터는 Mattermost에서 “Log In with SSO”를 눌러서 로그인한다. (기존의 아이디, 비밀번호 사용 불가)</li> </ol> <h2 id="tips">Tips</h2> <h3 id="로그인-화면에서-gitlab-버튼-텍스트-변경하기--아이콘-숨기기">로그인 화면에서 GitLab 버튼 텍스트 변경하기 / 아이콘 숨기기</h3> <p>Mattermost 로그인 페이지에서 GitLab 로그인 버튼의 텍스트를 바꾸고 싶다면, Mattermost의 <code class="language-plaintext highlighter-rouge">config.json</code> 파일을 수정한다. <br/> <code class="language-plaintext highlighter-rouge">GitLabSettings.ButtonText</code> 항목을 원하는 텍스트로 바꾸면 된다.<br/> 버튼 아이콘을 바꾸는 설정은 따로 없어서…. 나는 custom CSS를 이용하여 아이콘을 숨겼다.<br/> Mattermost에는 custom CSS를 적용할 수 있는 기능이 없기 때문에 플러그인을 이용해야 한다. 나는 <a href="https://github.com/discourse/mattermost-css-hacks">이 레포지토리</a>에 있는 가이드를 가지고 플러그인을 생성했다.<br/> 적용한 CSS는 다음과 같다:</p> <div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">svg</span><span class="o">[</span><span class="nt">aria-label</span><span class="o">=</span><span class="s1">"Gitlab Icon"</span><span class="o">]</span> <span class="p">{</span>
    <span class="nl">display</span><span class="p">:</span> <span class="nb">none</span> <span class="cp">!important</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div> <h3 id="idpassword-로그인-비활성화하기">ID/Password 로그인 비활성화하기</h3> <p>모든 유저들이 전환을 완료했다면, Mattermost의 관리자 UI -&gt; Authentication -&gt; Email 메뉴로 들어가서 다음과 같이 설정한다:</p> <ul> <li><strong>Enable account creation with email:</strong> False</li> <li><strong>Enable sign-in with email:</strong> False</li> <li><strong>Enable sign-in with username:</strong> False</li> </ul> <h2 id="마치며">마치며</h2> <p>뭔가 마무리를 해야 할 것 같은데 뭐라 써야 할지 잘 모르겠다.<br/> 앞으로도 연구실 서버 관리 일지를 비롯하여, 이 글과 같이 나만 알기엔 아까운 다양한 팁들을 정리해보려 한다.<br/> 끝.</p>]]></content><author><name></name></author><category term="mmlab-webmaster"/><category term="self-hosting"/><summary type="html"><![CDATA[현재 우리 연구실에서는 Mattermost를 협업 툴로 사용하고 있다. 최근의 연구실의 홈페이지, 웹메일, 위키, Mattermost 계정을 통합하기 위해 Authentik을 도입했다. 홈페이지, 웹메일, 위키는 모두 OIDC provider를 이용해 설정을 완료했으나, Mattermost에서 OIDC를 사용하려면 유료 라이센스를 구매해야 하는 문제점이 있었다. Mattermost의 무료 team edition에서 지원하는 SSO provider는 GitLab OAuth뿐이다. (참고: https://docs.mattermost.com/onboard/sso-gitlab.html)]]></summary></entry></feed>