Applications AWS

CommaFeed on AWS User Guide

| Product: CommaFeed on AWS

Overview

CommaFeed is a fast, self-hosted RSS and Atom feed reader with a modern React web interface - a private, ad-free successor to Google Reader that keeps your subscriptions and reading history on infrastructure you control. The cloudimg image ships CommaFeed as the project's own recommended GraalVM native executable (no Java runtime dependency), behind nginx as the sole public listener, with PostgreSQL bound to loopback as the datastore, and generates a unique administrator login on the first boot of every instance. Backed by 24/7 cloudimg support.

What is included:

  • CommaFeed 7.2.0 as the official GraalVM native executable at /opt/commafeed/commafeed, run as the dedicated non-root commafeed system user
  • nginx on :80 as the only public listener, reverse-proxying to the application on 127.0.0.1:8082 (with WebSocket support for the live feed tree) and serving a static /health endpoint
  • PostgreSQL as the datastore for feeds, entries, tags and read state, bound to 127.0.0.1 only, on a dedicated EBS data volume mounted at /var/lib/commafeed
  • Per-instance administrator, session-encryption and PostgreSQL passwords generated at first boot, in a root-only file - the image ships with an empty database and no working credentials
  • New-user self-registration disabled by default, so the reader is not left open to the public
  • commafeed.service, nginx.service and postgresql.service as systemd units, enabled and active
  • 24/7 cloudimg support

Prerequisites

Before you deploy this image you need:

  • An Amazon Web Services account where you can launch EC2 instances and subscribe to AWS Marketplace products
  • An EC2 key pair in the target Region for SSH access
  • A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network and inbound ports 80 (and 443 once you enable HTTPS) from the networks you will read from
  • The AWS CLI version 2 installed locally if you plan to deploy from the command line
  • Outbound internet access from the instance for package updates and for fetching the feeds you subscribe to

m5.large (2 vCPU / 8 GiB RAM) is the recommended instance type - CommaFeed's native executable is lightweight, so a smaller type also works for low-traffic personal use.

Connecting to your instance

Connect over SSH on port 22 as the default login user for your OS variant:

OS variant SSH login user
Ubuntu 24.04 ubuntu

The examples below use ubuntu; substitute your variant's user from the table.

Step 1: Launch the Instance from the AWS Marketplace

Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for CommaFeed. Select the cloudimg listing, choose Select, then Continue on the subscription summary.

Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that allows inbound port 22 from your management network and inbound ports 80 and 443 from the networks you will read from. Leave the root volume at the default size or larger.

Select Launch instance. First boot initialisation - database setup, secret rotation and administrator creation - completes within about a minute of the instance state becoming Running and the status checks passing.

Step 2: Launch the Instance from the AWS CLI

The following block launches an instance from the cloudimg CommaFeed Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22, 80 and 443 as described above.

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type m5.large \
  --key-name <key-name> \
  --subnet-id <subnet-id> \
  --security-group-ids <security-group-id> \
  --associate-public-ip-address \
  --metadata-options 'HttpTokens=required' \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=commafeed}]'

Step 3: Connect to your instance

ssh -i /path/to/<key-name>.pem ubuntu@<instance-public-ip>

Step 4: Confirm the services are running

systemctl is-active commafeed.service nginx.service postgresql.service
curl -s -o /dev/null -w 'health: HTTP %{http_code}\n' http://127.0.0.1/health
curl -s -o /dev/null -w 'front door: HTTP %{http_code}\n' http://127.0.0.1/

All three services report active, the static health endpoint returns HTTP 200, and the reader front door returns HTTP 200, which confirms nginx, CommaFeed and PostgreSQL are serving:

active
active
active
health: HTTP 200
front door: HTTP 200

Step 5: Retrieve your administrator login

The administrator account, the session-encryption key and the PostgreSQL password are generated uniquely on the first boot of your instance and written to a root-only file. Read it with:

sudo cat /root/commafeed-credentials.txt

The COMMAFEED_ADMIN_USER (always admin) and COMMAFEED_ADMIN_PASSWORD values are your sign-in for the web interface. You can confirm the file is present and root-only without printing the secret:

sudo test -f /root/commafeed-credentials.txt && echo "credentials file present, mode 0$(sudo stat -c '%a' /root/commafeed-credentials.txt)"
sudo grep -c '^COMMAFEED_ADMIN' /root/commafeed-credentials.txt
credentials file present, mode 0600
2

Step 6: First sign-in

Open a web browser and navigate to http://<instance-public-ip>/. CommaFeed redirects to its sign-in page. Enter admin as the user name and the COMMAFEED_ADMIN_PASSWORD from the credentials file, then select Log in.

CommaFeed sign-in page

The CommaFeed sign-in, served on first boot with a per-instance administrator login.

Step 7: Subscribe to your first feed

Select the + (Subscribe) button in the top bar. On the Subscribe tab, paste a feed URL (or a website URL - CommaFeed will try to discover the feed in the page) into Feed URL and select Next, then confirm to add it. You can also create categories to organize feeds, or bulk-import an existing subscription list on the OPML tab.

CommaFeed subscribe wizard

The subscribe wizard - analyze a feed URL, add it to a category, or import an OPML file.

Step 8: Read and organize your feeds

Your subscriptions appear in the left-hand tree, grouped by category, each with an unread count. Select All, a category, or an individual feed to read its entries in the main pane. The toolbar gives you refresh, mark-all-as-read, unread/all filtering, sort order and full-text search.

CommaFeed reader

The CommaFeed reader - subscriptions in the left tree, entries in the main pane.

Step 9: Read an entry

Select an entry to expand it in place and read the content, then star it, tag it, share it, or open the original article. Entries are marked read as you go, and keyboard shortcuts let you move through your unread items quickly.

CommaFeed entry view

An expanded entry with the per-entry action toolbar - star, tag, share and open.

Step 10: Prove the administrator login through the REST API

CommaFeed is API-driven: the /rest API is protected by HTTP Basic authentication. From an SSH session on the instance you can prove the round trip with the per-instance administrator password - a correct password returns 200, and a wrong password is refused with 401:

PW=$(sudo grep '^COMMAFEED_ADMIN_PASSWORD=' /root/commafeed-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -w 'good password: HTTP %{http_code}\n' -u "admin:$PW" http://127.0.0.1:8082/rest/user/settings
curl -s -o /dev/null -w 'wrong password: HTTP %{http_code}\n' -u 'admin:wrong-password-x' http://127.0.0.1:8082/rest/user/settings
good password: HTTP 200
wrong password: HTTP 401

The API accepts the generated administrator credentials and refuses an incorrect one, confirming the reader requires authentication.

Step 11: Confirm the runtime and security posture

The native executable, the dedicated non-root service user, and the listening ports - nginx on all interfaces on :80, CommaFeed and PostgreSQL bound to loopback only:

file /opt/commafeed/commafeed | cut -d: -f2-
id commafeed
sudo ss -tlnp | grep -E ':80 |:8082 |:5432 '
 ELF 64-bit LSB executable, x86-64, ... dynamically linked
uid=... (commafeed) gid=... (commafeed) groups=...(commafeed)
LISTEN 0  4096   0.0.0.0:80     0.0.0.0:*
LISTEN 0  4096   127.0.0.1:8082 0.0.0.0:*
LISTEN 0  200    127.0.0.1:5432 0.0.0.0:*

nginx listens on all interfaces on port 80, while both the CommaFeed application (8082) and PostgreSQL (5432) are bound to loopback only and are never exposed to the network.

Enabling registration (optional)

New-user self-registration is disabled by default so your reader is not open to the public. If you want to let other people create their own accounts on this instance, enable registrations and restart CommaFeed:

sudo sed -i 's|^COMMAFEED_USERS_ALLOW_REGISTRATIONS=.*|COMMAFEED_USERS_ALLOW_REGISTRATIONS=true|' /etc/commafeed/commafeed.env
sudo systemctl restart commafeed

Leave it disabled if CommaFeed is only for you or your team; add users from the administrator account instead.

Enabling HTTPS

For any deployment reachable over the internet, serve CommaFeed over HTTPS so logins cannot be intercepted. The image already fronts CommaFeed with nginx, so you add a TLS certificate to the existing nginx site. The following installs certbot and obtains a certificate, and assumes a DNS record pointing your fully qualified domain name at the instance's public IP, and port 443 open in the security group:

sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d reader.your-domain.example \
  --non-interactive --agree-tos -m you@your-domain.example --redirect

certbot edits the nginx site in place to serve HTTPS on 443 and redirect 80, and renews automatically. No change to the CommaFeed service is required because nginx continues to proxy to it on loopback.

Backup and maintenance

CommaFeed keeps all of its state - feeds, entries, tags, read state and users - in PostgreSQL, on the dedicated /var/lib/commafeed EBS volume. Back it up regularly:

sudo -u postgres pg_dump commafeed > <backup-dir>/commafeed-db-$(date +%F).sql

Ship the dump to Amazon S3 or another object store, and consider EBS snapshots of the data volume. You can also export your subscriptions from the web interface as an OPML file. Ubuntu's unattended-upgrades is enabled by default; keep the OS patched with sudo apt update && sudo apt upgrade. To upgrade CommaFeed, replace the native executable at /opt/commafeed/commafeed with a newer release and restart the service - database migrations run automatically on start. See https://github.com/Athou/commafeed.

Support

This image is backed by 24/7 cloudimg support. Contact us by email and chat for help with deployment, subscribing and organizing feeds, OPML import and export, integrations, upgrades, TLS termination and database administration. Guaranteed response within 24 hours, one hour average for critical issues. Contact support@cloudimg.co.uk.

For general CommaFeed questions consult the project at https://github.com/Athou/commafeed. CommaFeed is a trademark of its respective owner. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.