Web application for Freedium.cfd https://freedium.cfd/
Find a file
2025-01-25 11:58:13 +05:00
.vscode feat(git hook): init 2024-11-08 15:13:02 +05:00
bin Migrate to Docker & logger enhances 2024-02-07 17:17:15 +06:00
caddy feat(caddy): hotfix prod https error problem 2024-11-20 18:24:08 +05:00
data Moving codebase from GitHub 2024-01-31 06:48:20 +06:00
database-lib feat(git hook): init 2024-11-08 15:13:02 +05:00
docker-compose wgcf: new private own proxy instead of cloudflare 2025-01-25 11:17:29 +05:00
freedium-library refactor(mutable_string): remove _is_dirty flag and related methods 2025-01-02 21:46:47 +05:00
medium-parser hmmm: yeah, Medium? 2025-01-25 11:58:13 +05:00
new-web fix(Header): adjust scroll threshold for header visibility from 15% to 5% to improve user experience 2025-01-02 21:11:33 +05:00
plausible/clickhouse feat(git hook): init 2024-11-08 15:13:02 +05:00
proxy-balancer feat(docker): add additional two Cloudflare Warp instances 2024-12-06 23:13:58 +05:00
rl_string_helper feat(git hook): init 2024-11-08 15:13:02 +05:00
scripts structure: refactor codebase 2024-09-20 18:39:12 +05:00
sitemap-generator structure: refactor codebase 2024-09-20 18:39:12 +05:00
test_lab medium parser: overlapse parser finnal fix 2024-09-21 20:41:38 +05:00
tests fix(new-freedium): bug fixes, settings restructure, minor UI fixes, overlay loader implement 2024-12-15 21:42:05 +05:00
web hmmm: yeah, Medium? 2025-01-25 11:58:13 +05:00
wgcf feat(git hook): init 2024-11-08 15:13:02 +05:00
.dockerignore prod: docker compose refactor filenames 2024-07-27 14:11:33 +05:00
.env_template feat(git hook): init 2024-11-08 15:13:02 +05:00
.gitignore feat(git hook): init 2024-11-08 15:13:02 +05:00
Dockerfile docker-compose: enhance container health checks 2024-09-25 15:56:47 +05:00
mypy.ini feat(server): add pgAdmin configuration and improve type hints 2024-10-10 12:04:18 +05:00
README.md feat(docker): multiple profiles 2024-10-29 20:50:41 +05:00

Freedium: Your paywall breakthrough for Medium!

Become a Patron

Stack:

  • Backend:
    • language: Python 3.9+
    • framework: Unicorn, FastAPI
  • Frontend:
    • framework: Tailwinds CSS v3, Jinja2
    • monitoring: Sentry
  • Database:
    • PostgreSQL, Dragonfly (Redis and Memcached compatible key-value database)
  • Utils:
    • Caddy, Docker, Docker Compose, Cloudflare WARP proxy (wgcf)

Project configuration:

There is three (3) docker-compose profiles:

  • min - without 2 Cluster of Cloudflare WARP proxy, HAProxy proxy balancer, Plausible, Grafana.
  • local - based on min, but with freedium.local exposed hostname, both 80 and 443 ports are exposed, with self-signed TLS certificate.
  • prod - with all services for production.

Requirements:

  • Docker, Docker Compose, last version is preferred.
  • Linux, preferably rolling release. We can't guarantee that Freedium instance will work on other OS. Tested on Ubuntu 22.04 and Fedora 39.
  • git
  • Preferably, fresh and clean brain.

Local run:

To configure your Freedium instance, follow these steps:

  1. Clone the repository:

    git clone https://codeberg.org/Freedium-cfd/web/ ./freedium-web --depth 1
    cd ./freedium-web
    
  2. Create and configure the environment file:

    cp .env_template .env
    

    Open the .env file and adjust the values as needed for your setup.

  3. (Optional) Set up the Docker network:

    sudo docker network create caddy_net
    
  4. Change your hosts file:

    sudo nano /etc/hosts
    # or
    vim /etc/hosts
    # and when you are closed vim, type `:w !sudo tee %` to save file without executing vim in root mode
    

    Add the following line:

    127.0.0.1 freedium.local
    
  5. Start the Freedium services (min profile):

    sudo docker compose --profile local -f ./docker-compose/docker-compose.yml up
    

    Stopping the services:

    sudo docker compose --profile local -f ./docker-compose/docker-compose.yml down
    

And now you can access local instance of Freedium by opening browser and type https://freedium.local. There is would be a warning about insecure connection, because we use self-signed TLS certificate. Ignore it.

Production run:

All production services are running on prod profile. If you use Dockerized reverse proxy, you can specify network caddy_freedium_net with external: true option in networks section of your reverse proxy container. Specify caddy_freedium hostname with port 6752 (or 6753 for Plausible) in your reverse proxy configuration.

As alternative, you can directly change docker-compose configurations to use your reverse proxy. See docker-compose and caddy folders for more details.

Architecture:

graph TB
    subgraph "Main Application"
        fw[freedium_web]
        cdy[caddy_freedium]
    end

    subgraph "Database Layer"
        rds[redis_service<br/>DragonFlyDB]
        pg[(postgres_freedium<br/>PostgreSQL)]
        pgadm[pgadmin4_freedium]
    end

    subgraph "Proxy Layer"
        hpb[haproxy-proxy-balancer]

        subgraph "WGCF Cluster 1"
            wg1[wgcf1]
            d1[dante_1]
            wh1[wgcf1_healthcare_service]
        end

        subgraph "WGCF Cluster 2"
            wg2[wgcf2]
            d2[dante_2]
            wh2[wgcf2_healthcare_service]
        end
    end

    subgraph "Analytics"
        pls[freedium_plausible]
        pldb[(plausible_db)]
        pledb[(plausible_events_db<br/>ClickHouse)]
    end

    subgraph "Utility"
        ah[autoheal]
    end

    %% Dependencies
    fw -->|depends_on| hpb
    d1 -->|depends_on| wg1
    d2 -->|depends_on| wg2
    wg2 -->|depends_on| wg1
    hpb -->|depends_on| wg1
    hpb -->|depends_on| wg2
    pls -->|depends_on| pldb
    pls -->|depends_on| pledb

    %% Network Connections
    subgraph "Networks"
        fn[freedium_net]
        cn[caddy_net]
        pn[plausible_net]
    end

    fw ---|freedium_net| fn
    cdy ---|freedium_net & caddy_net| fn
    rds ---|freedium_net| fn
    pg ---|freedium_net| fn
    pgadm ---|freedium_net| fn
    hpb ---|freedium_net| fn
    wg1 ---|freedium_net| fn
    wg2 ---|freedium_net| fn
    wh1 ---|freedium_net| fn
    wh2 ---|freedium_net| fn
    pls ---|all networks| fn

    %% Port Exposures
    cdy -->|":6752"| ext1[External Access]
    fw -->|":7080"| ext2[External Access]
    pgadm -->|":5433"| ext3[External Access]

    classDef service fill:#2ecc71,stroke:#27ae60,color:white
    classDef network fill:#3498db,stroke:#2980b9,color:white
    classDef database fill:#e74c3c,stroke:#c0392b,color:white
    classDef proxy fill:#f1c40f,stroke:#f39c12,color:black
    classDef utility fill:#9b59b6,stroke:#8e44ad,color:white
    classDef external fill:#95a5a6,stroke:#7f8c8d,color:white

    class fw,cdy,pls service
    class rds,pg,pldb,pledb database
    class hpb,wg1,wg2,d1,d2 proxy
    class ah,wh1,wh2 utility
    class fn,cn,pn network
    class ext1,ext2,ext3 external

TODO:

Roadmap

  • Speed up parser logic, port to Cython or rewrite to Golang
  • Make parse Medium format directly to Markdown, not HTML, in order to make it more universal. This helps to generate RSS feeds, PDF, HTML. OR we need write separate parser for different formats, like PDF, Markdown, etc.
  • Add more services than just a Medium
  • Rewrite frontend to Svelte
  • Move frontend to Cloudflare Pages
  • Integrate Grafana/Prometheus to monitor our services
  • Add more metrics to our services to have ability to monitor it
  • Make able translate posts to different languages using translatepy library