Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
7a77a00
Improvements
jason5ng32 Jul 18, 2026
dcc2a3b
Fix(ui): align MAC input validation with backend (exactly 12 hex digits)
jason5ng32 Jul 19, 2026
0ccd23f
UI Improvement
jason5ng32 Jul 20, 2026
75a8ed3
Improvements
jason5ng32 Jul 20, 2026
d5146c8
Improvements
jason5ng32 Jul 21, 2026
6926045
Improvements
jason5ng32 Jul 21, 2026
bb600bb
Fix(ui): stop Safari page jump when closing the advanced tools drawer
jason5ng32 Jul 22, 2026
34f54b7
Improvements
jason5ng32 Jul 24, 2026
9117aa4
Add Checkbox
jason5ng32 Jul 24, 2026
b054d62
Feat(api): serve 30-day per-country blocking data from OONI aggregates
jason5ng32 Jul 24, 2026
66d4a1f
Feat(ui): rebuild Censorship Check around OONI history + picked realt…
jason5ng32 Jul 24, 2026
ab7cc4a
Chore: bump version to 7.2.0 and fill changelog in all locales
jason5ng32 Jul 24, 2026
e5ed9be
Improvements
jason5ng32 Jul 24, 2026
44f9194
Improvements
jason5ng32 Jul 24, 2026
1c78b19
Improvements
jason5ng32 Jul 24, 2026
8ec84cf
Improvements
jason5ng32 Jul 25, 2026
d3c1c21
Remove Empty
jason5ng32 Jul 25, 2026
4b6e0aa
Feat(api): serve a compact Globalping probe-country inventory
jason5ng32 Jul 25, 2026
b2c22a9
Feat(ui): shared Globalping country picker for MTR / latency / censor…
jason5ng32 Jul 25, 2026
7889786
Style(i18n): credit GlobalPing in test copy and land picker keys
jason5ng32 Jul 25, 2026
007d81c
Improvements
jason5ng32 Jul 25, 2026
d01fa5a
Improvements
jason5ng32 Jul 26, 2026
ac3dc20
Docs(readme): slim deployment sections, point to docs.ipcheck.ing
jason5ng32 Jul 28, 2026
25b47cf
Feat(nav): in-app docs assistant via GitBook embed
jason5ng32 Jul 28, 2026
89e8446
Feat(ui): Help Center link in the footer
jason5ng32 Jul 28, 2026
d403f8f
Feat(nav): let the docs assistant read the visitor's own test results
jason5ng32 Jul 28, 2026
528719b
Docs(privacy): document the docs assistant's data flow
jason5ng32 Jul 28, 2026
971e592
Docs(changelog): v7.2.0 — AI assistant and the documentation site
jason5ng32 Jul 28, 2026
95d8ac6
Style(nav): match the docs launcher to the FAB buttons
jason5ng32 Jul 28, 2026
5cc7193
Chore(ui): credit GitBook in the acknowledgements
jason5ng32 Jul 28, 2026
af59d93
Improvements
jason5ng32 Jul 28, 2026
ed83d8e
Improvements
jason5ng32 Jul 28, 2026
37f2e00
Improvements
jason5ng32 Jul 28, 2026
26bd8bd
Merge pull request #360 from jason5ng32/dev
jason5ng32 Jul 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ MAXMIND_AUTO_UPDATE="false"
CAIDA_AUTO_UPDATE="false"
# SITE
VITE_SITE_URL="https://ipcheck.ing"
# DOCS SITE — origin of the GitBook docs site powering the in-app
# assistant and the Help Center link. Empty disables both.
VITE_DOCS_URL=""
# CURL API
VITE_CURL_IPV4_DOMAIN=""
VITE_CURL_IPV6_DOMAIN=""
Expand Down
106 changes: 15 additions & 91 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,111 +92,33 @@ Click the 'Deploy to Docker' button at the top to complete the deployment. Or, u
docker run -d -p 18966:18966 --name myip --restart always jason5ng32/myip:latest
```

## 📚 Environment Variable

Variables marked **Yes** below must be set for the backend to function correctly. The MaxMind credentials in particular are required — read the setup notes in the next subsection before filling in the table.

### MaxMind Databases (Required)

MyIP relies on the free **GeoLite2** databases from MaxMind (City + ASN) for IP geolocation, ASN / organization lookup, and the country-code badges that appear throughout the app (IP cards, WebRTC ICE candidates, and more). A working MaxMind setup is required for the backend to serve a complete experience.

The `.mmdb` files are **not checked into this repository** because MaxMind's GeoLite2 license does not allow redistribution. You need to provide them yourself. There are two paths:

**Option A — Automatic (recommended, required for Docker)**

1. Create a free account at [maxmind.com/en/geolite2/signup](https://www.maxmind.com/en/geolite2/signup).
2. Generate a license key from your account's "Manage License Keys" page.
3. Set these three environment variables:
```bash
MAXMIND_ACCOUNT_ID="your-account-id"
MAXMIND_LICENSE_KEY="your-license-key"
MAXMIND_AUTO_UPDATE="true"
```
4. Start the backend. Within about 60 seconds of the first startup, the updater will download both databases. They are then refreshed every 24 hours automatically.

> ⚠️ **Docker deployers must use Option A.** A fresh container ships with an empty `common/maxmind-db/` directory — without the three variables above the backend starts, but the MaxMind-powered IP source and WebRTC country badges will not work, and you'll see `MaxMind API will return 503...` in the logs on every boot.

**Option B — Manual (for air-gapped or non-Docker setups)**

Download `GeoLite2-City.mmdb` and `GeoLite2-ASN.mmdb` from your MaxMind account and drop them into `common/maxmind-db/` before starting the backend. With this approach `MAXMIND_AUTO_UPDATE` can stay `"false"`, but you'll need to refresh the files manually as MaxMind publishes new versions.

### Environment variables list

| Variable Name | Required | Default Value | Description |
| --- | --- | --- | --- |
| `MAXMIND_ACCOUNT_ID` | **Yes** | `""` | MaxMind account ID, paired with `MAXMIND_LICENSE_KEY` to download GeoLite2 databases. See the MaxMind section above. |
| `MAXMIND_LICENSE_KEY` | **Yes** | `""` | MaxMind license key, paired with `MAXMIND_ACCOUNT_ID`. See the MaxMind section above. |
| `MAXMIND_AUTO_UPDATE` | **Yes** | `"false"` | Set to `"true"` to auto-download GeoLite2 databases ~60s after startup and refresh every 24h. **Required for Docker.** Can stay `"false"` only if you've pre-seeded the `.mmdb` files manually. |
| `CAIDA_AUTO_UPDATE` | No | `"false"` | Set to `"true"` to refresh the CAIDA datasets daily (as2org for ASN org-name lookup, as-rel2 for the ASN connectivity graph). When `"false"`, missing snapshots are still downloaded at startup but never refreshed afterwards. |
| `VITE_GOOGLE_ANALYTICS_ID` | **Yes** | `""` | Google Analytics ID, used to track user behavior |
| `BACKEND_PORT` | No | `"11966"` | The running port of the backend part of the program |
| `FRONTEND_PORT` | No | `"18966"` | The running port of the frontend part of the program |
| `SECURITY_RATE_LIMIT` | No | `"0"` | Controls the number of requests an IP can make to the backend server every 60 minutes (set to 0 for no limit) |
| `SECURITY_DELAY_AFTER` | No | `"0"` | Controls the first X requests from an IP every 20 minutes that are not subject to speed limits, and after X requests, the delay will increase |
| `SECURITY_BLACKLIST_LOG_FILE_PATH` | No | `""` | Opt-in on-disk ledger of rate-limited IPs (e.g. `"logs/blacklist-ip.log"`). Empty = no file is written; the event is always logged via the shared logger either way |
| `LOG_LEVEL` | No | `"info"` | Minimum log level (`debug` / `info` / `warn` / `error`). Lower-level messages are suppressed. |
| `LOG_FORMAT` | No | pretty | Set to `"json"` to emit one JSON event per line (for log aggregators / jq). Any other value (or unset) keeps the colored pretty output used in dev and pm2 log tails. |
| `LOG_HTTP` | No | `"false"` | Set to `"true"` to enable per-request HTTP logging on `/api/*` (method, URL, status, response time). Off by default to keep pm2 logs lean. Handler-level 4xx/5xx errors are always logged regardless of this flag. |
| `VITE_SENTRY_DSN_FRONTEND` | No | `""` | Sentry DSN for the frontend (build-time). When empty, no Sentry code is included in the bundle at all. Also read by the backend at runtime as the allowlist for `/api/monitoring`, the first-party tunnel that relays Sentry envelopes past ad blockers. If you bake it into a self-built Docker image at build time, pass the same value to the container at runtime too — otherwise the tunnel route stays disabled |
| `SENTRY_DSN_BACKEND` | No | `""` | Sentry DSN for the backend (runtime). When empty, the Sentry SDK is never loaded |
| `SENTRY_ENVIRONMENT` | No | `"production"` | Environment tag on backend Sentry events. Set to `"development"` on dev machines; the frontend tags itself automatically |
| `SENTRY_ORG` | No | `""` | Sentry organization slug, used with `SENTRY_PROJECT_FRONTEND` and `SENTRY_AUTH_TOKEN` to upload source maps at build time |
| `SENTRY_PROJECT_FRONTEND` | No | `""` | Sentry project slug of the frontend project, for build-time source map upload |
| `SENTRY_AUTH_TOKEN` | No | `""` | Sentry auth token enabling source map upload at build time. Build-time secret only — never exposed to the browser |
| `ALLOWED_DOMAINS` | No | `""` | Allowed domains for access, separated by commas, used to prevent misuse of the backend API |
| `GOOGLE_MAP_API_KEY` | No | `""` | API Key for Google Maps, used to display the location of the IP on a map |
| `IPINFO_API_KEY` | No | `""` | API Token for IPInfo.io, used to obtain IP geolocation information through IPInfo.io |
| `IPAPIIS_API_KEY` | No | `""` | API Key for IPAPI.is, used to obtain IP geolocation information through IPAPI.is |
| `IP2LOCATION_API_KEY` | No | `""` | API Key for IP2Location.io, used to obtain IP geolocation information through IP2Location.io |
| `CLOUDFLARE_API_KEY` | No | `""` | API Key for Cloudflare, used to obtain AS system information; with the two KV variables below (and the "Workers KV Storage: Edit" token permission) it also powers shareable diagnostic reports |
| `CLOUDFLARE_ACCOUNT_ID` | No | `""` | Cloudflare account ID, required for storing shareable diagnostic reports in Workers KV |
| `CLOUDFLARE_KV_NAMESPACE_ID` | No | `""` | Hex ID (not the name) of the Workers KV namespace that stores shareable diagnostic reports |
| `RIPESTAT_SOURCE_APP` | No | `""` | Source app name for RIPE.net, used to obtain ASN history information through RIPE.net |
| `MAC_LOOKUP_API_KEY` | No | `""` | API Key for MAC Lookup, used to obtain MAC address information |
| `VITE_CURL_IPV4_DOMAIN` | No | `""` | Provides the IPv4 domain for the CURL API to users |
| `VITE_CURL_IPV6_DOMAIN` | No | `""` | Provides the IPv6 domain for the CURL API to users |
| `VITE_CURL_IPV64_DOMAIN` | No | `""` | Provides the dual-stack domain for the CURL API to users |

Note that if any of the CURL series environment variables are missing, the CURL API will not be enabled.

### Using Environment Variables in a Node Environment

Create environment variables:
## 📖 Documentation

```bash
cp .env.example .env
```

Modify `.env`, and for example, add the following:
Full guides live in the MyIP Docs Center: **[docs.ipcheck.ing](https://docs.ipcheck.ing)**

```bash
BACKEND_PORT=11966
FRONTEND_PORT=18966
MAXMIND_ACCOUNT_ID="YOUR_ACCOUNT_ID"
MAXMIND_LICENSE_KEY="YOUR_LICENSE_KEY"
MAXMIND_AUTO_UPDATE="true"
GOOGLE_MAP_API_KEY="YOUR_KEY_HERE"
ALLOWED_DOMAINS="example.com,example.org"
```
* [Developer Guide](https://docs.ipcheck.ing/developer) — deployment, configuration, architecture, and contributing
* [Knowledge Base](https://docs.ipcheck.ing/knowledge-base) — how to use every tool, step-by-step network diagnosis, and networking concepts

Then restart the backend service.
## ⚙️ Configuration

### Using Environment Variables in Docker
Two settings matter before anything else:

You can add environment variables when running Docker, for example:
* **MaxMind GeoLite2 (required)** — free credentials that power IP geolocation and ASN lookups. Without them, the MaxMind source returns 503. → [MaxMind Setup](https://docs.ipcheck.ing/developer/getting-started/maxmind-setup)
* **`ALLOWED_DOMAINS` (required on a real domain)** — hostname allowlist for the backend API. Without it, every request from a non-localhost domain gets 403. → [Reverse Proxy & Domains](https://docs.ipcheck.ing/developer/getting-started/reverse-proxy-and-domains)

```bash
docker run -d -p 18966:18966 \
-e MAXMIND_ACCOUNT_ID="YOUR_ACCOUNT_ID" \
-e MAXMIND_LICENSE_KEY="YOUR_LICENSE_KEY" \
-e MAXMIND_AUTO_UPDATE="true" \
-e GOOGLE_MAP_API_KEY="YOUR_KEY_HERE" \
-e ALLOWED_DOMAINS="example.com,example.org" \
--name myip \
-e ALLOWED_DOMAINS="your-domain.com" \
--name myip --restart always \
jason5ng32/myip:latest

```

Everything else — optional API keys, security & rate limiting, logging, Sentry, the curl API domains — is documented in the [Environment Variables reference](https://docs.ipcheck.ing/developer/reference/environment-variables).


## 👩🏻‍💻 Advanced Usage

If you're using a proxy for internet access, consider adding this rule to your proxy configuration (modify it according to your client). This setup lets you check both your real IP and the IP when using the proxy:
Expand Down Expand Up @@ -230,4 +152,6 @@ As a open source project, I'm very grateful to the following sponsors for their

<a href="https://www.sentry.io"><img src="https://res.ipcheck.ing/img/sentry_logo.png" alt="Sentry" title="Sentry" width="240px" /></a>

<a href="https://www.gitbook.com"><img src="https://res.ipcheck.ing/img/gitbook_logo.png" alt="GitBook" title="GitBook" width="240px" /></a>

<a href="https://www.cloudflare.com/lp/project-alexandria/"><img src="https://res.ipcheck.ing/img/cloudflare_logo.png" alt="Cloudflare Project Alexandria" title="Cloudflare Project Alexandria" width="240px" /></a>
Loading
Loading