> For the complete documentation index, see [llms.txt](https://docs.ipcheck.ing/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ipcheck.ing/developer/getting-started/maxmind-setup.md).

# MaxMind Setup (Required)

MyIP reads two free **GeoLite2** databases from MaxMind — `GeoLite2-City.mmdb` and `GeoLite2-ASN.mmdb` — for local, offline IP geolocation and ASN lookups.

They are **not** in the repository and **not** in the Docker image. MaxMind's GeoLite2 license does not allow redistribution, so every deployment has to bring its own copy.

## What breaks without them

The server still starts. But:

* `/api/maxmind` returns **503** on every request, so the MaxMind IP source produces nothing.
* Features built on that source — including the country badges shown for WebRTC ICE candidates — stay empty.
* Every boot logs `❌ MaxMind API will return 503 until databases are loaded successfully`.

Other IP sources keep working, so the app looks half-broken rather than broken. That is exactly why this page is required reading.

## Get credentials

{% stepper %}
{% step %}

#### Create a free GeoLite2 account

Sign up at [maxmind.com/en/geolite2/signup](https://www.maxmind.com/en/geolite2/signup). No payment details are required.
{% endstep %}

{% step %}

#### Note your account ID

MaxMind shows it in your account dashboard. It is a number, not your email address.
{% endstep %}

{% step %}

#### Generate a license key

Open **Manage License Keys** and create a new key. Copy it immediately — MaxMind shows it only once.
{% endstep %}
{% endstepper %}

## Option A — Automatic download (recommended)

Set three variables and let MyIP fetch and refresh the databases itself.

{% code title=".env" %}

```bash
MAXMIND_ACCOUNT_ID="your-account-id"
MAXMIND_LICENSE_KEY="your-license-key"
MAXMIND_AUTO_UPDATE="true"
```

{% endcode %}

In Docker, pass the same three with `-e` — see [Deploy with Docker](/developer/getting-started/deploy-with-docker.md).

What happens then:

| When                       | What happens                                                                                                                                                                      |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| At startup, files missing  | The backend downloads both databases **before it starts listening**, capped at 5 minutes. This runs whenever credentials are present, even if `MAXMIND_AUTO_UPDATE` is `"false"`. |
| At startup, files present  | Nothing is downloaded; the existing files are loaded straight away.                                                                                                               |
| \~60 seconds after startup | The updater runs its first scheduled check.                                                                                                                                       |
| Every 24 hours after that  | It checks again and downloads only what MaxMind has actually updated.                                                                                                             |

{% hint style="success" %}
**Updates are safe by construction.** New files are downloaded to a temp directory, opened and validated, then published atomically with a `.bak` fallback. A file watcher reloads the in-memory readers afterwards, so a database refresh never restarts the server and never serves a half-written file. A lock file prevents two processes (for example two pm2 instances) from updating at once.
{% endhint %}

{% hint style="warning" %}
**Docker deployers must use Option A.** A fresh container has no `.mmdb` files at all, and there is nothing to copy them into unless you build your own image.
{% endhint %}

## Option B — Manual placement

For air-gapped hosts, or if you would rather not give the app outbound access to MaxMind. This only works when you [deploy from source](/developer/getting-started/deploy-with-nodejs.md).

{% stepper %}
{% step %}

#### Download the databases

From your MaxMind account, download the **GeoLite2 City** and **GeoLite2 ASN** archives in `.mmdb` (binary) form and extract them.
{% endstep %}

{% step %}

#### Put them in place

Copy both files into `common/maxmind-db/`, keeping their exact names:

```
common/maxmind-db/GeoLite2-City.mmdb
common/maxmind-db/GeoLite2-ASN.mmdb
```

{% endstep %}

{% step %}

#### Leave auto-update off

```bash
MAXMIND_AUTO_UPDATE="false"
```

Then start the backend. It finds the files and loads them.
{% endstep %}
{% endstepper %}

{% hint style="info" %}
With Option B you refresh the files yourself as MaxMind publishes new releases. You do not need to restart the server after replacing them — the file watcher notices the change and reloads the readers within a few seconds.
{% endhint %}

## Verifying

A healthy startup logs:

```
📦 MaxMind databases loaded (startup)
```

With auto-update on, you also get the schedule:

```
🗓️  MaxMind auto update plan: next check at ..., then every 24 hours
```

## Troubleshooting

<details>

<summary>❌ MaxMind API will return 503 until databases are loaded successfully</summary>

The backend could not open both `.mmdb` files. Scroll up in the log — there is always a more specific line above this one telling you why. Common causes:

* The credentials are missing, so nothing was ever downloaded.
* The download failed (see the entries below).
* Only one of the two files is present. MyIP needs **both** City and ASN.

</details>

<details>

<summary>⚠️ MaxMind databases are missing and MAXMIND_ACCOUNT_ID / MAXMIND_LICENSE_KEY are not configured</summary>

The variables never reached the process. Check that:

* Your `.env` sits in the project root and you restarted after editing it.
* In Docker, the `-e` flags are on the `docker run` command (or in the `environment:` block) — not on `docker exec`.
* Variable names are spelled exactly as above.

</details>

<details>

<summary>Failed to check GeoLite2-City: HTTP 401</summary>

MaxMind rejected the credentials. The account ID and license key are used as HTTP Basic auth against `download.maxmind.com`, so a 401 means one of them is wrong.

* Confirm the account ID is the numeric ID, not your email.
* Regenerate the license key — keys can be revoked, and a copy/paste that dropped a character looks identical to a valid key.
* Make sure the key was created for **GeoLite2**, under the same account.

</details>

<details>

<summary>MaxMind initial download failed: download did not complete within 5 min</summary>

The startup download hit its time cap. This is a network problem, not a credential problem — check that the host can reach `download.maxmind.com` (firewall, egress rules, proxy). The server starts anyway and the scheduled updater will try again.

</details>

<details>

<summary>MaxMind auto update plan: disabled</summary>

`MAXMIND_AUTO_UPDATE` is not exactly `"true"`. Only that literal value enables the periodic refresh.

Note this affects the **24-hour refresh** only. The startup download still runs when the files are missing and credentials are present.

</details>

<details>

<summary>MaxMind auto update skipped: MAXMIND_ACCOUNT_ID or MAXMIND_LICENSE_KEY is missing</summary>

Auto-update was requested but one of the two credentials is empty. Both are required.

</details>

<details>

<summary>MaxMind update skipped: another process is updating databases</summary>

Expected when you run several backend instances — one holds the update lock, the others step aside. Harmless.

If you see it on every attempt, a previous run probably crashed and left the lock behind. It is cleared automatically once it is 2 hours old; to clear it now, delete `.maxmind-update.lock` from `common/maxmind-db/`.

</details>

## Next steps

* [Deploy with Docker](/developer/getting-started/deploy-with-docker.md) — where the databases live inside the container
* [Optional API Keys](/developer/configuration/optional-api-keys.md) — additional IP data sources beyond MaxMind
* [IP Data Sources](/developer/architecture/ip-data-sources.md) — how MyIP combines its sources


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.ipcheck.ing/developer/getting-started/maxmind-setup.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
