Skip to content

paulgit/whatsmyip

Repository files navigation

What’s My IP

A small Node.js/Express app that shows your public IP address in a clean web UI and via simple API endpoints. Optionally, it enriches the result with IPInfo data (location, ISP, and hostname).


What you get

  • Web UI: IP (and hostname when available), location, ISP, dark mode, copy-to-clipboard
  • API: HTML / JSON / Text formats + dedicated endpoints
  • Optional IPInfo enrichment: works without a token, but fewer details

Quick start (local)

1) Prerequisites

  • Node.js: use the latest stable Node (or at least Node 18+)
  • npm

2) Install & run

git clone https://github.com/paulgit/whatsmyip.git
cd whatsmyip
npm install
npm run dev

Then open:

3) (Optional) Enable IPInfo enrichment

Copy the template and add your IPInfo token:

cp .env.example .env

Edit .env and set:

IPINFO_TOKEN=your_token_here

Get a token:


Quick start (Docker)

Build and run (single container)

docker build -t whatsmyip .
docker run --rm -p 3000:3000 -e IPINFO_TOKEN=your_token_here whatsmyip

Open:

Platform note (smaller images)

If you want a smaller image and you’re building on Apple Silicon, build a single platform image:

docker build --platform linux/amd64 -t whatsmyip .

Docker Compose (production-like vs development)

This repo uses Option A:

  • docker-compose.yml is production-like (no bind mounts, NODE_ENV=production)
  • Development overrides should live in docker-compose.dev.yml (bind mounts, NODE_ENV=development, etc.)

Production-like run with Compose

From the project root:

docker compose up -d

If you need IPInfo enrichment, provide the env var:

IPINFO_TOKEN=your_token_here docker compose up -d

Development run with Compose overrides

Create a docker-compose.dev.yml (not included here) and run:

docker compose -f docker-compose.yml -f docker-compose.dev.yml up

Notes:

  • Avoid bind mounts in production; they override the built image and can cause drift.
  • In real production, prefer deploying a versioned image tag built in CI rather than building on the server.

How to use the API

Base URL below assumes local dev: http://localhost:3000

Web page (HTML)

  • GET /
  • GET /?format=html

JSON (IP + enrichment when available)

  • GET /?format=json

Example:

{
  "ip": "203.0.113.42",
  "hostname": "example.com",
  "city": "San Francisco",
  "region": "California",
  "country": "US",
  "org": "AS15169 Google LLC"
}

Plain text (IP only)

  • GET /?format=text

Example:

203.0.113.42

Dedicated endpoints

  • GET /api/ip{ "ip": "…" }
  • GET /api/info{ "ip": "…", "hostname": "…", ... } (plus IPInfo fields when available)
  • GET /health{ "status": "ok", "timestamp": "…" }

Testing without deploying

You do not need to deploy anywhere to test this.

1) Manual browser test

  1. Run npm run dev
  2. Visit http://localhost:3000
  3. Confirm:
    • IP appears
    • hostname shows below the IP when present
    • copy button copies the IP
    • dark mode looks correct

2) Validate endpoints with curl

Health:

curl -sS http://localhost:3000/health

IP only:

curl -sS http://localhost:3000/api/ip

Full info:

curl -sS http://localhost:3000/api/info

3) Simulate a real public IP locally

When testing on localhost you’ll often see ::1 or private addresses. You can simulate a public client IP by providing a forwarded header:

curl -sS -H "x-forwarded-for: 8.8.8.8" http://localhost:3000/api/info

This is helpful for confirming IPInfo hostname/location behavior without deploying behind a real proxy/CDN.


Configuration

Environment variables

Create .env (optional):

PORT=3000
IPINFO_TOKEN=your_token_here

Notes:

  • Without IPINFO_TOKEN, the service still runs and returns your IP, but enrichment may be missing.
  • IPInfo has a free tier; see https://ipinfo.io/

Project structure (high level)

whatsmyip/
├── server.js          # Express server + API endpoints
├── public/            # Static frontend
│   ├── index.html
│   ├── style.css
│   └── app.js
├── package.json
├── Dockerfile
├── docker-compose.yml
└── .env.example

Troubleshooting

“Geolocation data unavailable”

  • Set IPINFO_TOKEN in .env (or in Docker -e IPINFO_TOKEN=...)
  • Confirm the token is valid
  • Try simulating a public IP with x-forwarded-for as shown above

Port already in use

If 3000 is already taken:

  • set PORT=3001 in .env and restart
  • or stop the process using port 3000

Credits


License

MIT — see LICENSE.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors