Self-hosted service
milesmcc/shynet avatar
milesmcc/shynet

Shynet: cookie-free web analytics you host yourself

Modern, privacy-friendly, and detailed web analytics that works without cookies or JS.

3,157 stars210 forksPythonApache-2.0

At a glance

What is it?
Shynet is a self-hosted Django analytics server that tracks page views without cookies and falls back to a 1x1 pixel when JavaScript is unavailable. It fits small and medium sites, and it asks for real deployment work in return.
Who is it for?
Adopt Shynet if you run a personal project or a small to medium site, you are comfortable with Docker and Django, and you want visitor data to stay on your own machine. Do not adopt it if you need one-click setup, a hosted dashboard, or analytics for very high traffic: the README states the project has not been tested at that scale.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The problem Shynet targets: analytics without a third party or a cookie banner

Most hosted analytics products require sending visitor data to another company, and many of them rely on cookies to link visits across sessions. Cookies are what trigger the consent notices that sit on top of a page before anyone has read it. Shynet takes the opposite position on both points. You run the server, so the records stay on infrastructure you control, and the tracking mechanism is designed so that no cookie is set. The README frames the motivation bluntly: existing tools hand visitor information to a third party, use cookies, collect more personal data than the job requires, or are closed and expensive. Shynet claims none of those caveats.

The audience is narrow on purpose. The README's Recommendations section says Shynet is great for personal projects and small to medium websites, has not been tested with ultra-high traffic sites, and requires a fair amount of technical know-how to deploy and maintain. If you want a one-click product, the README says you are better served elsewhere. That is an honest boundary, and it should shape the decision more than any feature list.

How Shynet tracks and stores a visit

The unit of work is a service, which corresponds to a website or a single top-level domain. Shynet generates one tracking embed per service, and you paste that embed into your pages. When a page loads, the embed reports back. If JavaScript is available, the tracking script handles it; that script is under a kilobyte according to the README and does not resemble a typical tracking script. If JavaScript is not available, Shynet falls back to a 1x1 transparent tracking pixel. That fallback is the reason the project carries a noscript topic: a visitor with scripting disabled still produces a hit.

A hit is a single page load. Sessions are collections of hits made by the same browser in a short period, and the README notes a session can also be a single hit. From those two primitives Shynet derives hits, sessions, page load time, bounce rate, duration, referrers, page popularity, operating system, browser, geographic location and network, and device type. User agent parsing supplies the OS, browser and device fields; IP address supplies the geographic and network fields, which is why the Docker image bundles GeoLite2 databases. The README also documents a primary-key integration: you can associate a Shynet visitor with a user account on your own site, which is optional and changes the privacy posture of the data you keep.

On the server side the stack is Django with Celery for background work, PostgreSQL for storage, and Redis for caching. The docker-compose.yml in the repository shows three services: the Shynet application on port 8080, a Postgres container, and an nginx container that listens on host port 8080 and proxies inward. For larger installations the README describes a different shape: parallelized ingress nodes with Redis caching and separate backend workers for database IO, deployed on Kubernetes, and the repository carries a kubernetes directory for that path.

Installing Shynet with docker-compose and registering a first service

The README does not repeat installation steps. It points to GUIDE.md, and states that the project supports Docker, docker-compose, Heroku and Kubernetes out of the box. The repository itself carries docker-compose.yml, Dockerfile, nginx.conf, TEMPLATE.env, heroku.yml and app.json, so the compose path is the one you can read directly from the files.

Start by creating the environment file that the compose definition expects. The compose file loads .env through env_file and tells you to use TEMPLATE.env as a guide. The database container reads DB_USER, DB_PASSWORD and DB_NAME from that file, and the application container is given DB_HOST=db.

bash
cp TEMPLATE.env .env
# edit .env: set DB_USER, DB_PASSWORD, DB_NAME and the Django settings TEMPLATE.env lists

Then bring the stack up. The compose file exposes the application on port 8080 internally and publishes host port 8080 through the nginx container.

bash
docker compose up -d

After the containers start you should be able to reach the Shynet interface on http://localhost:8080. The first account you create becomes the administrator, and from the management view you create a service for the site you want to track. Shynet then generates the tracking embed for that service; you copy it into your pages. If you prefer the published image over a local build, the compose file references milesmcc/shynet:latest, so docker compose pull followed by docker compose up -d uses that image. For anything beyond a single machine, the README directs you to the kubernetes directory instead of this compose file.

Where Shynet stops being the right tool

The most important limitation is stated by the project itself: Shynet has not been tested with ultra-high traffic sites. The README's answer to scale is architectural, not a promise of performance. You add parallelized ingress nodes, Redis caching and separate backend workers, which means the single-container story stops applying exactly when traffic grows. Anyone planning a launch with unpredictable spikes should treat the compose file as a starting point rather than a production guarantee.

The second limitation is operational. Deployment and maintenance require technical know-how by the README's own admission, and the moving parts are real: Django, PostgreSQL, Redis, Celery, nginx, and a GeoIP database baked into the image. There is no hosted fallback if your VPS goes down.

The third limitation concerns the data model rather than the software. Shynet avoids cookies, but it still parses user agents and IP addresses to produce device, browser and location fields, and the primary-key integration exists precisely so you can tie a visitor to a known account. Whether that combination is acceptable depends on your jurisdiction and your own collection practices. The README's FAQ says GDPR compliance depends on how you use it and directs you to a lawyer; it explicitly states the author is not one. If your requirement is a legally reviewed, out-of-the-box compliance posture, this project does not supply it.

Finally, the roadmap is a list of intentions, not shipped behaviour. It mentions data aggregation through rollups, anomaly detection, detailed data exports, two-factor authentication, and a data deletion tool. Until those land, do not plan around them.

Shynet compared with GoatCounter and other self-hosted analytics

GoatCounter is the closest comparison for a self-hosted, privacy-oriented analytics tool, and it appears in the search terms people use alongside Shynet. The approaches differ in stack and deployment shape. Shynet is a Django application with PostgreSQL, Celery and Redis, and its docker-compose file runs three containers behind nginx. That is a familiar shape if you already operate Django services, and it is heavier than a single binary if you do not. GoatCounter is written in Go and is commonly deployed as a single server process, which changes what you have to keep patched and backed up.

The tracking paths also differ in emphasis. Shynet's README highlights the JavaScript-free fallback: a 1x1 transparent pixel for visitors without scripting. If your audience includes people who browse with JavaScript disabled or through text-oriented clients, that fallback matters, and it is the reason the project lists noscript among its topics. If your audience is entirely scripted, the distinction is smaller.

Both projects share the same fundamental trade: you own the data, and you own the uptime, the upgrades and the backups. Neither is a hosted service, and neither removes the need to think about what you are storing.

Maintenance, upgrades and the Apache-2.0 licence

The repository is not archived, and the last push was on 2026-03-15, which is also the date of the v0.14.0 release. The release before that, v0.13.1, is dated 2023-07-28, and v0.13.0 is dated 2023-07-17. The gap between those two points is the practical upgrade risk: fixes can arrive after a long quiet period, and a jump from an older release can carry dependency work with it. The v0.14.0 notes describe it as security and dependency updates, and v0.13.1 was released to fix Cython and crypto build issues. Dependency churn, not feature churn, is the pattern here.

Because the project ships as a Docker image and a compose file, the routine upgrade is pulling a newer image and restarting the stack, then applying Django migrations. The repository does not document a rollback procedure, so if you upgrade in place you should have a database dump before you start. The Postgres data lives in the named volume shynet_db in the compose file, which is what you would back up and restore.

The licence is Apache-2.0, declared in both LICENSE and pyproject.toml. That permits commercial use and modification with the usual conditions around notices and patent grants. It is not legal advice, and if you redistribute a modified Shynet you should read the licence text rather than this summary. One detail worth knowing: the Dockerfile embeds a MaxMind licence key for downloading the public GeoLite2 databases, and the comments explain that the key is intentionally public and limited to those public datasets. If you build your own image, that arrangement is part of what you inherit.

Editorial conclusion

Adopt Shynet if you run a personal project or a small to medium site, you are comfortable with Docker and Django, and you want visitor data to stay on your own machine. Do not adopt it if you need one-click setup, a hosted dashboard, or analytics for very high traffic: the README states the project has not been tested at that scale. Before committing, verify three things: that your .env values match the keys in TEMPLATE.env, that the nginx.conf volume path resolves on your host, and that your chosen deployment target is covered by the options listed in GUIDE.md, since the README points there for installation rather than repeating the steps.

Frequently asked questions

Does Shynet need cookies or JavaScript to track visitors?

Shynet does not use cookies, and JavaScript is not required. The README states that it falls back to a 1x1 transparent tracking pixel when JavaScript is not available.

How do I install Shynet on my own server?

The README points to GUIDE.md for installation and says Docker, docker-compose, Heroku and Kubernetes are supported out of the box. The repository's docker-compose.yml runs the Shynet application, a Postgres database and an nginx container, with configuration read from a .env file based on TEMPLATE.env.

Does Shynet respect Do Not Track signals?

Yes. The README's FAQ says you can choose per service whether to collect any data from users with DNT enabled, and that by default Shynet will not collect data from those users.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. milesmcc/shynet on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/milesmcc-shynet.svg)](https://hysenlabs.com/projects/milesmcc-shynet)