Deployment guide

Fider 0.38.2

Overview

Fider is an open-source customer feedback portal. Customers or colleagues post ideas, vote on the ones they want and discuss them. You reply, tag, merge duplicates and move each idea through Open, Planned, Started, Completed or Declined, which also drives a public roadmap.

This guide covers launching and using the Fider 0.38.2 on Ubuntu 24.04 AMI from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud forums and social networks listing on AWS Marketplace. You pick it as the software version when you subscribe and launch.

Fider has notifications, webhooks, single sign-on through OAuth providers, a REST API and data export. It is one Go service that keeps everything in PostgreSQL.

What you get:

  • No first-visitor takeover. A fresh Fider normally shows a site setup page to whoever opens it first, and that person becomes the administrator. On this image, the site and its administrator are created on your instance's first boot, through Fider's own sign-up flow on a private loopback port, before anything is served. Site setup is then switched off (SIGNUP_DISABLED=true), so nobody who reaches the instance can create a site or claim the administrator role.
  • Per-instance secrets, no database password. The administrator's API key and Fider's signing secret (JWT_SECRET) are generated on your instance at first boot and written to /root/fider-credentials.txt (root only). There is no database password to leak or rotate. Fider signs in to PostgreSQL over the local Unix socket as its own operating system user (peer authentication), and no PostgreSQL role has a password. The image ships an empty database and no known credential.
  • Sign-in without a mail server. Fider has no passwords. It signs people in with a link or code sent by email. No mail server ships, so nobody can sign in or register by email until you configure one. You sign in as the administrator with a one-time link generated over SSH (Step 5).
  • HTTPS from the first boot. nginx serves Fider on port 443 with a certificate generated on your instance. Port 80 redirects to HTTPS, and requests for a host name the instance does not serve are dropped. Fider itself listens on 127.0.0.1:3000 only.
  • Fail closed. Fider and nginx start only after first boot has finished. If it cannot finish, nothing is served.
  • Hardened defaults. Fider, nginx, PostgreSQL and the first-boot service are blocked from the instance metadata service (Fider fetches avatars and calls webhooks and OAuth endpoints). The AMI requires IMDSv2. Fider is handed the configured host name and the real client address from the connection, never values a client sends. nginx refuses state-changing requests from a plain http:// origin, and the access log never records query strings.
  • Fully patched Ubuntu 24.04 LTS at build time, with unattended security upgrades switched on.

What is on the image: Fider 0.38.2 (the official build, fetched by checksum, no container runtime), nginx 1.24 and PostgreSQL 16 (from Ubuntu 24.04), cloud-init and the AWS Systems Manager agent.

Default user: ubuntu; Architecture: x86_64; Recommended instance type: m5.large.

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route you use for management).
  • A security group that allows TCP 22 (SSH) from your admin network, and TCP 443 (Fider) and TCP 80 (redirects to HTTPS) from the people who will use the portal. Never open 3000 or 5432, because Fider and PostgreSQL listen on the loopback address only.
  • An SMTP server or relay (for example Amazon SES) if people other than the administrator will sign in. Fider sends every sign-in link and code by email.
1

Launch the instance

In the AWS Marketplace listing, choose Continue to Subscribe, then Continue to Configuration. Pick Fider 0.38.2 on Ubuntu 24.04 as the software version and select your Region, then choose Launch through EC2. Choose m5.large, your key pair and a security group as described in Prerequisites.

To launch with the AWS CLI instead, replace the values in angle brackets:

aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
  --instance-type m5.large --key-name <your-key-pair> \
  --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=fider}]'

First boot finishes well under a minute after the instance is running.

2

Connect to your instance

Connect to Fider 0.38.2 on Ubuntu 24.04 over SSH as the ubuntu user:

ssh -i <your-key.pem> ubuntu@<public-ip>
3

Check the services

First boot sets the secrets and the certificate, and creates the site and its administrator. Then Fider and nginx start:

systemctl is-active nginx fider postgresql@16-main fider-firstboot
sudo test -f /var/lib/sac/data/fider-firstboot.done && echo FIRSTBOOT_DONE

All four units are active and the first-boot marker is present:

active active active active FIRSTBOOT_DONE

Only SSH and nginx listen on network ports. Fider and PostgreSQL listen on the loopback address:

sudo ss -lntp | awk 'NR>1 {print $4, $6}' | grep -v '127.0.0.5' | sed -E 's/,pid=[0-9]+,fd=[0-9]+//g' | sort
0.0.0.0:22 users:(("sshd"),("systemd")) 0.0.0.0:443 users:(("nginx"),("nginx"),("nginx")) 0.0.0.0:80 users:(("nginx"),("nginx"),("nginx")) 127.0.0.1:3000 users:(("fider")) 127.0.0.1:5432 users:(("postgres")) [::]:22 users:(("sshd"),("systemd")) [::]:443 users:(("nginx"),("nginx"),("nginx")) [::]:80 users:(("nginx"),("nginx"),("nginx"))
4

Your URL and credentials

The credentials file is readable by root only. This command shows everything except the two secret values, the API key and the signing secret:

sudo grep -v -E '^fider\.(admin\.apikey|jwt\.secret)=' /root/fider-credentials.txt
# Fider 0.38.2 - generated on first boot by fider-firstboot.service
# These values are unique to this instance; none was baked into the image. Keep this file secret. fider.url=https://<public-ip>/ fider.admin.email=admin@fider.invalid fider.db.name=fider fider.db.user=fider
# Fider has no passwords: people sign in with a link or code sent by email. No mail server is configured, so
# sign in as the administrator with a one-time link (valid 15 minutes, dead 5 minutes after first use):
#
sudo fider-signin-link
# Set your own address for the administrator (then configure SMTP in /etc/fider/fider.env):
#
sudo fider-set-admin-email you@example.com
# The API key above authenticates the administrator to the Fider API (Authorization: Bearer <key>).
# The certificate is self signed (minted on this instance): accept the browser warning once, or install your own.
# Port 80 redirects to https. Change the name Fider is served as:
sudo fider-set-hostname <your-dns-name>
# New sites cannot be created (SIGNUP_DISABLED=true). PostgreSQL listens on 127.0.0.1:5432 only, and there is
# no database password: no PostgreSQL role has one, and Fider signs in over the local socket /var/run/postgresql
# as the OS user fider (peer authentication).
# User guide: https://secureanycloud.com/stacks/fider-0-38-2/

The URL uses the instance's public IP address from the EC2 instance metadata. The certificate also names the public DNS name and the private IP address.

If you stop and start the instance without an Elastic IP, the boot service picks up the new address, issues a new certificate for it and updates Fider's base URL. To serve Fider under your own DNS name, see Step 8.

5

Sign in as the administrator

Generate a one-time sign-in link on the instance:

sudo fider-signin-link | sed -E 's/k=[A-Za-z0-9]+/k=<one-time-key>/'
One-time sign-in link for admin@fider.invalid (valid 15 minutes; dead 5 minutes after first use): https://<public-ip>/signin/verify?k=<one-time-key>

Run the command without the sed to see the real link, then open the link in your browser. Your browser warns once about the self-signed certificate. Accept the warning, or install your own certificate (Step 8). You are signed in as Administrator and land on the feedback board.

The link works for 15 minutes. Once it has been used, Fider accepts it again for 5 more minutes (a grace period it keeps for mail clients that preview links) and then refuses it. Run sudo fider-signin-link again whenever you need a new link.

Give the administrator your own email address, so sign-in links reach you once mail is configured:

sudo fider-set-admin-email you@example.com
6

Collect and manage feedback

People post an idea in Enter your suggestion here, vote on ideas and comment. Each idea has its own page with the voters, the vote count, the status and the discussion.

As administrator, you can Update Status (Open, Planned, Started, Completed, Declined, Duplicate) with a public response, Edit or Delete an idea, and tag it. Ideas marked Planned, Started or Completed appear on the Roadmap page.

Open the menu under your avatar and choose Site Settings for the administration pages: General (board title, welcome text), Privacy (make the board private so only invited people can see it), Users (roles: visitor, collaborator, administrator), Tags, Invitations, Authentication, Advanced, Webhooks and Export.

Authentication lets you add Facebook, Google, GitHub or any OAuth2 provider (your company identity provider, for example) so people sign in with an existing account. None is configured on this image. Fider 0.38.2 refuses to call OAuth or webhook endpoints on private network addresses unless you set ALLOW_PRIVATE_NETWORK_TARGETS=true.

The API key in the credentials file lets scripts read and write as the administrator. The commands below pass it in a header file, so it never appears on a command line:

H=$(sudo sed -n 's#^fider.url=https://\([^/]*\)/#\1#p' /root/fider-credentials.txt)
K=$(sudo sed -n 's/^fider.admin.apikey=//p' /root/fider-credentials.txt)
curl -sk --resolve "$H:443:127.0.0.1" -H @<(printf 'Authorization: Bearer %s\n' "$K") "https://$H/api/v1/users" | jq -c '{totalCount, users: [.users[] | {name, email, role}]}'
{"totalCount":1,"users":[{"name":"Administrator","email":"admin@fider.invalid","role":"administrator"}]}

Generate a new key at any time from your avatar menu under Settings > API Key > Regenerate API Key. The old key stops working.

7

Configure email

Until you configure mail, only the administrator can sign in (with fider-signin-link), and Fider sends no notifications. The image deliberately points Fider at a mail port where nothing listens, so no sign-in code can be delivered anywhere. To check, run:

sudo grep -E '^EMAIL_' /etc/fider/fider.env
EMAIL_NOREPLY=noreply@fider.invalid EMAIL_SMTP_HOST=127.0.0.1 EMAIL_SMTP_PORT=25

To let people sign in by email, set your SMTP server (Amazon SES, a corporate relay or any provider) and a sender address you own in /etc/fider/fider.env, then restart Fider. For example, for Amazon SES SMTP in your Region, run:

sudo nano /etc/fider/fider.env
# EMAIL_NOREPLY=feedback@<your-domain>
# EMAIL_SMTP_HOST=email-smtp.<region>.amazonaws.com
# EMAIL_SMTP_PORT=587
# EMAIL_SMTP_USERNAME=<smtp-username>
# EMAIL_SMTP_PASSWORD=<smtp-password>
sudo systemctl restart fider

The file is owned by root and readable by the fider group only. See Fider's email configuration documentation for the other settings (Mailgun, Amazon SES API, allow and block lists).

8

Your own DNS name and certificate

Point a DNS record at the instance (an Elastic IP keeps the address stable), then set the name that Fider is served as. The command creates a new self-signed certificate for the name. It also updates nginx, Fider's base URL (used in every link Fider builds, including the links in emails) and the URL in /root/fider-credentials.txt, and it keeps the name across reboots:

sudo fider-set-hostname <your-domain>

Next, install a certificate from a public certificate authority (for example one issued by Let's Encrypt for <your-domain>) over the generated pair, and reload nginx. Running fider-set-hostname again replaces it with a self-signed certificate:

sudo install -m 0644 <your-domain>.crt /etc/nginx/ssl/fider.crt
sudo install -m 0600 <your-domain>.key /etc/nginx/ssl/fider.key
sudo nginx -t && sudo systemctl reload nginx
9

Security checks

The shipped round-trip check does the following:

  • Reads the user list with this instance's API key over HTTPS.
  • Proves that a wrong key and common guesses are refused with Fider's "API Key is invalid" answer, and that an anonymous request is refused.
  • Proves that site setup is gone.
  • Checks PostgreSQL: no role has a password, the fider operating system user signs in as the fider database user over the local socket, any other operating system user is refused as fider, and a sign-in over TCP is refused.

Secrets are handed to curl and psql in root-only temporary files, never on a command line:

sudo bash /usr/local/sbin/fider-cred-roundtrip.sh
OK per-instance administrator API key lists the administrator over HTTPS (200); wrong/default keys refused (400 API Key is invalid); anonymous API read refused (401); site sign-up 404; PostgreSQL: no role has a password, fider signs in over the local socket (peer), other OS users and TCP logins refused

Site setup cannot be reached, so nobody can create a second site or take over the first:

H=$(sudo sed -n 's#^fider.url=https://\([^/]*\)/#\1#p' /root/fider-credentials.txt)
curl -sk --resolve "$H:443:127.0.0.1" -o /dev/null -w 'signup page: %{http_code}\n' "https://$H/signup"
curl -sk --resolve "$H:443:127.0.0.1" -H 'Content-Type: application/json' -d '{"tenantName":"x","name":"x","email":"x@example.com"}' -o /dev/null -w 'create a second site: %{http_code}\n' "https://$H/_api/tenants"
signup page: 404 create a second site: 404

Every service is denied the instance metadata service (and Azure's equivalent address), so a URL that Fider is asked to fetch can never reach your instance credentials:

for u in fider nginx postgresql@16-main fider-firstboot; do printf '%s: %s\n' "$u" "$(systemctl show -p IPAddressDeny --value $u.service | tr ' ' '\n' | sort | xargs)"; done
fider: 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128 nginx: 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128 postgresql@16-main: 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128 fider-firstboot: 168.63.129.16/32 169.254.169.254/32 fd00:ec2::254/128

The block holds inside the running service. This check joins a shell to Fider's control group and tries to reach the metadata service from there. The result 000 means the connection was refused:

CG=$(systemctl show -p ControlGroup --value fider.service)
sudo bash -c "echo \$\$ > /sys/fs/cgroup$CG/cgroup.procs; curl -s -m 5 -o /dev/null -w 'metadata from the fider service: %{http_code}\n' -X PUT -H 'X-aws-ec2-metadata-token-ttl-seconds: 60' http://169.254.169.254/latest/api/token; true"
metadata from the fider service: 000

Fider 0.38.2 refuses state-changing requests that a browser marks as cross-site, and cookie-authenticated writes that are not JSON. In front of it, nginx also refuses any state-changing request from a plain http:// or null origin.

The first request below comes from the plain http:// form of the instance's own host, and nginx refuses it. The second is marked cross-site, and Fider refuses it:

H=$(sudo sed -n 's#^fider.url=https://\([^/]*\)/#\1#p' /root/fider-credentials.txt)
curl -sk --resolve "$H:443:127.0.0.1" -H "Origin: http://$H" -H 'Content-Type: application/json' -d '{}' "https://$H/_api/signin"
curl -sk --resolve "$H:443:127.0.0.1" -H 'Sec-Fetch-Site: cross-site' -H 'Content-Type: application/json' -d '{}' -o /dev/null -w 'cross-site write: %{http_code}\n' "https://$H/_api/signin"
sac: state-changing request from a plain-http origin refused cross-site write: 403
10

Versions and the command line

dpkg-query -W -f='${Package} ${Version}\n' nginx postgresql-16 id fider cat /etc/sac/fider-release.txt
nginx 1.24.0-2ubuntu7.18 postgresql-16 16.15-0ubuntu0.24.04.1 uid=997(fider) gid=987(fider) groups=987(fider) sac: Fider 0.38.2 (AGPL-3.0-only) from getfider/fider, image manifest sha256:e106e55d56de3cd36a578c9d094eec71400b20b8610d02937707e1c6153847de (linux/amd64), commit e492af4a30db30c104df3dfb9e0f04e55757ba9e; LICENSE sha256 d11d906d7e29af95d28b051cd89a064bb25ae27a5c407c9994626c47e13bdc8f. Source: https://github.com/getfider/fider/tree/v0.38.2

Package versions move as Ubuntu publishes security updates. The files that matter:

  • /opt/fider/: the Fider program, its database migrations, templates and web assets (owned by root, read-only to the service).
  • /etc/fider/fider.env (owner root, group fider, mode 0640): listen address (127.0.0.1:3000), BASE_URL (set by fider-set-hostname), the PostgreSQL connection (the local socket, no password), JWT_SECRET, SIGNUP_DISABLED=true and mail settings. See the configuration reference for the full list.
  • /etc/nginx/sites-available/sac-fider and /etc/nginx/ssl/: the HTTPS front end and its certificate.
  • journalctl -u fider shows Fider's log (warnings and errors only). Restart Fider with sudo systemctl restart fider. Fider applies its database migrations each time it starts.
11

Changing secrets

There is no database password to change. Fider's DATABASE_URL points at PostgreSQL's local socket. PostgreSQL lets the fider operating system user sign in as the fider database user there (peer authentication), and no PostgreSQL role has a password, so nothing can sign in over TCP:

printf 'SELECT rolname, rolpassword IS NULL AS no_password FROM pg_authid WHERE rolcanlogin ORDER BY 1;\n' | sudo -u postgres psql -X -tA
fider|t postgres|t

Open a SQL shell on Fider's database as the application user with sudo -u fider psql -d fider. If you move the database to another server (for example Amazon RDS), give the role a password there and put the connection string in DATABASE_URL.

Changing JWT_SECRET in the same file and restarting Fider signs everybody out.

12

Backup and maintenance

All of Fider's state (ideas, votes, comments, users, settings and uploaded images) is in the fider PostgreSQL database. Back it up regularly, and copy the dump off the instance (for example to Amazon S3):

sudo -u postgres pg_dump -Fc fider > <backup-dir>/fider-$(date +%F).dump

Also keep a copy of /etc/fider/fider.env. Administrators can download a full backup from Site Settings > Export as well.

Ubuntu security updates install automatically. To upgrade Fider, take a backup, then replace /opt/fider with the files of a newer Fider release (its official image's /app directory) and restart the service. Migrations run on start.

13

Security recommendations

  • Serve Fider under your own DNS name with a publicly trusted certificate (Step 8), and limit the security group to port 22 from your admin network plus ports 80 and 443.
  • Set your own address on the administrator account and configure mail (Steps 5 and 7) before you invite people.
  • Make the board private under Site Settings > Privacy if only invited people should see it, and give staff the collaborator role rather than administrator.
  • Take regular database backups and test a restore.

Support and licensing

Fider is open-source software released under the GNU Affero General Public License version 3 (AGPL-3.0). The license text is installed at /usr/share/doc/fider/LICENSE, and the source of this exact version is at github.com/getfider/fider. If you modify Fider and let people use it over a network, the AGPL requires you to offer them your modified source.

SecureAnyCloud provides 24/7 technical support for this image by email and live chat: sales@secureanycloud.com. For Fider itself, see the documentation.

Fider is a trademark of its respective owner. SecureAnyCloud is not affiliated with or endorsed by the Fider project. All other product names are trademarks of their respective owners.

Deploy on AWS

Launch Fider 0.38.2 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS