Architecture¶
The tale of sewifurs.org’s architecture is that of gradual evolution, not up-front design.
History¶
When sewifurs.org was created in November 2021, it was a static website. It was converted to a Flask web app and an accompanying bot in March 2022. The bot gained moderation functions in February 2024. Basic Telegram-based logins (for Bluesky Social custom handles) were supported in March 2025.
Following this, another developer joined the project, and I started to get inquiries from furries elsewhere who were interested in using sewifurs.org as a base for local furry community websites of their own. Major improvements were needed to allow sewifurs.org to grow. July and August 2025 saw the replacement of hardcoded privileges with a runtime-configurable permission system, a split into multiple independently-runnable modules, and a cloud-friendlier settings system. Integration testing came in September 2025, and Docker Compose in November 2025.
As of writing, sewifurs.org still requires a hard fork to use; branding, chat directory entries, and other details are hardcoded as SEWI Furs. However, as this project’s architecture continues to evolve, a future split into two projects may be possible: an unbranded core (tentatively called FurHome), and a branded client consuming that core (the ‘future’ SEWI Furs).
Modules¶
sewifurs.org is split into the following modules:
sewifurs.bot, the Telegram botRequires Telegram bot credentials.
Does not require a web server.
sewifurs.linkchecker, the chat directory link checkerDoes not require Telegram bot credentials.
Does not require a web server.
sewifurs.website, the Flask web appDoes not require Telegram bot credentials, but some functionality won’t be available without them.
Requires a web server.
When doing local development, if you only need to interact with one part of
sewifurs.org, you can run only that module with python3 -m sewifurs.module,
replacing module with the appropriate name. sewifurs.website will
spin up Flask’s built-in development server on port 5000 if run directly.
When deployed using Docker, all modules are started in a single container by
run.sh, which also prepares static assets for serving by the nginx container,
runs database migrations, and uses uWSGI to serve sewifurs.website.app
behind nginx.
Current state¶
architecture-beta
group compose(cloud)[Docker Compose]
group world(cloud)[Persistence]
service bot(server)[Bot] in compose
service linkchecker(server)[Link checker] in compose
service website(server)[Website] in compose
service script(disk)[Run script] in compose
service sqlite(database)[sqlite3 database] in world
service uwsgi(server)[uWSGI] in compose
service telegram(internet)[Telegram] in world
service dns(internet)[DNS providers] in world
service nginx(server)[nginx] in compose
service static(disk)[Static assets] in compose
service docs(disk)[Documentation] in compose
service config(disk)[Configuration] in world
service sphinx(server)[Sphinx] in compose
website:B -- T:uwsgi
uwsgi:B -- T:nginx
static:R -- L:nginx
docs:L -- R:nginx
docs:B -- T:sphinx
script:B -- T:website
bot:R -- L:script
linkchecker:L -- R:script
config{group}:B -- T:script{group}