<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>DocWhoZee</title>
  <subtitle>dum spiro spero | 302.04 ppm computer science, #iphonephotography, #photograpy, #mysteries, #walking, #hiking, occasional #hacker, lately barista at the xyzzy café.</subtitle>
  <id>https://xyzzy.cafe/@docwhozee/blog/</id>
  <updated>2026-10-11T17:44:27Z</updated>
  <link href="https://xyzzy.cafe/@docwhozee/blog/feed.xml" rel="self" type="application/atom+xml"></link>
  <link href="https://xyzzy.cafe/@docwhozee/blog/" rel="alternate" type="text/html"></link>
  <entry>
    <title>Docker Compose Setup for Running Littlefedi</title>
    <id>https://xyzzy.cafe/@docwhozee/blog/01a12c10-e591-70d1-b007-f70bc37b6be0/</id>
    <link href="https://xyzzy.cafe/@docwhozee/blog/2026/10/11/docker-compose-setup-for-running-littlefedi/" rel="alternate" type="text/html"></link>
    <updated>2026-10-11T17:44:27Z</updated>
    <published>2026-10-11T17:44:27Z</published>
    <content type="html"><![CDATA[<p>Once we have the <a href="https://xyzzy.cafe/@docwhozee/blog/2026/10/11/building-littlefedi-docker-image/" rel="nofollow noreferrer noopener" target="_blank">Dockerfile for building a littlefedi docker image</a>, we can then make use of it and setup docker compose for it:</p>
<pre><code>networks:
  frontend:
    name: frontend
    external: true

services:
  littlefedi:
    image: littlefedi
    build: ./littlefedi
    environment:
      - LITTLEFEDI_AUTH_MFA_ENCRYPTION_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      - LITTLEFEDI_AUTH_REQUIRE_ADMIN_MFA=true
      - LITTLEFEDI_MEDIA_PROXY_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
      - LITTLEFEDI_SMTP_PASSWORD=XXXXXXXXXXXXXXXXX
    ulimits:
      nofile: 65536
    restart: unless-stopped
    networks:
      - frontend
    volumes:
      - ./data:/data
      - ./config:/config
      - ./backup:/backup
</code></pre>
<p>Notes:</p>
<ul>
<li>
<p>the <code>frontend</code> network is reverse-proxied through <code>caddy</code></p>
<pre><code>xyzzy.cafe {
      reverse_proxy littlefedi:8080
}
</code></pre>
</li>
<li>
<p>the <code>Dockerfile</code> and the littlefedi sources are located in a <code>littlefedi</code> subdirectory.</p>
</li>
<li>
<p>For the value of the environment variables, have a look at littlefedi&#39;s <a href="https://littlefedi.org/docs.html" rel="nofollow noreferrer noopener" target="_blank">documents</a>.</p>
</li>
</ul>
<p>To give it all a spin:</p>
<pre><code>docker compose build littlefedi
docker compose up
</code></pre>
<p><a href="/@docwhozee/blog/tags/t-bGl0dGxlZmVkaQ/" class="mention hashtag" rel="tag nofollow noreferrer noopener" target="_blank">#<span>littlefedi</span></a> <a href="/@docwhozee/blog/tags/t-ZG9ja2VyY29tcG9zZQ/" class="mention hashtag" rel="tag nofollow noreferrer noopener" target="_blank">#<span>DockerCompose</span></a></p>
]]></content>
  </entry>
  <entry>
    <title>Building Littlefedi Docker Image</title>
    <id>https://xyzzy.cafe/@docwhozee/blog/01a12bef-5f44-71c7-8cde-4872f3bc66bc/</id>
    <link href="https://xyzzy.cafe/@docwhozee/blog/2026/10/11/building-littlefedi-docker-image/" rel="alternate" type="text/html"></link>
    <updated>2026-10-11T17:07:50Z</updated>
    <published>2026-10-11T17:07:50Z</published>
    <content type="html"><![CDATA[<p><code>xyzzy.cafe</code> is powered by <a href="https://littlefedi.org" rel="nofollow noreferrer noopener" target="_blank">littlefedi</a>. I&#39;m running it inside a docker compose setup — which requires a littlefedi docker image to start with:</p>
<pre><code>FROM golang:1.27 AS build

WORKDIR /usr/src/littlefedi

# pre-copy/cache go.mod for pre-downloading dependencies and only redownloading them in subsequent builds if they change
COPY src/go.mod src/go.sum ./
RUN go mod download

COPY src .
RUN make build-blog

FROM debian:trixie-slim
RUN apt-get update &amp;&amp; \
    apt install -y --no-install-recommends ca-certificates gosu procps &amp;&amp; \
    rm -rf /var/lib/apt/lists/*
COPY --from=build /usr/src/littlefedi/littlefedi-blog /bin/littlefedi
EXPOSE 8080
# Create default app (UID/GID 1000)
RUN groupadd --gid 1000 app &amp;&amp; \
    useradd --uid 1000 --gid 1000 --comment &#34;&#34; app
RUN mkdir /config 
RUN mkdir /data
RUN mkdir /backup
VOLUME /config
VOLUME /data
VOLUME /backup
COPY entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh

ENTRYPOINT [&#34;entrypoint.sh&#34;]
CMD [&#34;/bin/littlefedi&#34;, &#34;--config&#34;, &#34;/config/littlefedi.toml&#34;]
</code></pre>
<p>I&#39;m using the &#34;official&#34; <code>golang</code> docker image here to build <code>littlefedi</code> from the expanded <a href="https://littlefedi.org/downloads/" rel="nofollow noreferrer noopener" target="_blank">littlefedi source tar</a> placed in the <code>src</code> subdirectory.</p>
<p>A couple of notes:</p>
<ul>
<li>
<p>I want to have the blog-enabled variant of littlefedi, hence the <code>make build-blog</code> incantation.</p>
</li>
<li>
<p>I&#39;m pretty much only interested in the littlefedi binary, thus, the multi-stage docker file: I pull a slim Debian image for the final docker image and copy the generated <code>littlefedi-blog</code> into it (renaming it to <code>littlefedi</code>).</p>
</li>
<li>
<p>To enable <code>littlefedi</code> to do TLS certificate verifications we need the <code>ca-certificates</code> package installed, we need <code>gosu</code> to run <code>littelfedi</code> as non-root, the <code>procps</code> package to install <code>ps</code> (for debugging).</p>
</li>
<li>
<p>Given that this is a slim docker container image I just went with</p>
<p>instead of faffing around with <a href="https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html" rel="nofollow noreferrer noopener" target="_blank">linux filesystem hierarchy standard compliant folder names.</a></p>
<ul>
<li><code>/config</code> to hold the <code>littlefedi.toml</code> configuration file,</li>
<li><code>/data</code> to store media</li>
<li><code>/backup</code> to hold littlefedi&#39;s backups</li>
</ul>
</li>
</ul>
<p>To ensure that mounted volumes (<code>/config</code>, <code>data</code>, <code>/backup</code>) are accessible from outside the docker image <code>entrypoint.sh</code> obtains the UID and GID from the mounted <code>/config</code> volume and modifies the <code>app</code> user and group to match:</p>
<pre><code>#!/bin/bash

CONFIG_UID=$(stat -c &#39;%u&#39; /config)
CONFIG_GID=$(stat -c &#39;%g&#39; /config)

usermod -u &#34;${CONFIG_UID}&#34; app
groupmod -g &#34;${CONFIG_GID}&#34; app

# ensure uid:gid are as intended for 
for v in /config /data /backup ; do
    chown -R app:app ${v}  
done

# run the passed-in args (or CMD if none provided)
exec gosu app &#34;$@&#34;
</code></pre>
<p>Using <code>gosu</code> we then run <code>littelfedi</code> (or whatever we pass in as commands) as user <code>app:app</code>.</p>
<p><a href="/@docwhozee/blog/tags/t-bGl0dGxlZmVkaQ/" class="mention hashtag" rel="tag nofollow noreferrer noopener" target="_blank">#<span>littlefedi</span></a> <a href="/@docwhozee/blog/tags/t-ZG9ja2Vy/" class="mention hashtag" rel="tag nofollow noreferrer noopener" target="_blank">#<span>docker</span></a> <a href="/@docwhozee/blog/tags/t-ZG9ja2VyZmlsZQ/" class="mention hashtag" rel="tag nofollow noreferrer noopener" target="_blank">#<span>dockerfile</span></a></p>
]]></content>
  </entry>
  <entry>
    <title>fall(en) leaf capturing a piece of blue sky</title>
    <id>https://xyzzy.cafe/@docwhozee/blog/01a12af4-d614-7b19-8950-a3317af5e5b8/</id>
    <link href="https://xyzzy.cafe/@docwhozee/blog/2026/10/11/fall-en-leaf-capturing-a-piece-of-blue-sky/" rel="alternate" type="text/html"></link>
    <updated>2026-10-11T12:34:11Z</updated>
    <published>2026-10-11T12:34:11Z</published>
    <content type="html"><![CDATA[<p><img src="https://xyzzy.cafe/@docwhozee/blog/2026/10/11/fall-en-leaf-capturing-a-piece-of-blue-sky/media/01a12af4-d479-729e-97c5-57527ed7d0ec.jpg" alt="A brown leaf, fallen from a tree, on the ground had captured a tiny puddle. The tiny puddle reflected a piece of blue sky."></p><p><a href="/@docwhozee/blog/tags/t-cGhvdG9ncmFwaHk/" class="mention hashtag" rel="tag nofollow noreferrer noopener" target="_blank">#<span>photography</span></a> <a href="/@docwhozee/blog/tags/t-aXBob25lcGhvdG9ncmFwaHk/" class="mention hashtag" rel="tag nofollow noreferrer noopener" target="_blank">#<span>iphonephotography</span></a> <a href="/@docwhozee/blog/tags/t-ZmFsbA/" class="mention hashtag" rel="tag nofollow noreferrer noopener" target="_blank">#<span>fall</span></a> <a href="/@docwhozee/blog/tags/t-Ymx1ZXNreQ/" class="mention hashtag" rel="tag nofollow noreferrer noopener" target="_blank">#<span>BlueSky</span></a></p>]]></content>
  </entry>
</feed>