- Ruby 56%
- Gherkin 19.6%
- HTML 16.1%
- JavaScript 5.5%
- CSS 2.5%
- Other 0.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
Some checks failed
Automated Tests / rspec --exclude-pattern 'spec/{controllers,models}/**/*.rb' (push) Has been cancelled
Automated Tests / rake db:otwseed (push) Has been cancelled
Automated Tests / cucumber features/admins (push) Has been cancelled
Automated Tests / cucumber features/bookmarks (push) Has been cancelled
Automated Tests / cucumber features/collections (push) Has been cancelled
Automated Tests / cucumber features/comments_and_kudos (push) Has been cancelled
Automated Tests / cucumber features/gift_exchanges (push) Has been cancelled
Automated Tests / cucumber features/importing (push) Has been cancelled
Automated Tests / cucumber features/other_a (push) Has been cancelled
Automated Tests / cucumber features/other_b (push) Has been cancelled
Automated Tests / cucumber features/prompt_memes_a (push) Has been cancelled
Automated Tests / cucumber features/prompt_memes_b (push) Has been cancelled
Automated Tests / cucumber features/prompt_memes_c (push) Has been cancelled
Automated Tests / cucumber features/search (push) Has been cancelled
Automated Tests / cucumber features/tag_sets (push) Has been cancelled
Automated Tests / cucumber features/tags_and_wrangling (push) Has been cancelled
Automated Tests / cucumber features/users (push) Has been cancelled
Automated Tests / cucumber features/works (push) Has been cancelled
Automated Tests / rspec spec/controllers (push) Has been cancelled
Automated Tests / rspec spec/models (push) Has been cancelled
Brakeman Scan / Brakeman Scan (push) Has been cancelled
- Target .userstuff[role="article"] specifically for chapter content - Previously extracted from entire chapter div, including summary/notes modules - Fixes issue where chapter summaries appeared in fic text - Fixes issue where chapter notes appeared in fic text - Maintains fallback to .userstuff if role="article" not found |
||
| .github | ||
| app | ||
| bin | ||
| config | ||
| db | ||
| entrypoints | ||
| factories | ||
| features | ||
| lib | ||
| log | ||
| public | ||
| rubocop | ||
| script | ||
| scripts | ||
| spec | ||
| test | ||
| .codeclimate.yml | ||
| .codecov.yml | ||
| .devcontainer.json | ||
| .env.example | ||
| .erb-lint.yml | ||
| .gitattributes | ||
| .gitignore | ||
| .hound.yml | ||
| .jshintignore | ||
| .jshintrc | ||
| .phrase.yml | ||
| .rubocop.yml | ||
| .ruby-version | ||
| .simplecov | ||
| ACKNOWLEDGMENTS.md | ||
| Capfile | ||
| config.ru | ||
| CONTRIBUTING.md | ||
| docker-compose.yml | ||
| fflol-logo-white.png | ||
| fflol-logo.png | ||
| Gemfile | ||
| Gemfile.lock | ||
| LICENSE | ||
| Rakefile | ||
| README.md | ||
| SECURITY.md | ||
fanfiction.lol
An independent fanfiction archive forked from the OTW-Archive codebase, the open-source software powering Archive of Our Own. Created by Brennan, a Queer Red River Métis author and web developer, because fandom writing deserves independent, free infrastructure.
Live site: fanfiction.lol
Source code: source.tube/brennan/fanfiction.lol
Contact: mail@brennanbrown.ca
What Makes This Fork Different?
No Invite Queue
Anyone can register immediately, no waiting list, no queue. Sign up and start posting.
Fandom and Discourse Agnostic
This archive cares about the writing of fans, not fandom internal politics or discourse. Write whatever you want, tag it honestly so readers can find what they're looking for and avoid what they'd rather avoid. There are many other places on the internet for those conversations, just not here.
Expanded Content Warnings
Content warnings are important signals for readers who need them. The archive warnings include:
- Graphic Depictions Of Violence
- Major Character Death
- Rape/Non-Con
- Ableism
- Colonialism
- Queerphobia
- Misogyny
- Racism
- Systemic Oppression
- Real Person Fiction (RPF)
- Incest
Expanded Relationship Tags
The tagging system reflects the full range of what people actually write:
- F/F (Female/Female, Femslash, Lesbian, Sapphic)
- F/M (Female/Male, Het, Heterosexual)
- M/M (Male/Male, Slash, Gay, Queer)
- Gen (General, no romantic or sexual relationships)
- Multi (Multiple relationship tags)
- Other (Unconventional dynamics, complex relationship structures)
- Poly/Ensemble (Polyamorous relationships, ensemble casts)
- Asexual (Asexual spectrum, Ace)
- Aromantic (Aromantic spectrum, Aro)
- QPR (Queerplatonic Relationship)
- Queer (Other queer relationships or identities)
- Getting Together (Developing romantic relationship)
Nearly All Tags Are Canonical
Every tag you create goes into the searchable record.
Technical Stack
This fork runs on a complex stack containerized with Docker Compose:
- Ruby on Rails 8.1.2.1 on Ruby 3.4.6
- MariaDB 10.5.4 for the database
- Redis 7.4.9 for caching and job queue
- Elasticsearch 7.17.9 for work search (2GB RAM requirement)
- Memcached 1.5.22 for fragment caching
- Resque for background jobs with scheduler
- Cloudflare Tunnel for HTTPS/SSL without port forwarding
Deployment Architecture
The archive is deployed on a homelab server (Lubuntu on cafe) behind a Cloudflare Tunnel:
- SSL termination handled by Cloudflare at the edge
- No port forwarding required—home ports stay closed
- Container isolation for all services
- Automated backups via cron scripts
Deployment
Prerequisites
- Docker 29.1.3 or later
- Cloudflare account with domain configured
- At least 6 GB RAM allocated to Docker
- 30+ GB free disk space
Quick Start
-
Configure environment:
cp .env.example .env # Edit .env with your secrets -
Configure Cloudflare Tunnel:
- Create tunnel in Cloudflare Zero Trust
- Add public hostnames pointing to
http://web_prod:3000 - Add tunnel token to
.env
-
Initialize database:
docker compose run web_prod script/reset_database-prod.sh docker compose exec web_prod bundle exec rake db:schema:load docker compose exec web_prod bundle exec rails runner script/ensure_required_tags.rb docker compose exec web_prod bundle exec rake skins:load_site_skins -
Create admin account:
docker compose exec web_prod bundle exec rails runner script/create_admin.rb -
Start services:
docker compose up -d web_prod worker sc cloudflared
Services
web_prod— Rails application serverworker— Resque background job workersc— Resque scheduler for recurring taskscloudflared— Cloudflare Tunnel daemondb— MariaDB databasees— Elasticsearch 7.17.5 (amd64 emulation on ARM64)redis— Redis for caching and job queuemc— Memcached for fragment caching
Important Technical Notes
CSS in Database
The site uses a custom skin system where CSS is stored in the database (Skin model), not in files. To update styles:
- Update CSS files locally for reference
- Update the database skin via Rails runner:
docker exec fanfiction-web bundle exec rails runner 'skin = Skin.find_by_title("fanfiction.lol"); css = skin.css; css.gsub!("old", "new"); skin.save(validate: false)' - Clear Rails cache:
docker exec fanfiction-web bundle exec rails runner 'Rails.cache.clear' - Restart container:
docker compose restart fanfiction-web - Purge Cloudflare cache
Elasticsearch Indexing
Elasticsearch 7.17.9 is required (gem pins 7.17.1). While initial development was on macOS with Rosetta emulation, the production deployment runs on Lubuntu (cafe) with native amd64. After database changes, reload Elasticsearch:
docker compose run web_prod bin/reload_elastic
Tag System
All tags are set to canonical: true by default for immediate searchability. The tagging system is the same robust AO3 system but without volunteer wrangling bottlenecks.
Other AO3 Forks
fanfiction.lol is one of several AO3 forks. Here are the others:
- SuperLove — run by Kat (Melo)
- Sunset
- SquidgeWorld — run by Walter, the first AO3 fork ever deployed (November 2020)
- Ad Astra
- CFAA
About the Original OTW-Archive
The OTW-Archive software is developed by the Organization for Transformative Works, a nonprofit organization by and for fans. You can see the original in action on Archive of Our Own.
For detailed setup notes for the original codebase, see SquidgeWorld's guide.
fanfiction.lol is not affiliated with the Organization for Transformative Works or Archive of Our Own.
Contributing
This is a personal project, but I welcome feedback and issues. The upstream OTW-Archive has Contributing Guidelines if you want to contribute to the original codebase.
- Report issues: source.tube/brennan/fanfiction.lol/issues
- Contact: mail@brennanbrown.ca
- Mastodon: @brennan@social.lol
- Web: brennan.day/accounts
License
The Archive code is licensed under GPL-2.0-or-later by the Organization for Transformative Works.
Acknowledgments
- Kat (Melo) who runs SuperLove and wrote the Docker deployment guide that made this possible
- Walter who runs SquidgeWorld and whose bare-metal guide is the foundational reference for anyone doing this
- The Organization for Transformative Works for creating and maintaining the OTW-Archive codebase
love writing, love fandom!