{"id":21182813,"url":"https://github.com/seriousbug/ferrite-analytics","last_synced_at":"2025-10-07T04:50:22.201Z","repository":{"id":180574812,"uuid":"664388447","full_name":"SeriousBug/ferrite-analytics","owner":"SeriousBug","description":"Lightweight self-hostable analytics that respects users privacy","archived":false,"fork":false,"pushed_at":"2023-11-24T23:21:36.000Z","size":205,"stargazers_count":1,"open_issues_count":6,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-09T12:35:08.608Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SeriousBug.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-07-09T20:35:11.000Z","updated_at":"2023-12-30T21:04:14.000Z","dependencies_parsed_at":"2023-11-25T00:33:28.289Z","dependency_job_id":null,"html_url":"https://github.com/SeriousBug/ferrite-analytics","commit_stats":null,"previous_names":["seriousbug/basalytics"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/SeriousBug/ferrite-analytics","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeriousBug%2Fferrite-analytics","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeriousBug%2Fferrite-analytics/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeriousBug%2Fferrite-analytics/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeriousBug%2Fferrite-analytics/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SeriousBug","download_url":"https://codeload.github.com/SeriousBug/ferrite-analytics/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SeriousBug%2Fferrite-analytics/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278722767,"owners_count":26034461,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-20T17:58:11.821Z","updated_at":"2025-10-07T04:50:22.175Z","avatar_url":"https://github.com/SeriousBug.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ferrite Analytics\n\nThis is a service for tracking user events in a way that respects users' privacy.\n\n### What is Ferrite Analytics?\n\nFerrite Analytics tracks page visits and other events on websites like items on\npages being clicked, hovered over, or being scrolled into view. It also tracks\nuser sessions (limited to a single day). All of this is done without storing any\ncookies or other data on users devices, and without collecting any personally\nidentifiable information like IP addresses.\n\nThis tracking can be done either with a tracking pixel, which tracks views only,\nor a small tracking script that comes under 2KB uncompressed, which can be\nconfigured to track many things.\n\n### How does Ferrite Analytics respect privacy?\n\nTo respect users privacy, Ferrite Analytics doesn't save users IP addresses, or\neven full user agents. It only saves a summary of the user agent, like \"Windows,\nFirefox\", and a session hash.\n\nThe session hash is computed from the users IP address, user agent, the current\nday, along with a throwaway \"day code\" as salt. This was inspired by Plausible\nAnalytics, who discovered that the IP address and user agent are sufficient to\ntrack user sessions effectively. Adding the current day (like `2023-08-06`) to\nthis limits tracked sessions to a day, ensuring users are not tracked over a\nlong period of time. Finally the \"day code\" is a randomly generated code that is\nkept in memory and thrown away every day. This ensures that it is extremely\ndifficult, if not impossible, to reverse the hashing process by brute force as\nan attacker would not be able to guess the day code.\n\n### Can I use Ferrite Analytics?\n\nNot really. It's not ready for general use yet. While the tracking is\nfunctional, the dashboard is still in progress meaning you can't really view the\ncollected events or analyze them in any way. And configuring the tracker script\nrequires writing json by hand.\n\nIn the meantime, please consider some of these other open source projects:\n\n- [oxitraffic](https://codeberg.org/mo8it/oxitraffic) tracks page visits and\n  time spent only, it's simple but effective. Open source, self hosted.\n- [Plausible Analytics](https://plausible.io/) is a more comprehensive web\n  analytics tool. It's open source, with both managed service and self hosting\n  options available.\n\n### Do I need a cookie banner / GDPR consent banner with Ferrite Analytics?\n\nYes, you probably still do. If you read [the guidelines by the European Data Protection Board](https://edpb.europa.eu/our-work-tools/documents/public-consultations/2023/guidelines-22023-technical-scope-art-53-eprivacy_en), they explain that (abbreviated by me):\n\n\u003e ... [tracking] pixel or tracked URL [...] constitutes storage [...], at the very least through the caching mechanism of the client-side software. As such,\n\u003e Article 5(3) ePD is applicable ...\n\nIn other words: even if you don't store any cookies or unique identifiers, and\nyou don't access any personal or even identifiable information, you are still in\nviolation of the ePrivacy Directive if you don't ask for consent first. Because\nthe tracking script or pixel might be cached and that's technically \"information\nstored on the terminal equipment\" which can't be done without asking for consent\nfirst.\n\nThis is a very extreme reading of the ePrivacy directive in my opinion, and one\nthat relies on a technicality (i.e. if I configure `Cache-Control` headers so\nthe tracking pixel is not cached, is it okay then?). I also think this is not\nwhat the spirit of the law had intended. Yet, I'm not a lawyer and I'd have to\ntrust European Data Protection Board's view over my own.\n\n## Usage\n\nIf you do want to use Ferrite Analytics, the preferred way to deploy Ferrite\nAnalytics is using Docker. If you would like to avoid docker, binaries compiled\nfor different operating systems and architectures are available under the\n[Releases tab](https://github.com/SeriousBug/ferrite-analytics/releases). Docker\ncontainer images are available both on ghcr.io\n(`ghcr.io/seriousbug/ferrite-analytics`)and DockerHub\n(`seriousbug/ferrite-analytics`).\n\nTo run Ferrite Analytics, you will need to set the environment variable\n`DATABASE_URL` to a database. Available options are Sqlite and PostgresQL. For\nSqlite, use `DATABASE_URL=sqlite:/path/to/database.sqlite?mode=rwc`. PostgresQL\nis untested right now, so figure it out yourself! Ferrite Analytics will\nautomatically perform any required migrations when you launch it.\n\nIf you are running Ferrite Analytics behind a reverse proxy, you should also set\nthe `--forward-ip-header` parameter. This parameter should be set to the name of\na header that holds the original IP address. For example, if you have an nginx\nconfig such as:\n\n```\nlocation /ferrite/ {\n  proxy_pass http://localhost:3000/;\n  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n}\n```\n\nThen you should set the parameter to `X-Forwarded-For` like `--forward-ip-header X-Forwarded-For`.\n\nHere is a `docker-compose.yml` file that puts all of these together:\n\n```yml\nversion: \"3\"\nservices:\n  ferrite-analytics:\n    # Get container image from ghcr (Github)\n    image: ghcr.io/seriousbug/ferrite-analytics:latest\n    # Get the IP address from the `X-Forwarded-For` header. Only set this if Ferrite Analytics is behind a reverse proxy!\n    command: --forward-ip-header 'X-Forwarded-For'\n    restart: unless-stopped\n    # Put all the data in a named volume\n    volumes:\n      - ferrite-analytics-data:/data\n    environment:\n      - DATABASE_URL=sqlite:/data/ferrite.sqlite?mode=rwc\n    # Expose port 3000, where Ferrite Analytics' API is.\n    ports:\n      - 3000:3000\nvolumes:\n  ferrite-analytics-data:\n```\n\n## Developing\n\nMake sure you cloned the submodules, otherwise it will not build or run.\n\nMake sure you have `cargo` and `pnpm` installed.\n\nYou will first need to run `pnpm install \u0026\u0026 pnpm run` inside `tracker` to build the tracker script.\nThen, run `cargo run` inside `service` to build and run the service.\n\nTo make changes in any database entities, you will need to have `sea-orm-cli`\ninstalled. Add a new migration under `service/migration/src`, then run\n`sea-orm-cli migrate up` while inside `service` to migrate the database up. Then\nrun `sea-orm-cli generate entity -o src/entity` to update the generated entity\ncode. There is also a VSCode task to regenerate entities.\n\n## License\n\nAll code is freely available under GNU Affero General Public License v3.0.\nPlease see `LICENSE.txt` for details. The only exception to this is the tracker\nscript, located under the `tracker` folder. This script is designed to be\nembedded into websites and applications, and is licensed under MIT. Please see\nthe `LICENSE.txt` in that folder.\n\n**What this means for you:** You can deploy Ferrite Analytics for your own use, and add\nthe tracking script to your own website or application. There is nothing special\nyou need to do, you're free to use it however you want!\n\nHowever, if you provide Ferrite Analytics as a service for others, or you sell or\notherwise redistribute Ferrite Analytics, you are bound by the AGPLv3 license. You will\nneed to release the source code of Ferrite Analytics as it is used in your service or\nproduct, along with any modifications you made, and along with any other code\nthat links with Ferrite Analytics code, under GNU Affero General Public License v3.0.\nPlease see the license text for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseriousbug%2Fferrite-analytics","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseriousbug%2Fferrite-analytics","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseriousbug%2Fferrite-analytics/lists"}