Skip to content

moshe19909090/ip-resolver

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

2 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

IP Resolver

A Dockerized full-stack web application that displays the current host's public and internal IP addresses, resolves domain names to IP addresses, and maintains a visible history of resolved domains.

πŸ—οΈ Architecture

High-Level Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         HTTP/REST API         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Frontend  β”‚ ────────────────────────────> β”‚   Backend   β”‚
β”‚  (React +   β”‚                               β”‚ (Express +  β”‚
β”‚ TypeScript) β”‚ <──────────────────────────── β”‚  Node.js)   β”‚
β”‚             β”‚                               β”‚             β”‚
β”‚ Port: 3000  β”‚                               β”‚ Port: 4000  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                               β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
       β”‚                                              β”‚
       β”‚                                              β”‚
       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    Docker Network

Communication Flow

  1. Frontend β†’ Backend: The frontend makes REST API calls to the backend
  2. API Proxy: In Docker, nginx (frontend container) proxies /api/* requests to the backend service
  3. Backend Services:
    • Fetches public IP from external service (ipify.org)
    • Resolves internal IP from system network interfaces
    • Performs DNS resolution using Node.js dns module

Technology Stack

  • Frontend: React 18 + TypeScript + Vite + SCSS
  • Backend: Node.js 20 + Express + TypeScript
  • Containerization: Docker + Docker Compose
  • Web Server: Nginx (for serving frontend and proxying API requests)
  • Package Manager: npm

πŸ“‘ API Endpoints

GET /api/ip

Returns the current host's public and internal IP addresses.

Response:

{
  "publicIp": "x.x.x.x",
  "internalIp": "x.x.x.x"
}

Implementation Notes:

  • Public IP is fetched from https://api.ipify.org
  • Internal IP is resolved from system network interfaces (first non-loopback IPv4)

POST /api/resolve

Resolves a domain name to an IP address.

Request Body:

{
  "domain": "example.com"
}

Response:

{
  "domain": "example.com",
  "ip": "x.x.x.x"
}

Error Responses:

  • 400 Bad Request: Invalid or missing domain
  • 500 Internal Server Error: DNS resolution failed

Implementation Notes:

  • Validates domain format (basic regex check)
  • Uses Node.js dns.lookup() for resolution
  • Returns IPv4 addresses only

GET /health

Health check endpoint for Docker health checks.

Response:

{
  "status": "ok"
}

πŸš€ Installation & Usage

Prerequisites

  • Docker and Docker Compose installed
  • Node.js 20+ (for local development)

Running with Docker Compose (Recommended)

  1. Clone the repository:
git clone <repository-url>
cd ip-resolver
  1. Build and start all services:
docker compose up --build
  1. Access the application:
  1. Stop the services:
docker compose down

Local Development

Backend

  1. Navigate to backend directory:
cd backend
  1. Install dependencies:
npm install
  1. Run in development mode:
npm run dev

The backend will run on http://localhost:4000

Frontend

  1. Navigate to frontend directory:
cd frontend
  1. Install dependencies:
npm install
  1. Run in development mode:
npm run dev

The frontend will run on http://localhost:3000 (Vite dev server proxies /api to backend)

πŸ§ͺ Testing & Building

Backend

cd backend

# Type check
npm run typecheck

# Build
npm run build

# Run production build
npm start

Frontend

cd frontend

# Type check
npm run typecheck

# Build for production
npm run build

# Preview production build
npm run preview

πŸ”„ CI/CD Pipeline

GitHub Actions

The CI pipeline (.github/workflows/ci.yml) runs on every push and pull request:

  1. Backend Job:

    • Installs dependencies
    • Runs TypeScript type checking
    • (Optional) Runs tests if present
  2. Frontend Job:

    • Installs dependencies
    • Runs TypeScript type checking
    • Builds production assets
  3. Docker Build Job:

    • Builds backend Docker image
    • Builds frontend Docker image
    • Validates docker-compose.yml syntax

Why these checks?

  • Type checking catches errors before runtime
  • Building validates that code compiles correctly
  • Docker builds ensure containers can be created successfully

GitLab CI

Equivalent pipeline (.gitlab-ci.yml) with stages:

  • install: Install dependencies
  • test: Type checking
  • build: Build frontend assets
  • docker-build: Build Docker images

🎨 Design Decisions

Frontend

  1. State Management: Using React hooks (useState, useEffect) - simple and sufficient for this application. No need for Redux or Context API.

  2. History Duplicates: Duplicate domains are allowed in history. Each resolution creates a new entry with a timestamp. This allows tracking if a domain's IP changes over time.

  3. Loading States: Separate loading states for IP fetch and domain resolution provide better UX feedback.

  4. Error Handling: User-friendly error messages displayed inline with clear styling, via a reusable ErrorMessage component.

  5. Styling: Custom SCSS (no heavy UI frameworks) with shared variables, component-scoped styles, and a responsive, mobile-friendly layout.

  6. Componentization: UI split into focused components (Header, IpAddresses, DomainResolver, HistoryList, HistoryItem, Spinner, ErrorMessage) to keep concerns separated and the App component thin.

Backend

  1. Public IP Service: Using ipify.org - simple, reliable, no authentication required. Alternative services could be used (ip-api.com, icanhazip.com).

  2. Internal IP Resolution: Uses Node.js os.networkInterfaces() to find the first non-loopback IPv4 address. This typically returns the primary network interface's IP.

  3. DNS Resolution: Using Node.js dns.lookup() which respects system DNS configuration and /etc/hosts file.

  4. Error Handling: Clear error messages with appropriate HTTP status codes (400 for client errors, 500 for server errors).

  5. CORS: Enabled for all origins (suitable for development). In production, restrict to specific domains.

Docker

  1. Multi-stage Builds: Both frontend and backend use multi-stage Dockerfiles to minimize image size.

  2. Nginx Proxy: Frontend nginx configuration proxies /api requests to backend service. This allows the frontend to make relative API calls (no hard-coded API base URL in the built assets).

  3. Health Checks: Backend includes a health check endpoint for Docker health monitoring.

  4. Network Isolation: Both services run on the same Docker network for secure inter-container communication.

  5. Port Mapping:

    • Frontend: 3000 (host) β†’ 80 (container)
    • Backend: 4000 (host) β†’ 4000 (container)

Tradeoffs

  1. Vite Environment Variables: Vite bundles environment variables at build time, not runtime. This means the API URL is baked into the build. In production, we use nginx to proxy requests, so relative URLs work. Alternative: Use runtime configuration or a separate config endpoint.

  2. No Database: History is stored in frontend state only. On page refresh, history is lost. For persistence, you'd need a database (PostgreSQL, MongoDB, etc.) and additional API endpoints.

  3. No Authentication: The API is open. In production, you'd want authentication/authorization.

  4. Simple Domain Validation: Basic regex validation. For production, use a more robust domain validation library.

πŸ“ Project Structure

ip-resolver/
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   └── server.ts              # Express server and API endpoints
β”‚   β”œβ”€β”€ Dockerfile                 # Backend Docker image
β”‚   β”œβ”€β”€ package.json
β”‚   └── tsconfig.json
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ App.tsx                # Main React component (composition only)
β”‚   β”‚   β”œβ”€β”€ App.scss               # App-level styles
β”‚   β”‚   β”œβ”€β”€ main.tsx               # React entry point
β”‚   β”‚   β”œβ”€β”€ styles/
β”‚   β”‚   β”‚   β”œβ”€β”€ index.scss         # Global styles
β”‚   β”‚   β”‚   └── variables.scss     # Shared SCSS variables (colors, etc.)
β”‚   β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”‚   β”œβ”€β”€ Header/            # Header component + styles
β”‚   β”‚   β”‚   β”œβ”€β”€ IpAddresses/       # IP addresses section + styles
β”‚   β”‚   β”‚   β”œβ”€β”€ DomainResolver/    # Resolve-domain form + styles
β”‚   β”‚   β”‚   β”œβ”€β”€ HistoryList/       # History list container + styles
β”‚   β”‚   β”‚   β”œβ”€β”€ HistoryItem/       # Single history item + styles
β”‚   β”‚   β”‚   β”œβ”€β”€ Spinner/           # Reusable loading spinner + styles
β”‚   β”‚   β”‚   └── ErrorMessage/      # Reusable error message + styles
β”‚   β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”‚   └── api.ts             # Frontend API client (fetch/resolve)
β”‚   β”‚   β”œβ”€β”€ types/
β”‚   β”‚   β”‚   └── index.ts           # Shared TypeScript interfaces
β”‚   β”‚   └── vite-env.d.ts          # Vite TypeScript helpers
β”‚   β”œβ”€β”€ public/
β”‚   β”‚   β”œβ”€β”€ index.html
β”‚   β”‚   └── vite.svg
β”‚   β”œβ”€β”€ Dockerfile                 # Frontend Docker image (Vite build + nginx)
β”‚   β”œβ”€β”€ nginx.conf                 # Nginx configuration (serves app + /api proxy)
β”‚   β”œβ”€β”€ vite.config.ts
β”‚   β”œβ”€β”€ package.json
β”‚   └── tsconfig.json
β”œβ”€β”€ .github/
β”‚   └── workflows/
β”‚       └── ci.yml                 # GitHub Actions CI
β”œβ”€β”€ .gitlab-ci.yml                 # GitLab CI
β”œβ”€β”€ docker-compose.yml             # Docker Compose configuration
β”œβ”€β”€ .gitignore
└── README.md

πŸ”§ Environment Variables

Backend

  • PORT: Server port (default: 4000)
  • NODE_ENV: Environment (development/production)

Frontend

  • VITE_API_URL: API base URL (default: empty, uses relative paths)

πŸ“ Future Enhancements

  • Add database persistence for resolution history
  • Implement authentication/authorization
  • Add rate limiting for API endpoints
  • Support IPv6 resolution
  • Add bulk domain resolution
  • Export history as CSV/JSON
  • Add unit and integration tests
  • Implement caching for frequently resolved domains

πŸ“„ License

ISC

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors