💾 Archived View for senders.io › gemlog › 2021-03-09-dockerization.gmi captured on 2023-09-08 at 16:13:49. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2021-12-04)

-=-=-=-=-=-=-

Dockerization

Decided to write up a quick gemlog on how I run my server via docker.

Background

I have a debian server I run out of my network rack that I host my website, services, and capsule on. I like to run everything out of docker for isolation as well as management ease. I only have minimal packages installed on my actual host machine and I can easily drop a service without worrying about lingering packages / daemons running.

A Pro-tip

Fail2ban should run on your actual host machine, since it's important :)

Setup

To get started I created a directory to store the gemini contents in: apps/gemini.Inside I setup four additional directories:

molly-brown

I went with molly-brown since it seemed easy to setup and could even provide mulituser if I choose to go that route. Since I don't run my apps on the host I created a Dockerfile to run the application in:

FROM debian:stable-slim

RUN apt-get update && apt-get install -y golang git
RUN mkdir /opt/go
ENV GOPATH=/opt/go
RUN go get github.com/BurntSushi/toml
RUN go get tildegit.org/solderpunk/molly-brown

EXPOSE 1965
VOLUME /etc/certs
VOLUME /var/log/molly
VOLUME /var/gemini

COPY molly.conf /etc/molly.conf

ENTRYPOINT /opt/go/bin/molly-brown

This will let us run the service in the container as long as we attach the necessary volumes.

gemtext

I write and store the gemtext in the gemini directory that I mount in the container as a volume to be served.

gemfeed

In order to create the atom.xml I serve on this capsule I cloned gemfeed in the atom/ directory. I created a Dockerfile as well in order to run this script to generate attaching a readonly copy of the gemini/ directory and a volume to place the generated xml:

FROM python:latest

COPY gemfeed/gemfeed.py /
COPY gemfeed/setup.py /
COPY docker-entrypoint.sh /

RUN python -m pip install -e .

VOLUME /feed
VOLUME /gemini

CMD /docker-entrypoint.sh

Since my content is served over different directories I had to apply a patch from the gemfeed pull-requests. However, at least on my version of python it required a fix where the fnmatch didn't actually work. The diff I applied:

// it's a bit too large to just drop here so I'll link to my git commit:

[https] git.senders.io (diff)

docker-compose

I like to setup my images via docker-compose as it generally provides a clean interface for interacting with the images:

version: '3'
services:
  gemini-capsule:
    build: capsule/
    ports:
      - "1965:1965"
    restart: unless-stopped
    volumes:
      - "${PWD}/volumes/log:/var/log/molly"
      - "${PWD}/gemini:/var/gemini"
      - "${PWD}/volumes/feed/atom.xml:/var/gemini/feed/atom.xml"
      - "/path/to/certs:/etc/certs:ro"
  gemini-feed:
    build: atom/
    volumes:
      - "${PWD}/gemini:/gemini:ro"
      - "${PWD}/volumes/feed:/feed"

I haven't found a great way of managing the feed-script, Ideally I'd install it on the server's host and cronjob it to generate the feed - but this allows for a currently more managed way generating the feed.

Gotchas

The biggest gotcha I am currently facing is: how do I place my atom.xml in the /var/gemini directory while keeping it a readonly mount? Originally, I thought by mounting the feed/atom.xml into the /var/gemini/feed/atom.xml I was working around this, but it does in fact create the feed/atom.xml in the host directory. So the problem for the day is how to better manage this to prevent generated content from leaking into static content?

I have a .gitignore ensuring I don't commit anything that is generated, but I dislike this. But it works so I'm keeping it for now.

Conclusion

molly-brown live reloads the files so I can save and publish new gemlogs, having the atom feed regenerate when I am finished writting.

Home