Skip to main content

Overview

The port exposure capability allows your Utari workers to make custom development servers and applications accessible by exposing specific ports. While port 8080 is automatically exposed, you can expose additional ports for applications running on different ports, enabling you to test multiple services simultaneously or work with applications that require specific port configurations.
Port 8080 Note: Port 8080 is automatically exposed and does NOT require manual exposure. Use this tool for all other ports.

Understanding Port Exposure

What is Port Exposure?

Port exposure creates a tunnel that makes locally running applications accessible:

Local Development

Applications running in your Utari workspace on specific ports

External Access

Makes these applications accessible via public URLs

Multiple Services

Run and access multiple servers simultaneously on different ports

Testing & Debugging

Test applications in development before deployment

Default vs. Custom Ports

Automatically Available
  • No configuration needed
  • Immediately accessible
  • Default for most development servers
Common Uses:
  • Python HTTP server: python -m http.server 8080
  • Node.js apps configured for 8080
  • Default development server port
Already works - no exposure tool needed

When to Expose Ports

Use Cases for Port Exposure

Many frameworks use specific default ports:
  • React/Create React App: Port 3000
  • Next.js: Port 3000
  • Angular: Port 4200
  • Vue.js: Port 8080 (auto-exposed) or 5173 (Vite)
  • Flask: Port 5000
  • Django: Port 8000
  • Express.js: Configurable, often 3000
  • Svelte: Port 5000 or 8080
When you need multiple servers running at once:
    Frontend: React on port 3000 (expose)
    Backend API: Express on port 5000 (expose)
    Database Admin: Port 5432 (expose if needed)
    Monitoring: Port 9090 (expose)
Some applications require specific ports:
  • Database interfaces and admin tools
  • Monitoring dashboards
  • Development tools (Webpack dev server, etc.)
  • API documentation servers
  • Testing frameworks
When you’ve configured your application for a specific port:
    // Server configured for port 4000
    app.listen(4000, () => {
      console.log('Server running on port 4000');
    });

Exposing Ports

Basic Port Exposure

1

Start Your Application

Launch your development server on the desired port:
    # React development server
    npm start  # Typically runs on port 3000
    
    # Flask application
    python app.py  # Typically runs on port 5000
    
    # Custom Node.js server
    node server.js  # Runs on configured port
2

Request Port Exposure

Ask your worker to expose the port:
    Please expose port 3000 so I can access my React app
3

Receive Access URL

Your worker provides a public URL:
    Port 3000 exposed successfully!
    Access your application at: https://[unique-url].utari.app
4

Access Your Application

Click the provided URL to access your running application.

Multiple Port Exposure

You can expose multiple ports simultaneously:
1

Start Multiple Services

    # Terminal 1: Frontend on port 3000 (non-blocking)
    npm run dev
    
    # Terminal 2: Backend on port 5000 (non-blocking)
    python api_server.py
    
    # Terminal 3: Database UI on port 8081 (non-blocking)
    npm run db-admin
2

Expose All Ports

    Please expose ports 3000, 5000, and 8081
3

Get All URLs

    Ports exposed successfully:
    - Port 3000: https://[url1].utari.app (Frontend)
    - Port 5000: https://[url2].utari.app (API)
    - Port 8081: https://[url3].utari.app (Database UI)

Common Development Server Configurations

React Applications

# Start development server
npm start

# Request exposure
"Please expose port 3000 for my React app"

Node.js/Express Applications

const express = require('express');
const app = express();
const PORT = 3000;

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

// Request exposure for port 3000

Python Applications

# Run Flask app
python app.py
# or
flask run

# Request exposure
"Please expose port 5000 for my Flask app"

Angular Applications

# Angular CLI dev server (Default: 4200)
ng serve

# Request exposure
"Please expose port 4200 for my Angular app"

Vue.js Applications

# Auto-exposed - no action needed
npm run serve

Complete Development Workflow

Full-Stack Application Setup

1

Install Dependencies

    # Frontend dependencies
    cd frontend && npm install
    
    # Backend dependencies
    cd ../backend && pip install -r requirements.txt --break-system-packages
2

Start Backend (Non-Blocking)

    # Start Flask API on port 5000
    python api.py
    # Running in background
3

Start Frontend (Non-Blocking)

    # Start React app on port 3000
    cd frontend && npm start
    # Running in background
4

Expose Ports

    Please expose ports 3000 and 5000
5

Access Applications

    Frontend URL: https://[url1].utari.app
    Backend API: https://[url2].utari.app/api
6

Test Integration

  • Visit frontend URL
  • Verify API calls to backend URL work
  • Test application functionality

Microservices Architecture

1

Start All Services

    # Service 1: Authentication (port 4000)
    node services/auth/server.js &
    
    # Service 2: User Management (port 4001)
    node services/users/server.js &
    
    # Service 3: Data API (port 4002)
    node services/data/server.js &
    
    # Gateway (port 3000)
    node gateway/server.js &
2

Expose All Service Ports

    Please expose ports 3000, 4000, 4001, and 4002
3

Map Services

    Gateway: https://[url1].utari.app
    Auth Service: https://[url2].utari.app
    User Service: https://[url3].utari.app
    Data Service: https://[url4].utari.app

Port Exposure Best Practices

Use Standard Ports

Stick with framework defaults when possible for easier collaboration and documentation

Document Port Usage

Keep a list of which services run on which ports for easy reference

Avoid Conflicts

Ensure no two services try to use the same port simultaneously

Remember 8080

Use port 8080 when possible since it’s auto-exposed (one less step)

Non-Blocking Execution

Always run servers in non-blocking mode so they continue running in the background

Test After Exposure

Always verify the exposed URL works after requesting port exposure

Clean Up

Stop unused servers and unexpose ports when done to free resources

Use Environment Variables

Configure ports via environment variables for flexibility

Common Port Reference

FrameworkDefault PortExposure Needed
React (CRA)3000✅ Yes
Next.js3000✅ Yes
Angular4200✅ Yes
Vue (CLI)8080❌ No (auto)
Vite5173✅ Yes
Svelte5000/80805000: ✅ Yes
Nuxt.js3000✅ Yes

Troubleshooting

Verify:
  • Server is actually running on that port
  • Check server logs for startup errors
  • Use netstat -tuln | grep [PORT] to confirm port is listening
  • Ensure no firewall blocking
  • Try restarting the server
  • Re-request port exposure
Solutions:
  • Check what’s using the port: lsof -i :[PORT]
  • Stop the existing process
  • Or use a different port
  • Kill stuck processes: kill -9 [PID]
  • Restart with new port number
Check:
  • URL copied correctly (no typos)
  • Server started successfully
  • No CORS issues (check browser console)
  • Server bound to 0.0.0.0 not localhost
  • Try accessing from incognito/private window
Ensure:
  • All servers started successfully
  • All ports explicitly exposed
  • No port conflicts
  • Check each service individually
  • Verify each exposed URL
Check that server is bound to all interfaces:Wrong (localhost only):
    app.listen(3000, 'localhost')
Correct (all interfaces):
    app.listen(3000, '0.0.0.0')
    // or simply
    app.listen(3000)
Verify:
  • Server is running (check with list_commands)
  • Correct route/path being accessed
  • Server has proper route handlers
  • No typos in URL path
  • Check server logs for requests

Environment-Specific Configuration

Using Environment Variables

# .env file
PORT=3000
API_PORT=5000
DB_PORT=5432

# Start app (reads from .env)
npm start

Package.json Scripts

{
  "scripts": {
    "dev": "PORT=3000 react-scripts start",
    "dev:custom": "PORT=4000 react-scripts start",
    "api": "PORT=5000 node server.js",
    "start:all": "concurrently \"npm run dev\" \"npm run api\""
  }
}

Advanced Usage

Proxy Configuration

When frontend needs to communicate with backend on different port:
{
  "proxy": "http://localhost:5000"
}

Docker Compose with Port Mapping

version: '3.8'
services:
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"  # Expose 3000
  
  backend:
    build: ./backend
    ports:
      - "5000:5000"  # Expose 5000
  
  database:
    image: postgres
    ports:
      - "5432:5432"  # Expose 5432 if UI needed

Summary

You’ve successfully learned:
How port exposure works in Utari
When to use port exposure (all ports except 8080)
How to expose single and multiple ports
Common framework default ports and configurations
Best practices for development server management
Troubleshooting port exposure issues
Advanced configurations for multi-service applications
Port exposure enables your development workflow in Utari, allowing you to run and access multiple development servers, test full-stack applications, and work with framework-specific tooling—all through simple conversational requests.

Next Steps