OS Apps: Fider and AudioBookshelf

Published: Jun 3, 2025 by Isaac Johnson

Today I want to dig into two Open-Source apps that have been on my list: Fider and AudioBookshelf.

Fider is a Feedback + Voting site. It sort of reminds me of Digg from back in the day. The idea is people can drop suggestions and then also vote. Everyone is gated by an email to limit spam. We’ll try setting this up on Docker as well as Kubernetes. I’ll even cover OAuth setup with Google.

Audioshelf is a self-hosted Audiobook and Podcast server. It is not for music, so we can set that aside for now. We’ll set this up in Docker (for good reasons) and sort out Books and Podcasts (and music, in a way).

Fider

Back in Jan, I saw this Marius post on Fider which is a simple containerized feedback system.

In the Docker install steps we can see a simple Docker compose file

services:
  db:
    restart: always
    image: postgres:17
    volumes:
      - /var/fider/pg_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: fider
      POSTGRES_PASSWORD: s0m3g00dp4ssw0rd
  app:
    restart: always
    image: getfider/fider:stable
    ports:
      - "80:3000"
    environment:
      # Public Host Name
      BASE_URL: http://localhost

      # Connection string to the PostgreSQL database
      DATABASE_URL: postgres://fider:s0m3g00dp4ssw0rd@db:5432/fider?sslmode=disable

      # Generate a secure secret, for example using https://jwtsecret.com
      JWT_SECRET: VERY_STRONG_SECRET_SHOULD_BE_USED_HERE

      # From which account e-mails will be sent
      EMAIL_NOREPLY: noreply@yourdomain.com

      ###
      # EMAIL
      # Either EMAIL_MAILGUN_* or EMAIL_SMTP_*, EMAIL_AWSSES_* or EMAIL_RESEND_* is required
      ###

      # EMAIL_MAILGUN_API: key-yourkeygoeshere
      # EMAIL_MAILGUN_DOMAIN: yourdomain.com
      # EMAIL_MAILGUN_REGION: US

      # EMAIL_SMTP_HOST: smtp.yourdomain.com
      # EMAIL_SMTP_PORT: 587
      # EMAIL_SMTP_USERNAME: user@yourdomain.com
      # EMAIL_SMTP_PASSWORD: s0m3p4ssw0rd
      # EMAIL_SMTP_ENABLE_STARTTLS: 'true'

      # EMAIL_AWSSES_REGION: us-east-1
      # EMAIL_AWSSES_ACCESS_KEY_ID: youraccesskeygoeshere
      # EMAIL_AWSSES_SECRET_ACCESS_KEY: yoursecretkeygoeshere

      # EMAIL_RESEND_API: resend-api-key

Here I’ll use a Resend sender

builder@LuiGi:~/Workspaces/fiderApp$ cat ./docker-compose.yml
services:
  db:
    restart: always
    image: postgres:17
    volumes:
      - /home/builder/Workspaces/fiderApp/pg_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: fider
      POSTGRES_PASSWORD: s0m3g00dp4ssw0rd
  app:
    restart: always
    image: getfider/fider:stable
    ports:
      - "8844:3000"
    environment:
      # Public Host Name
      BASE_URL: http://localhost:8844

      # Connection string to the PostgreSQL database
      DATABASE_URL: postgres://fider:s0m3g00dp4ssw0rd@db:5432/fider?sslmode=disable

      # Generate a secure secret, for example using https://jwtsecret.com
      JWT_SECRET: VERY_STRONG_SECRET_SHOULD_BE_USED_HERE

      # From which account e-mails will be sent
      EMAIL_NOREPLY: isaac@steeped.space

      EMAIL_RESEND_API: re_xxxxxxxxxxxxxxxxxxxxxxxx

I see it launch but the app keeps crashing looking for an SMTP variable

builder@LuiGi:~/Workspaces/fiderApp$ docker compose up
[+] Running 28/28
 ✔ app Pulled                                                                                                     18.1s
   ✔ 6e909acdb790 Pull complete                                                                                   12.2s
   ✔ d5b5f7131ee0 Pull complete                                                                                   12.5s
   ✔ de3223de4c07 Pull complete                                                                                   12.6s
   ✔ 9d21d4a801d9 Pull complete                                                                                   12.7s
   ✔ b7fe34b6c18a Pull complete                                                                                   12.8s
   ✔ b644702da688 Pull complete                                                                                   12.8s
   ✔ 4da2d0a291ce Pull complete                                                                                   12.9s
   ✔ 1d4cef4462a8 Pull complete                                                                                   15.6s
   ✔ 87c2e062905e Pull complete                                                                                   15.7s
   ✔ 800fb5df1c38 Pull complete                                                                                   15.8s
   ✔ e9f9de74aa60 Pull complete                                                                                   15.8s
   ✔ e49a90a7cdb7 Pull complete                                                                                   15.9s
 ✔ db Pulled                                                                                                     104.5s
   ✔ 61320b01ae5e Pull complete                                                                                   19.8s
   ✔ 3db9b37be7c3 Pull complete                                                                                   19.9s
   ✔ e9a82aed48d7 Pull complete                                                                                   20.1s
   ✔ 7c852ebdd63e Pull complete                                                                                   20.2s
   ✔ 28708ff4e046 Pull complete                                                                                   21.7s
   ✔ 6ce13d85dabe Pull complete                                                                                   21.8s
   ✔ bd1fa28722bb Pull complete                                                                                   21.9s
   ✔ 410cd7ec9a40 Pull complete                                                                                   21.9s
   ✔ 475b0e32b814 Pull complete                                                                                  101.8s
   ✔ e7aba16d6a5e Pull complete                                                                                  101.9s
   ✔ 89ba8b615fa9 Pull complete                                                                                  101.9s
   ✔ 82697a7976df Pull complete                                                                                  102.0s
   ✔ 7e11eb1421f3 Pull complete                                                                                  102.1s
   ✔ 2bb588ce4e67 Pull complete                                                                                  102.1s
[+] Running 3/3
 ✔ Network fiderapp_default  Created                                                                               0.1s
 ✔ Container fiderapp-db-1   Created                                                                               0.3s
 ✔ Container fiderapp-app-1  Created                                                                               0.3s
Attaching to app-1, db-1
db-1   | The files belonging to this database system will be owned by user "postgres".
db-1   | This user must also own the server process.
db-1   |
db-1   | The database cluster will be initialized with locale "en_US.utf8".
db-1   | The default database encoding has accordingly been set to "UTF8".
db-1   | The default text search configuration will be set to "english".
db-1   |
db-1   | Data page checksums are disabled.
db-1   |
db-1   | fixing permissions on existing directory /var/lib/postgresql/data ... ok
db-1   | creating subdirectories ... ok
db-1   | selecting dynamic shared memory implementation ... posix
db-1   | selecting default "max_connections" ... 100
app-1  | panic: could not find environment variable named 'EMAIL_SMTP_HOST'
app-1  |
app-1  | goroutine 1 [running]:
app-1  | github.com/getfider/fider/app/pkg/env.mustBeSet({0x1c1f3b5, 0xf})
db-1   | selecting default "shared_buffers" ... 128MB
app-1  |        /server/app/pkg/env/env.go:205 +0x85
app-1  | github.com/getfider/fider/app/pkg/env.Reload()
app-1  |        /server/app/pkg/env/env.go:190 +0x246
app-1  | github.com/getfider/fider/app/pkg/env.init.0()
app-1  |        /server/app/pkg/env/env.go:146 +0xf
db-1   | selecting default time zone ... Etc/UTC
db-1   | creating configuration files ... ok
db-1   | running bootstrap script ... ok
db-1   | performing post-bootstrap initialization ... ok
app-1 exited with code 0
db-1   | syncing data to disk ... ok
db-1   |
db-1   |
db-1   | Success. You can now start the database server using:
db-1   |
db-1   |     pg_ctl -D /var/lib/postgresql/data -l logfile start
db-1   |
db-1   | initdb: warning: enabling "trust" authentication for local connections
db-1   | initdb: hint: You can change this by editing pg_hba.conf or using the option -A, or --auth-local and --auth-host, the next time you run initdb.
db-1   | waiting for server to start....2025-05-31 13:26:01.395 UTC [50] LOG:  starting PostgreSQL 17.5 (Debian 17.5-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
db-1   | 2025-05-31 13:26:01.400 UTC [50] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db-1   | 2025-05-31 13:26:01.419 UTC [53] LOG:  database system was shut down at 2025-05-31 13:25:58 UTC
db-1   | 2025-05-31 13:26:01.427 UTC [50] LOG:  database system is ready to accept connections
db-1   |  done
db-1   | server started
db-1   | CREATE DATABASE
db-1   |
db-1   |
db-1   | /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
db-1   |
db-1   | waiting for server to shut down....2025-05-31 13:26:01.586 UTC [50] LOG:  received fast shutdown request
db-1   | 2025-05-31 13:26:01.596 UTC [50] LOG:  aborting any active transactions
db-1   | 2025-05-31 13:26:01.598 UTC [50] LOG:  background worker "logical replication launcher" (PID 56) exited with exit code 1
db-1   | 2025-05-31 13:26:01.600 UTC [51] LOG:  shutting down
db-1   | 2025-05-31 13:26:01.606 UTC [51] LOG:  checkpoint starting: shutdown immediate
app-1  | panic: could not find environment variable named 'EMAIL_SMTP_HOST'
app-1  |
app-1  | goroutine 1 [running]:
app-1  | github.com/getfider/fider/app/pkg/env.mustBeSet({0x1c1f3b5, 0xf})
app-1  |        /server/app/pkg/env/env.go:205 +0x85
app-1  | github.com/getfider/fider/app/pkg/env.Reload()
app-1  |        /server/app/pkg/env/env.go:190 +0x246
app-1  | github.com/getfider/fider/app/pkg/env.init.0()
app-1  |        /server/app/pkg/env/env.go:146 +0xf
app-1  | panic: could not find environment variable named 'EMAIL_SMTP_HOST'
app-1  |
app-1  | goroutine 1 [running]:
app-1  | github.com/getfider/fider/app/pkg/env.mustBeSet({0x1c1f3b5, 0xf})
app-1 exited with code 2
app-1  |        /server/app/pkg/env/env.go:205 +0x85
app-1  | github.com/getfider/fider/app/pkg/env.Reload()
app-1  |        /server/app/pkg/env/env.go:190 +0x246
app-1  | github.com/getfider/fider/app/pkg/env.init.0()
app-1  |        /server/app/pkg/env/env.go:146 +0xf
app-1  | panic: could not find environment variable named 'EMAIL_SMTP_HOST'
app-1  |
app-1  | goroutine 1 [running]:
app-1  | github.com/getfider/fider/app/pkg/env.mustBeSet({0x1c1f3b5, 0xf})
app-1  |        /server/app/pkg/env/env.go:205 +0x85
app-1  | github.com/getfider/fider/app/pkg/env.Reload()
app-1  |        /server/app/pkg/env/env.go:190 +0x246
app-1  | github.com/getfider/fider/app/pkg/env.init.0()
app-1  |        /server/app/pkg/env/env.go:146 +0xf
db-1   | 2025-05-31 13:26:02.143 UTC [51] LOG:  checkpoint complete: wrote 921 buffers (5.6%); 0 WAL file(s) added, 0 removed, 0 recycled; write=0.027 s, sync=0.494 s, total=0.544 s; sync files=301, longest=0.010 s, average=0.002 s; distance=4238 kB, estimate=4238 kB; lsn=0/1908970, redo lsn=0/1908970
db-1   | 2025-05-31 13:26:02.148 UTC [50] LOG:  database system is shut down
db-1   |  done
db-1   | server stopped
db-1   |
db-1   | PostgreSQL init process complete; ready for start up.
db-1   |
db-1   | 2025-05-31 13:26:02.223 UTC [1] LOG:  starting PostgreSQL 17.5 (Debian 17.5-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
db-1   | 2025-05-31 13:26:02.265 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
db-1   | 2025-05-31 13:26:02.265 UTC [1] LOG:  listening on IPv6 address "::", port 5432
db-1   | 2025-05-31 13:26:02.282 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db-1   | 2025-05-31 13:26:02.301 UTC [66] LOG:  database system was shut down at 2025-05-31 13:26:02 UTC
db-1   | 2025-05-31 13:26:02.312 UTC [1] LOG:  database system is ready to accept connections
app-1 exited with code 2
app-1  | panic: could not find environment variable named 'EMAIL_SMTP_HOST'
app-1  |
app-1  | goroutine 1 [running]:
app-1  | github.com/getfider/fider/app/pkg/env.mustBeSet({0x1c1f3b5, 0xf})

I filled out the SMTP settings for resend form and it worked.


This time it worked to launch

builder@LuiGi:~/Workspaces/fiderApp$ docker compose up
[+] Running 2/2
 ✔ Container fiderapp-app-1  Recreated                                                                                                                                                           0.1s
 ✔ Container fiderapp-db-1   Created                                                                                                                                                             0.0s
Attaching to app-1, db-1
db-1   |
db-1   | PostgreSQL Database directory appears to contain a database; Skipping initialization
db-1   |
db-1   | 2025-05-31 13:36:13.482 UTC [1] LOG:  starting PostgreSQL 17.5 (Debian 17.5-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
db-1   | 2025-05-31 13:36:13.482 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
db-1   | 2025-05-31 13:36:13.482 UTC [1] LOG:  listening on IPv6 address "::", port 5432
app-1  | INFO [2025-05-31T13:36:13Z] [MIGRATE] Running migrations...
db-1   | 2025-05-31 13:36:13.494 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
app-1  | INFO [2025-05-31T13:36:13Z] [MIGRATE] Found total of 74 migration files.
db-1   | 2025-05-31 13:36:13.505 UTC [29] LOG:  database system was shut down at 2025-05-31 13:34:22 UTC
db-1   | 2025-05-31 13:36:13.506 UTC [30] FATAL:  the database system is starting up
app-1  | ERROR [2025-05-31T13:36:13Z] [MIGRATE] Error Trace:
db-1   | 2025-05-31 13:36:13.506 UTC [31] FATAL:  the database system is starting up
app-1  | - failed to get last migration record (app/pkg/dbx/migrate.go:57)
db-1   | 2025-05-31 13:36:13.507 UTC [32] FATAL:  the database system is starting up
app-1  | - pq: the database system is starting up
db-1   | 2025-05-31 13:36:13.519 UTC [1] LOG:  database system is ready to accept connections
app-1 exited with code 0
db-1   | 2025-05-31 13:36:16.656 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.656 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
db-1   | 2025-05-31 13:36:16.657 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.657 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
db-1   | 2025-05-31 13:36:16.667 UTC [37] ERROR:  relation "schema_migrations" does not exist at character 21
db-1   | 2025-05-31 13:36:16.667 UTC [37] STATEMENT:  SELECT version FROM schema_migrations LIMIT 1
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Current version is 0
db-1   | 2025-05-31 13:36:16.667 UTC [37] ERROR:  relation "logs" does not exist at character 13
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201701261850 (201701261850_create_tenants.up.sql)
db-1   | 2025-05-31 13:36:16.667 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
db-1   | 2025-05-31 13:36:16.667 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.667 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201701281131 (201701281131_rename_domain.up.sql)
db-1   | 2025-05-31 13:36:16.682 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.682 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201702072040 (201702072040_create_ideas.up.sql)
db-1   | 2025-05-31 13:36:16.686 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.686 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201702251213 (201702251213_create_users.up.sql)
db-1   | 2025-05-31 13:36:16.693 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.693 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201702251620 (201702251620_add_tenant_cname.up.sql)
db-1   | 2025-05-31 13:36:16.698 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.698 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201703172030 (201703172030_add_ideas_userid.up.sql)
db-1   | 2025-05-31 13:36:16.701 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.701 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201703172115 (201703172115_remove_col_defaults.up.sql)
db-1   | 2025-05-31 13:36:16.705 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.705 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201703240709 (201703240709_remove_col_tenants.up.sql)
db-1   | 2025-05-31 13:36:16.709 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.709 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201703240710 (201703240710_create_comments.up.sql)
db-1   | 2025-05-31 13:36:16.713 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.713 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201703310824 (201703310824_remove_col_user_providers.up.sql)
db-1   | 2025-05-31 13:36:16.719 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.719 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201703310857 (201703310857_add_tenant_to_users.up.sql)
db-1   | 2025-05-31 13:36:16.722 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.722 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201704101854 (201704101854_add_ideas_number.up.sql)
db-1   | 2025-05-31 13:36:16.727 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.727 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201704112003 (201704112003_add_role_users.up.sql)
db-1   | 2025-05-31 13:36:16.732 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.732 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201704181821 (201704181821_add_supporters.up.sql)
db-1   | 2025-05-31 13:36:16.735 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.735 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201705132054 (201705132054_add_idea_status.up.sql)
db-1   | 2025-05-31 13:36:16.740 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.740 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201705191854 (201705191854_add_idea_slug.up.sql)
db-1   | 2025-05-31 13:36:16.744 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.744 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201705202300 (201705202300_add_idea_response.up.sql)
db-1   | 2025-05-31 13:36:16.747 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.747 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201707081055 (201707081055_set_cname_null.up.sql)
db-1   | 2025-05-31 13:36:16.751 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.751 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201707261949 (201707261949_set_cname_empty.up.sql)
db-1   | 2025-05-31 13:36:16.757 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.757 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201707271826 (201707271826_new_tenant_settings.up.sql)
db-1   | 2025-05-31 13:36:16.761 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.761 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201709081837 (201709081837_create_email_verifications.up.sql)
db-1   | 2025-05-31 13:36:16.766 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.766 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201709091228 (201709091228_create_email_verification_key_index.up.sql)
db-1   | 2025-05-31 13:36:16.771 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.771 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201709141944 (201709141944_rename_email_verification.up.sql)
db-1   | 2025-05-31 13:36:16.775 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.775 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201709241236 (201709241236_add_tenant_status.up.sql)
db-1   | 2025-05-31 13:36:16.779 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.779 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201709241254 (201709241254_add_signin_request_name_expires_on.up.sql)
db-1   | 2025-05-31 13:36:16.782 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.782 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201711152138 (201711152138_create_tags.up.sql)
db-1   | 2025-05-31 13:36:16.787 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.787 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201711181740 (201711181740_create_uniq_indexes.up.sql)
db-1   | 2025-05-31 13:36:16.794 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.794 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201712061924 (201712061924_unique_email.up.sql)
db-1   | 2025-05-31 13:36:16.798 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.798 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201712131842 (201712131842_unique_slug.up.sql)
db-1   | 2025-05-31 13:36:16.804 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.804 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201801031643 (201801031643_original_id.up.sql)
db-1   | 2025-05-31 13:36:16.808 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.808 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201801152006 (201801152006_rename_signin_requests.up.sql)
db-1   | 2025-05-31 13:36:16.811 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.811 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201801152017 (201801152017_add_kind_email_verification.up.sql)
db-1   | 2025-05-31 13:36:16.815 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.815 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201802061858 (201802061858_create_notification_tables.up.sql)
db-1   | 2025-05-31 13:36:16.819 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.819 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201802071816 (201802071816_seed_subscribers_table.up.sql)
db-1   | 2025-05-31 13:36:16.825 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.825 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201802231910 (201802231910_add_pg_trgm.up.sql)
db-1   | 2025-05-31 13:36:16.829 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.829 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201802241348 (201802241348_create_webnotification_tables.up.sql)
db-1   | 2025-05-31 13:36:16.849 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.849 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201803011831 (201803011831_add_tenant_id_everywhere.up.sql)
db-1   | 2025-05-31 13:36:16.855 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.855 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201803110836 (201803110836_edit_comment_columns.up.sql)
db-1   | 2025-05-31 13:36:16.875 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.875 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201804091842 (201804091842_add_is_private.up.sql)
db-1   | 2025-05-31 13:36:16.879 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.879 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201805061319 (201805061319_create_uploads.up.sql)
db-1   | 2025-05-31 13:36:16.883 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.883 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201805070759 (201805070759_add_logo_id.up.sql)
db-1   | 2025-05-31 13:36:16.889 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.889 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201805162034 (201805162034_add_custom_css.up.sql)
db-1   | 2025-05-31 13:36:16.895 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.895 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201805230000 (201805230000_drop_supporters_column.up.sql)
db-1   | 2025-05-31 13:36:16.899 UTC [37] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.899 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201805261834 (201805261834_add_user_status.up.sql)
db-1   | 2025-05-31 13:36:16.904 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.904 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201806191904 (201806191904_create_logs.sql)
db-1   | 2025-05-31 13:36:16.909 UTC [36] ERROR:  relation "logs" does not exist at character 13
db-1   | 2025-05-31 13:36:16.909 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201807122132 (201807122132_create_oauth_providers.sql)
db-1   | 2025-05-31 13:36:16.913 UTC [36] ERROR:  column "created_at" of relation "logs" does not exist at character 37
db-1   | 2025-05-31 13:36:16.913 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201808152020 (201808152020_rename_idea_post.sql)
db-1   | 2025-05-31 13:36:16.919 UTC [37] ERROR:  column "created_at" of relation "logs" does not exist at character 37
db-1   | 2025-05-31 13:36:16.919 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201808181931 (201808181931_add_api_key_users.sql)
db-1   | 2025-05-31 13:36:16.926 UTC [36] ERROR:  column "created_at" of relation "logs" does not exist at character 37
db-1   | 2025-05-31 13:36:16.926 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201808192103 (201808192103_increase_key_size.sql)
db-1   | 2025-05-31 13:36:16.932 UTC [36] ERROR:  column "created_at" of relation "logs" does not exist at character 37
db-1   | 2025-05-31 13:36:16.932 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201808291958 (201808291958_rename_support_vote.sql)
db-1   | 2025-05-31 13:36:16.937 UTC [37] ERROR:  column "created_at" of relation "logs" does not exist at character 37
db-1   | 2025-05-31 13:36:16.937 UTC [37] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201809262108 (201809262108_rename_datetime_fields.sql)
db-1   | 2025-05-31 13:36:16.942 UTC [36] ERROR:  column "created_at" of relation "logs" does not exist at character 37
db-1   | 2025-05-31 13:36:16.942 UTC [36] STATEMENT:  INSERT INTO logs (tag, level, text, created_at, properties) VALUES ($1, $2, $3, $4, $5)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201810022329 (201810022329_add_events.sql)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201810152035 (201810152035_add_comment_deleted.sql)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201811071547 (201811071547_increase_link_size.sql)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201812102208 (201812102208_create_blob_table.sql)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201812171813 (201812171813_migrate_to_blobs.sql)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201812201644 (201812201644_migrate_autocert_to_blobs.sql)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201812230904 (201812230904_user_avatar_type.sql)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201901042021 (201901042021_create_tenants_billing.sql)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201901072106 (201901072106_recreate_post_slug_index.sql)
app-1  | INFO [2025-05-31T13:36:16Z] [MIGRATE] Running Version: 201901130830 (201901130830_attachments.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] Running Version: 201904022134 (201904022134_lowercase_emails.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] Running Version: 201904091921 (201904091921_fix_api_users_role.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] Running Version: 202105161823 (202105161823_create_indexes.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] Running Version: 202107031320 (202107031320_add_locale_field.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] Running Version: 202107211126 (202107211126_added_allowing_email_auth.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] Running Version: 202108092243 (202108092243_create_webhooks.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] Running Version: 202109052023 (202109052023_email_supressed_at.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] Running Version: 202109072130 (202109072130_paddle_fields.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] Running Version: 202109272130 (202109272130_system_settings.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] Running Version: 202205082055 (202205082055_trusted_provider.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] Running Version: 202406111146 (202406111146_add_posts_user_id_index.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] Running Version: 202410122105 (202410122105_create_reactions_up.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] Running Version: 202503202000 (202503202000_mentions_notifications.sql)
app-1  | INFO [2025-05-31T13:36:17Z] [MIGRATE] 74 migrations have been applied.
app-1  | INFO [2025-05-31T13:36:17Z] [WEB] Application is starting
app-1  | INFO [2025-05-31T13:36:17Z] [WEB] Version: 0.22.0-0ea0031a87fe8a2927b4ba6b2967d93bd605c331
app-1  | INFO [2025-05-31T13:36:17Z] [WEB] Environment: production
app-1  | INFO [2025-05-31T13:36:17Z] [WEB] http server started on :3000
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 6.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 11.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 1.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 5.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 0.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 2.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 14.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 4.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 7.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 13.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 15.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 12.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 8.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 3.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 10.
app-1  | INFO [2025-05-31T13:36:17Z] [BGW] Starting worker 9.

I can now view the signup page

/content/images/2025/06/fider-01.png

Be aware that for initial signup it wants to verify your email (which seems silly for the admin user)

/content/images/2025/06/fider-02.png

At first, I thought I might be stuck as the email did not come through.

/content/images/2025/06/fider-04.png

Perhaps resend doe not like the from and to addresses to be the same. I certainly didn’t get a forward to my gmail.

That said, I could view the logs in Resend to find the validation URL:

/content/images/2025/06/fider-03.png

I did a quick scan of settings before moving on and noted that if I take this to production, I can use some IdP’s like Google

/content/images/2025/06/fider-05.png

I’ll try making a suggestion

/content/images/2025/06/fider-06.png

I now have a suggestion visible

/content/images/2025/06/fider-07.png

I now have a couple posts

/content/images/2025/06/fider-08.png

An incognito window does show that they are public (but one cannot vote without logging in)

/content/images/2025/06/fider-09.png

This might be a challenge as the sign in just sends emails

/content/images/2025/06/fider-10.png

Helm

As I’m having troubles with the container so perhaps I’ll have more luck with the Fider helm charts

$ helm repo add fider https://getfider.github.io/helm
"fider" has been added to your repositories

$ helm search repo fider
NAME                    CHART VERSION   APP VERSION     DESCRIPTION
fider/fider             0.0.6           0.25.0          An open platform to collect and prioritize feed...
fider/postgresql        12.6.4          15.3.0          PostgreSQL (Postgres) is an open source object-...

We can look at the values in the chart

I can start with a quick install to see what it creates

$ helm install myfider -n fider --set postgresql.enabled=true fider/fider
NAME: myfider
LAST DEPLOYED: Mon Jun  2 21:15:37 2025
NAMESPACE: fider
STATUS: deployed
REVISION: 1
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace fider -l "app.kubernetes.io/name=fider,app.kubernetes.io/instance=myfider" -o jsonpath="{.items[0].metadata.name}")
  export CONTAINER_PORT=$(kubectl get pod --namespace fider $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace fider port-forward $POD_NAME 8080:$CONTAINER_PORT

$ kubectl get po -n fider
NAME                       READY   STATUS              RESTARTS   AGE
myfider-6df6556897-sjzs8   0/1     Init:0/1            0          11s
myfider-postgresql-0       0/1     ContainerCreating   0          11s

the first thing I noticed is the dbchecker was failing and it seems to do with a wrong PSQL service name

2025-06-03T02:17:28Z INF [PostgreSQL] Checking the postgresql-service:5432 ...
2025-06-03T02:17:28Z ERR Expectation failed error="failed to establish a connection to the postgresql server, caused by: dial tcp: lookup postgresql-service on 10.43.0.10:53: no such host" dsn=postgres://fider:s0m3g00dp4ssw0rd@postgresql-service:5432/fider?sslmode=disable
2025-06-03T02:17:29Z INF [PostgreSQL] Checking the postgresql-service:5432 ...
2025-06-03T02:17:29Z ERR Expectation failed error="failed to establish a connection to the postgresql server, caused by: dial tcp: lookup postgresql-service on 10.43.0.10:53: no such host" dsn=postgres://fider:s0m3g00dp4ssw0rd@postgresql-service:5432/fider?sslmode=disable
builder@LuiGi:~/Workspaces/jekyll-blog$ kubectl get svc -n fider
NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE
myfider-postgresql-hl   ClusterIP   None            <none>        5432/TCP            2m3s
myfider                 ClusterIP   10.43.83.15     <none>        3000/TCP,4000/TCP   2m3s
myfider-postgresql      ClusterIP   10.43.139.150   <none>        5432/TCP            2m3s

I fixed that and added values for SendGrid email

$ helm upgrade --install myfider -n fider -f ./values.yaml fider/fider
Release "myfider" has been upgraded. Happy Helming!
NAME: myfider
LAST DEPLOYED: Mon Jun  2 21:26:52 2025
NAMESPACE: fider
STATUS: deployed
REVISION: 2
NOTES:
1. Get the application URL by running these commands:
  export POD_NAME=$(kubectl get pods --namespace fider -l "app.kubernetes.io/name=fider,app.kubernetes.io/instance=myfider" -o jsonpath="{.items[0].metadata.name}")
  export CONTAINER_PORT=$(kubectl get pod --namespace fider $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
  echo "Visit http://127.0.0.1:8080 to use your application"
  kubectl --namespace fider port-forward $POD_NAME 8080:$CONTAINER_PORT

So we could create an ingress, I made a new A record

$ az account set --subscription "Pay-As-You-Go" && az network dns record-set a add-record -g idjdnsrg -z tpk.pw -a 75.73.224.240 -n fider
{
  "ARecords": [
    {
      "ipv4Address": "75.73.224.240"
    }
  ],
  "TTL": 3600,
  "etag": "61f9f4b8-8462-458f-806b-007de99bd520",
  "fqdn": "fider.tpk.pw.",
  "id": "/subscriptions/d955c0ba-13dc-44cf-a29a-8fed74cbb22d/resourceGroups/idjdnsrg/providers/Microsoft.Network/dnszones/tpk.pw/A/fider",
  "name": "fider",
  "provisioningState": "Succeeded",
  "resourceGroup": "idjdnsrg",
  "targetResource": {},
  "trafficManagementProfile": {},
  "type": "Microsoft.Network/dnszones/A"
}

I then setup the ingress and applied

builder@LuiGi:~/Workspaces/jekyll-blog$ helm upgrade --install myfider -n fider -f ./values.yaml fider/fider
Release "myfider" has been upgraded. Happy Helming!
NAME: myfider
LAST DEPLOYED: Mon Jun  2 21:43:57 2025
NAMESPACE: fider
STATUS: deployed
REVISION: 7
NOTES:
1. Get the application URL by running these commands:
  https://fider.tpk.pw/
builder@LuiGi:~/Workspaces/jekyll-blog$ kubectl get ingress -n fider
NAME      CLASS    HOSTS          ADDRESS   PORTS     AGE
myfider   <none>   fider.tpk.pw             80, 443   72s
builder@LuiGi:~/Workspaces/jekyll-blog$ kubectl get cert -n fider
NAME        READY   SECRET      AGE
fider-tls   False   fider-tls   79s
builder@LuiGi:~/Workspaces/jekyll-blog$ kubectl get cert -n fider
NAME        READY   SECRET      AGE
fider-tls   True    fider-tls   95s
builder@LuiGi:~/Workspaces/jekyll-blog

I can now signup using the URL https://fider.tpk.pw/

/content/images/2025/06/fider-11.png

I fired up the signup

/content/images/2025/06/fider-12.png

This time I had no issues getting the email

/content/images/2025/06/fider-13.png

I can now add suggestions

/content/images/2025/06/fider-14.png

I can customize it a bit

/content/images/2025/06/fider-15.png

Oauth

Let’s add google login as by defualt, no OAuth providers are setup

/content/images/2025/06/fider-16.png

We first go to Google Credentials to create a new credential

/content/images/2025/06/fider-17.png

We’ll create a new “OAuth client ID”

/content/images/2025/06/fider-18.png

We’ll add a new Web client and the OAuth call back to <site>/oauth/google/callback

/content/images/2025/06/fider-19.png

This should return a Client ID and Secret we’ll need to put into Fider

/content/images/2025/06/fider-20.png

I’ll now want to add these Env vars via Helm

OAUTH_GOOGLE_CLIENTID: Client ID given by Google
OAUTH_GOOGLE_SECRET: Client Secret given by Google

I can do it with a few quick commands locally:

builder@DESKTOP-QADGF36:~$ helm list -n fider
NAME    NAMESPACE       REVISION        UPDATED                                 STATUS          CHART         APP VERSION
myfider fider           7               2025-06-02 21:43:57.622777665 -0500 CDT deployed        fider-0.0.6   0.25.0
builder@DESKTOP-QADGF36:~$ helm get values myfider -n fider -o yaml > fider.values.yaml
builder@DESKTOP-QADGF36:~$ helm get values myfider -n fider -o yaml > fider.values.yaml.bak
builder@DESKTOP-QADGF36:~$ vi fider.values.yaml
builder@DESKTOP-QADGF36:~$ diff fider.values.yaml fider.values.yaml.bak
42,45d41
<   - name: OAUTH_GOOGLE_CLIENTID
<     value: 511842454269-8mis7mvs0vfa91mid2n2lq1gsdl1eclo.apps.googleusercontent.com
<   - name: OAUTH_GOOGLE_SECRET
<     value: GOxxxxxxxxxxxxxxxxxxxxxxxxxxx
builder@DESKTOP-QADGF36:~$ helm repo add fider https://getfider.github.io/helm
"fider" has been added to your repositories
builder@DESKTOP-QADGF36:~$ helm upgrade myfider -n fider -f ./fider.values.yaml fider/fider
Release "myfider" has been upgraded. Happy Helming!
NAME: myfider
LAST DEPLOYED: Tue Jun  3 06:24:17 2025
NAMESPACE: fider
STATUS: deployed
REVISION: 8
NOTES:
1. Get the application URL by running these commands:
  https://fider.tpk.pw/

I did not even have to re-login - can now see Google enabled

/content/images/2025/06/fider-21.png

A quick test proves it works

I’ve now loaded it with some options. I welcome you to go to https://fider.tpk.pw/ to add new ones or vote on them. If Fider turns into spam, then I’ll lock it down more.

/content/images/2025/06/fider-23.png

AudioBookshelf

I listen to AudioBooks from time to time - most often with Audible for which I have a pretty extensive collection. In fact, just yesterday I picked up the latest Stephen King. But I find dancing between devices a bit challenging.

Audioshelf is a self-hosted Audiobook and Podcast server. Frankly this solves two problems at once (as my ancient Doggcatcher app I don’t think is updated anymore).

The Docker compose steps are pretty easy

services:
  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:latest
    ports:
      - 13378:80
    volumes:
      - </path/to/audiobooks>:/audiobooks
      - </path/to/podcasts>:/podcasts
      - </path/to/config>:/config
      - </path/to/metadata>:/metadata
    environment:
      - TZ=America/Toronto

I initially planned to convert this to Helm to run in Kubernetes, but I think docker might work best as i can mount the volume on the NAS

builder@builder-T100:~$ sudo mkdir /mnt/sassynassymusic
builder@builder-T100:~$ sudo vi /etc/fstab
builder@builder-T100:~$ cat /etc/fstab | tail -n 1
192.168.1.129:/volume1/music    /mnt/sassynassymusic    nfs    auto,nofail,noatime,nolock,intr,tcp,actimeo=1800        0       0
builder@builder-T100:~$ sudo mount -a
builder@builder-T100:~$ ls /mnt/sassynassymusic/Audiobooks/
@eaDir  eatthatfrog_berrettkoehler  humbleconsulting  humbleleadership  long-distanceteammate

I’ll make some local dirs and open them up for podcasts, config and metadata

builder@builder-T100:~/AudioBookshelf$ ls -ltra
total 24
-rw-rw-r--  1 builder builder  324 Jun  3 07:26 docker-compose.yml
drwxrwxr-x  2 builder builder 4096 Jun  3 07:26 podcasts
drwxr-xr-x 87 builder builder 4096 Jun  3 07:27 ..
drwxrwxr-x  2 builder builder 4096 Jun  3 07:27 config
drwxrwxr-x  2 builder builder 4096 Jun  3 07:27 metadata
drwxrwxr-x  5 builder builder 4096 Jun  3 07:27 .
builder@builder-T100:~/AudioBookshelf$ chmod 777 podcasts/
builder@builder-T100:~/AudioBookshelf$ chmod 777 config/
builder@builder-T100:~/AudioBookshelf$ chmod 777 metadata/

We can now see a docker compose YAML that uses the NAS mount for the AudioBooks but some local folders for the rest

builder@builder-T100:~/AudioBookshelf$ cat ./docker-compose.yml
services:
  audiobookshelf:
    image: ghcr.io/advplyr/audiobookshelf:latest
    ports:
      - 13378:80
    volumes:
      - /mnt/sassynassymusic/Audiobooks:/audiobooks
      - /home/builder/AudioBookshelf/podcasts:/podcasts
      - /home/builder/AudioBookshelf/config:/config
      - /home/builder/AudioBookshelf/metadata:/metadata
    environment:
      - TZ=America/Chicago

I can now start it up (interactively)

builder@builder-T100:~/AudioBookshelf$ docker compose up
[+] Running 10/10
 ✔ audiobookshelf 9 layers [⣿⣿⣿⣿⣿⣿⣿⣿⣿]      0B/0B      Pulled                                                      6.1s
   ✔ fe07684b16b8 Pull complete                                                                                    0.7s
   ✔ 50e3d90b6378 Pull complete                                                                                    2.4s
   ✔ de1f569a8696 Pull complete                                                                                    2.5s
   ✔ a35ae40f249e Pull complete                                                                                    2.5s
   ✔ fee7fee3e86b Pull complete                                                                                    3.4s
   ✔ dfa18c41c46b Pull complete                                                                                    3.5s
   ✔ b14f4aee86e0 Pull complete                                                                                    3.6s
   ✔ fdf0bf560042 Pull complete                                                                                    4.8s
   ✔ 8dc553bc5569 Pull complete                                                                                    4.8s
[+] Building 0.0s (0/0)
[+] Running 2/2
 ✔ Network audiobookshelf_default             Created                                                              0.1s
 ✔ Container audiobookshelf-audiobookshelf-1  Created                                                              0.5s
Attaching to audiobookshelf-audiobookshelf-1
audiobookshelf-audiobookshelf-1  | Running in production mode.
audiobookshelf-audiobookshelf-1  | Options: CONFIG_PATH=/config, METADATA_PATH=/metadata, PORT=80, HOST=undefined, SOURCE=docker, ROUTER_BASE_PATH=/audiobookshelf
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:10.382] INFO: === Starting Server ===
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:10.384] INFO: [Server] Init v2.24.0
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:10.384] INFO: [Server] Node.js Version: v20.19.2
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:10.385] INFO: [Server] Platform: linux
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:10.385] INFO: [Server] Arch: x64
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:10.392] INFO: [Database] absdatabase.sqlite not found at /config/absdatabase.sqlite
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:10.392] INFO: [Database] Initializing db at "/config/absdatabase.sqlite"
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:10.418] INFO: [Database] Loading extension /usr/local/lib/nusqlite3/libnusqlite3.so
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:10.419] INFO: [Database] Successfully loaded extension /usr/local/lib/nusqlite3/libnusqlite3.so
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:10.419] INFO: [Database] Db supports unaccent and unicode foldings
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:10.420] INFO: [Database] Db connection was successful
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:10.620] INFO: [MigrationManager] Database is new. Skipping migrations.
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.005] INFO: [Database] Db initialized with models: user, library, libraryFolder, book, podcast, podcastEpisode, libraryItem, mediaProgress, series, bookSeries, author, bookAuthor, collection, collectionBook, playlist, playlistMediaItem, device, playbackSession, feed, feedEpisode, setting, customMetadataProvider, mediaItemShare
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.006] INFO: [Database] Adding trigger update_library_items_title
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.011] INFO: [Database] Adding trigger update_library_items_title_ignore_prefix
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.018] INFO: [Database] Adding trigger update_library_items_title_from_podcasts_title
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.024] INFO: [Database] Adding trigger update_library_items_title_ignore_prefix_from_podcasts_title_ignore_prefix
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.031] INFO: [Database] Adding trigger update_library_items_author_names_on_book_authors_insert
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.037] INFO: [Database] Adding trigger update_library_items_author_names_on_book_authors_delete
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.043] INFO: [Database] Adding trigger update_library_items_author_names_on_authors_update
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.079] INFO: [Database] running ANALYZE
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.084] INFO: [Database] ANALYZE completed
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.086] INFO: [LogManager] Init current daily log filename: 2025-06-03.txt
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.114] INFO: [BackupManager] 0 Backups Found
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.115] INFO: [BackupManager] Auto Backups are disabled
audiobookshelf-audiobookshelf-1  | [2025-06-03 07:29:11.134] INFO: Listening on port :80

The first page has configure (note: i did not change my zoom level, it just uses rather small fonts)

/content/images/2025/06/audiobookshelf-01.png

I’m now at the main dashboard

/content/images/2025/06/audiobookshelf-02.png

I’ll add my Audiobooks first.

/content/images/2025/06/audiobookshelf-03.png

I then clicked scan

/content/images/2025/06/audiobookshelf-04.png

I was a bit worried as these were from a Humble Bundle I got a while back and came down as mp3 files not m4b or any other “book” format.

But as we see, it did find them just fine

/content/images/2025/06/audiobookshelf-05.png

Playing from the web browser was fine, but would it pick up where i left off if I switched to the phone?

/content/images/2025/06/audiobookshelf-06.jpg

Indeed it picked right back up.

I stopped then started the Docker service in daemon mode

builder@builder-T100:~/AudioBookshelf$ docker compose up -d
[+] Building 0.0s (0/0)
[+] Running 1/1
 ✔ Container audiobookshelf-audiobookshelf-1  Started                                                              0.5s

I want to expose this externally so first I need a DNS record

$ az account set --subscription "Pay-As-You-Go" && az network dns record-set a add-record -g idjdnsrg -z tpk.pw -a 75.73.224.240 -n audioshelf
{
  "ARecords": [
    {
      "ipv4Address": "75.73.224.240"
    }
  ],
  "TTL": 3600,
  "etag": "a49e0012-e016-4851-9c43-7b80929bc704",
  "fqdn": "audioshelf.tpk.pw.",
  "id": "/subscriptions/d955c0ba-13dc-44cf-a29a-8fed74cbb22d/resourceGroups/idjdnsrg/providers/Microsoft.Network/dnszones/tpk.pw/A/audioshelf",
  "name": "audioshelf",
  "provisioningState": "Succeeded",
  "resourceGroup": "idjdnsrg",
  "targetResource": {},
  "trafficManagementProfile": {},
  "type": "Microsoft.Network/dnszones/A"
}

Then I just need an Endpoint, Service and Ingress to expose it externally

$ cat audioshelf.yaml
apiVersion: v1
kind: Endpoints
metadata:
  name: audioshelf-external-ip
subsets:
- addresses:
  - ip: 192.168.1.100
  ports:
  - name: audioshelfint
    port: 13378
    protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: audioshelf-external-ip
spec:
  clusterIP: None
  clusterIPs:
  - None
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  - IPv6
  ipFamilyPolicy: RequireDualStack
  ports:
  - name: audioshelf
    port: 80
    protocol: TCP
    targetPort: 13378
  sessionAffinity: None
  type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer: azuredns-tpkpw
    ingress.kubernetes.io/ssl-redirect: "true"
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
    nginx.org/websocket-services: audioshelf-external-ip
  generation: 1
  name: audioshelfingress
spec:
  rules:
  - host: audioshelf.tpk.pw
    http:
      paths:
      - backend:
          service:
            name: audioshelf-external-ip
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific
  tls:
  - hosts:
    - audioshelf.tpk.pw
    secretName: audioshelf-tls

$ kubectl apply -f ./audioshelf.yaml
endpoints/audioshelf-external-ip created
service/audioshelf-external-ip created
ingress.networking.k8s.io/audioshelfingress created

I can now login using the URL

/content/images/2025/06/audiobookshelf-07.png

Podcasts

Let’s add a new Podcast library

/content/images/2025/06/audiobookshelf-08.png

I added several, but no episodes showed up.

/content/images/2025/06/audiobookshelf-11.png

When I got back to the UI, I realized it, by default, sets it to find new episodes newer than the moment you add (namely, only future episodes).

I moved it back by a few days in the Episodes tab then could find new episodes

/content/images/2025/06/audiobookshelf-09.png

Now I can see one to play

/content/images/2025/06/audiobookshelf-10.png

Like this:

One of my favourites from DJ Hex, which my primary coding music, DNB Dojo stopped updating a couple of years ago but he keeps his feed up. I set it to download all the episodes as I just like to listen at random

/content/images/2025/06/audiobookshelf-12.png

A quick note: if we add books to a network share, we’ll want to go to the library to “scan” to find them

/content/images/2025/06/audiobookshelf-14.png

I found a few classic Sci-fi books to add to my collection of business books on libvox which has free public domain books read by volunteers.

/content/images/2025/06/audiobookshelf-15.png

Stats

The app has various stats and metrics for those interested; such as top authors and largest items

/content/images/2025/06/audiobookshelf-13.png

I can make user accounts and even set whether they can access explicit content (which would be good for my kiddos)

/content/images/2025/06/audiobookshelf-17.png

Summary

We set up Fider, first on docker then on Kubernetes. I spent a bit more time than I hoped trying to get Docker to work - I suspect now it might have just been an old image. Once in Kubernetes, it worked like a charm (using Sendgrid).

I then moved on to AudioBookshelf which was very easy to setup in Docker. They have docs for Docker, Linux, Windows and more. My only challenge was really figuring out how the episodes of podcasts worked. I thought that it would show the last 5 or so but instead it just, by default, shows future episodes. Once I sorted that, it worked great. It also works fantastic for audiobooks. I’ll have to check this more as I commute.

I don’t think I’ll ditch my local Doggcatcher app though because one really good use for an Android app is when i have low/no bandwidth. This means I’ll likely go back to the local app for remote camping (BWCA), airplane and kids sports practices (some of the regional pools are like faraday cages for signal).

Hopefully you found something interesting… and for the time being (unless it gets spammed too hard), please use my Fider (fider.tpk.pw) to provide ideas/suggestions if you have any. If there ends up being a desire for podcasts or YouTube videos, I can always go that direction.

fider feedback audiobookshelf podcasts audiobooks opensource docker kubernetes

Have something to add? Feedback? You can use the feedback form

Isaac Johnson

Isaac Johnson

Cloud Solutions Architect

Isaac is a CSA and DevOps engineer who focuses on cloud migrations and devops processes. He also is a dad to three wonderful daughters (hence the references to Princess King sprinkled throughout the blog).

Theme built by C.S. Rhymes