La Vita è Bear

Run my own Nitter instance

Nitter is an Open Source alternative Twitter web frontend. It’s also more than just a frontend, as it also provides APIs for third party apps to use. For example, the ActivityPub app I use, Fedilab, also has a feature to add timelines to twitter users via nitter instances, so I can still “follow” some important twitter accounts not on ActivityPub yet (for example, I use it to access @CaltrainAlerts on my commuting days to be on top of delays and cancellations).

Nitter does have an official instance,, but it has certain stability issues. So I also run an instance myself on my Linux box at home for my own use.

Because I don’t want to deal with the whole nim development environment, and also the lack of “releases” of Nitter itself, I chose to use containers to run it. Also, instead of docker, I use podman to run containers, and podman provides a neat feature to generate systemd unit file out of a running container so the container itself will work like any systemd service on your system. I took full advantage of that.

Nitter does have a dependency on Redis, and it provided a docker-compose file to run both Nitter and Redis containers. But I don’t really want to deal with docker-compose, so I just installed Redis locally on my Linux box (I’m using Debian testing, so it’s simply apt install redis), changed the config to only bind on localhost, and enabled host loopback on podman’s args.

In the end, the full ExecStart line of my ~/.config/systemd/user/container-nitter.service file is:

ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --sdnotify=conmon --cgroups=no-conmon --runtime=crun --rm -d --replace --name nitter --net slirp4netns:allow_host_loopback=true -v /home/fishy/.config/nitter/nitter.conf:/src/nitter.conf -p 9098:9098

In nitter.conf, I just change it to the ip address assigned by slirp4netns:

redisHost = ""
redisPort = 6379

I also run an nginx server to provide https and map that to localhost:9098.

Due to the lack of releases, I just run the :latest container, and occasionally run podman pull followed by systemctl --user restart container-nitter to update it to the latest version. But occasionally the :latest version can have bugs to make it unusable, so I usually first run podman image inspect to get the sha256 sum of the container image I’m currently using before running podman pull. If the new :latest version turned out to be broken, I just run podman image tag to “revert” to the previous known good version. I have this script to automate this:

$ cat ~/bin/ 

set -e

backup=$(podman image inspect --format="{{.Digest}}"
echo "current image digest: ${backup}"
podman pull
systemctl --user restart container-nitter.service
echo ""
echo "to revert:"
echo "podman image tag${backup} && systemctl --user restart container-nitter.service"

I also wrote a simple Android app, Nene, to be used as the default app to open twitter links on the Nitter instance of your choice on your phone.

#English #Linux #nitter #tech