Applications AWS

yarr Self-Hosted RSS Feed Reader on AWS User Guide

| Product: yarr

Overview

This image runs yarr (yet another rss reader), a fast, lightweight open source self-hosted RSS and Atom feed reader and aggregator. yarr is a single Go binary with an embedded web interface and an embedded SQLite database, so it starts instantly and keeps your reading history entirely on infrastructure you control. Subscribe to any website's feed, organise subscriptions into folders, and read articles in a clean three-pane view with unread tracking, full-text search, a built-in readability mode, and OPML import and export.

The cloudimg image is secure by default. yarr's web interface has no server-side authentication of its own, so this image binds yarr only to the loopback interface and fronts it with nginx on port 80 enforcing an HTTP login. The password is a unique value generated on first boot for each instance and written to a root-only file. No credential is baked into the image, and no two deployments share one.

What is included:

  • yarr installed as the official prebuilt Linux server binary at /usr/local/bin/yarr
  • A dedicated non-root yarr service (yarr.service) bound to 127.0.0.1:7070
  • The SQLite feed database on its own dedicated, independently resizable data volume at /var/lib/yarr
  • nginx on port 80 reverse proxying the reader with an HTTP login, plus a loopback-only /healthz endpoint for health probes
  • A one-shot yarr-firstboot.service that generates a per-instance password on first boot and writes it to /root/yarr-info.txt (mode 0600)
  • Self-contained demo feeds so the reader is populated the moment you sign in
  • A fully patched Ubuntu 24.04 LTS base
  • 24/7 cloudimg support

yarr is published by its author under the MIT licence. This image is packaged by cloudimg and is not affiliated with or endorsed by the yarr project.

Prerequisites

An AWS account, an EC2 key pair in the target region, and a VPC with a public subnet. m5.large (2 vCPU / 8 GiB RAM) is the recommended instance type; yarr is lightweight and runs comfortably on smaller types too. Security group inbound: allow 22/tcp from your management network for SSH and 80/tcp for the reader. yarr serves plain HTTP on port 80; for production or shared access, terminate TLS in front of it with your own domain using nginx or an Application Load Balancer (see Step 8).

Step 1 - Launch the AMI

Subscribe to the listing in AWS Marketplace, choose Continue to Launch, and launch through the EC2 console or the AWS CLI. Select the m5.large instance type, your key pair, and a security group that opens ports 22 and 80.

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type m5.large \
  --key-name <your-key-pair> \
  --security-group-ids <security-group-id> \
  --subnet-id <subnet-id> \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=yarr}]'

Step 2 - Connect to your instance

Connect over SSH as the default login user for the OS variant you launched. This listing may ship more than one OS variant; use the matching login user below.

OS variant SSH login user Connect
Ubuntu 24.04 LTS ubuntu ssh ubuntu@<instance-public-ip>

Step 3 - Confirm the services are running

yarr runs as yarr.service on the loopback interface, fronted by nginx on port 80. A one-shot yarr-firstboot.service runs once on first boot to generate the per-instance password. Confirm all three units are active, and that nginx is listening on port 80 while yarr stays private on 127.0.0.1:7070:

systemctl is-active yarr nginx yarr-firstboot
sudo ss -tlnp | grep -E ":80 |:7070 "

Expected output:

active
active
active
LISTEN 0 511      0.0.0.0:80   0.0.0.0:* users:(("nginx",...))
LISTEN 0 4096   127.0.0.1:7070 0.0.0.0:* users:(("yarr",...))
LISTEN 0 511         [::]:80      [::]:* users:(("nginx",...))

nginx is reachable on port 80, and yarr is bound to 127.0.0.1 only, so it can never be reached directly - the login enforced by nginx cannot be bypassed.

Step 4 - Confirm the feed database is on its own data volume

The SQLite feed database lives on a dedicated EBS data volume mounted at /var/lib/yarr, separate from the operating system disk, so you can resize or snapshot it independently. Confirm it is a mount point of its own:

findmnt /var/lib/yarr
sudo ls -l /var/lib/yarr/storage.db

Step 5 - Read your unique credential

Each instance generates its own random administrator password on first boot and writes it to a root-only file. Read your username, URL and password:

sudo cat /root/yarr-info.txt

The username is admin. Keep this file secret - it is the only place the generated password is stored.

Step 6 - Confirm the secure-by-default posture from the command line

Before signing in, prove that the reader is protected. The following reads your per-instance password from the root-only file, then shows that an unauthenticated request and a wrong password are both rejected with 401, while the correct credential returns 200:

PW=$(sudo grep '^YARR_ADMIN_PASSWORD=' /root/yarr-info.txt | cut -d= -f2-)
echo "unauth : $(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/api/status)"
echo "wrongpw: $(curl -s -o /dev/null -w '%{http_code}' -u admin:wrong-password http://127.0.0.1/api/status)"
echo "authed : $(curl -s -o /dev/null -w '%{http_code}' -u "admin:$PW" http://127.0.0.1/api/status)"

Expected output:

unauth : 401
wrongpw: 401
authed : 200

The reader arrives pre-populated with self-contained demo feeds so the interface is not empty on first sign-in. Confirm the demo articles are present:

PW=$(sudo grep '^YARR_ADMIN_PASSWORD=' /root/yarr-info.txt | cut -d= -f2-)
curl -s -u "admin:$PW" http://127.0.0.1/api/items | \
  python3 -c 'import json,sys; print("articles in reader:", len(json.load(sys.stdin)["list"]))'

Step 7 - Sign in and read

Open http://<instance-public-ip>/ in a browser. When prompted, sign in with the username admin and the password from /root/yarr-info.txt. The three-pane reader loads with the demo feeds already populated: folders and feeds on the left, the article list in the middle, and the reading pane on the right.

The yarr three-pane reader: folders and feeds in the sidebar, the article list in the middle, and articles ready to read

Click any article to open it in the reading pane. Use the readability view to strip clutter, mark items read or starred, and switch between light, sepia and dark themes.

An article open in the yarr reading pane, with the feed sidebar and article list alongside

Step 8 - Add and organise your own feeds

Open the settings menu (the ... button, top-left) and choose New Feed, then paste any website or feed URL - yarr discovers the feed automatically. Drag feeds into folders to organise them. The same menu offers Import and Export for moving your subscriptions in and out as OPML, a light/sepia/dark Theme switch, and an Auto Refresh interval.

The yarr settings menu with New Feed, Refresh Feeds, theme options and OPML Import and Export

You can also add a feed from the command line against the API. The image ships a small self-contained self-test feed served locally, so this works offline and proves live feed fetching on your instance:

PW=$(sudo grep '^YARR_ADMIN_PASSWORD=' /root/yarr-info.txt | cut -d= -f2-)
ADD=$(curl -s -u "admin:$PW" -H 'Content-Type: application/json' \
  --data '{"url":"http://127.0.0.1/demo/selftest.xml"}' http://127.0.0.1/api/feeds)
FID=$(echo "$ADD" | python3 -c 'import json,sys; print(json.load(sys.stdin)["feed"]["id"])')
echo "add status: $(echo "$ADD" | python3 -c 'import json,sys; print(json.load(sys.stdin)["status"])')"
sleep 2
curl -s -u "admin:$PW" "http://127.0.0.1/api/items?feed_id=$FID" | \
  python3 -c 'import json,sys; print("fetched items:", len(json.load(sys.stdin)["list"]))'
curl -s -o /dev/null -u "admin:$PW" -X DELETE "http://127.0.0.1/api/feeds/$FID"
echo "self-test feed removed"

Expected output:

add status: success
fetched items: 1
self-test feed removed

Step 9 - Change the login password

The login is enforced by nginx using a per-instance htpasswd file. To set your own password, overwrite the htpasswd entry for admin and reload nginx. You will be prompted for the new password twice:

sudo sh -c 'printf "admin:%s\n" "$(openssl passwd -apr1)" > /etc/nginx/yarr.htpasswd'
sudo chown root:www-data /etc/nginx/yarr.htpasswd
sudo chmod 640 /etc/nginx/yarr.htpasswd
sudo systemctl reload nginx

Update /root/yarr-info.txt if you want to keep a record.

Step 10 - Terminate TLS with your own domain (recommended)

yarr serves plain HTTP on port 80. For production, put your own domain and certificate in front of nginx. Point a DNS record at the instance, then either add a TLS server block to nginx with a certificate from your CA (for example Let's Encrypt via certbot), or place the instance behind an Application Load Balancer with an ACM certificate and forward to port 80. Keep the loopback bind and the HTTP login in place behind your TLS terminator.

Troubleshooting

  • Browser keeps asking for the password: confirm you are using the value from /root/yarr-info.txt (username admin). Re-read it with sudo cat /root/yarr-info.txt.
  • 502/500 from nginx: check yarr is up with systemctl status yarr and curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1/healthz (expect 200). If the htpasswd file is missing, nginx returns an error on the login-protected path by design - re-run Step 9 to recreate it.
  • Feeds not updating: yarr fetches on a schedule; set an interval under settings Auto Refresh, or use Refresh Feeds to fetch immediately. Outbound HTTPS must be allowed from the instance to reach external feeds.
  • Resizing storage: grow the /var/lib/yarr EBS volume in the console, then run sudo growpart and sudo resize2fs on its device.

Support

cloudimg provides 24/7 technical support for this product by email and live chat at support@cloudimg.co.uk. We help with deployment, TLS termination with your own domain and certificate, changing the login credential, OPML import and export, and connecting Fever-compatible mobile apps. For refunds, contact support@cloudimg.co.uk with your AWS account ID and subscription details.