> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nova-cloud.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Instance Ports

> Open and manage network ports on your GPU instance for web services, APIs, and applications.

By default, all ports on your Nova Cloud instance are **closed** except for SSH (port 22). This guide shows you how to open ports for web services, Jupyter notebooks, APIs, and other applications.

## Default Port Configuration

When you create an instance, the firewall (UFW — Uncomplicated Firewall) is pre-configured with:

| Port       | Status     | Protocol | Purpose                         |
| ---------- | ---------- | -------- | ------------------------------- |
| 22         | **Open**   | TCP      | SSH access                      |
| All others | **Closed** | —        | Blocked by default for security |

<Note>
  If you created your instance with a template that includes a WebUI (Stable Diffusion, ComfyUI, or Linux Desktop), the WebUI is accessible through the **portal** when you click **Connect** on your instance — you do not need to open ports for it. See the [Connecting guide](/guides/connecting#connecting-via-webui-portal) for details.
</Note>

## Opening Ports

Connect to your instance via SSH first, then use `ufw` commands to manage ports.

### Open a Single Port

```bash theme={null}
# Open a TCP port (most common)
sudo ufw allow 8888/tcp

# Open a UDP port
sudo ufw allow 9090/udp

# Open a port for both TCP and UDP
sudo ufw allow 3000
```

### Open a Range of Ports

```bash theme={null}
# Open ports 8000 through 8100
sudo ufw allow 8000:8100/tcp
```

### Verify Your Rules

```bash theme={null}
sudo ufw status
```

You'll see output like:

```
Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere
8888/tcp                   ALLOW       Anywhere
8080/tcp                   ALLOW       Anywhere
```

## Common Port Configurations

Here are the ports you'll most commonly need to open, depending on your workload:

### Machine Learning & Data Science

| Service                  | Port | Command                   |
| ------------------------ | ---- | ------------------------- |
| Jupyter Notebook / Lab   | 8888 | `sudo ufw allow 8888/tcp` |
| TensorBoard              | 6006 | `sudo ufw allow 6006/tcp` |
| MLflow                   | 5000 | `sudo ufw allow 5000/tcp` |
| Weights & Biases (local) | 8080 | `sudo ufw allow 8080/tcp` |
| Ray Dashboard            | 8265 | `sudo ufw allow 8265/tcp` |

### AI Image Generation

| Service                  | Port | Command                   |
| ------------------------ | ---- | ------------------------- |
| Stable Diffusion (A1111) | 7860 | `sudo ufw allow 7860/tcp` |
| ComfyUI                  | 8188 | `sudo ufw allow 8188/tcp` |
| Fooocus                  | 7865 | `sudo ufw allow 7865/tcp` |
| InvokeAI                 | 9090 | `sudo ufw allow 9090/tcp` |

### Web & API Development

| Service           | Port | Command                   |
| ----------------- | ---- | ------------------------- |
| HTTP              | 80   | `sudo ufw allow 80/tcp`   |
| HTTPS             | 443  | `sudo ufw allow 443/tcp`  |
| FastAPI / Uvicorn | 8000 | `sudo ufw allow 8000/tcp` |
| Flask             | 5000 | `sudo ufw allow 5000/tcp` |
| Node.js / Express | 3000 | `sudo ufw allow 3000/tcp` |
| Gradio            | 7860 | `sudo ufw allow 7860/tcp` |

### LLM Inference

| Service                         | Port  | Command                    |
| ------------------------------- | ----- | -------------------------- |
| vLLM                            | 8000  | `sudo ufw allow 8000/tcp`  |
| Text Generation Inference (TGI) | 8080  | `sudo ufw allow 8080/tcp`  |
| Ollama                          | 11434 | `sudo ufw allow 11434/tcp` |
| LocalAI                         | 8080  | `sudo ufw allow 8080/tcp`  |
| Open WebUI                      | 3000  | `sudo ufw allow 3000/tcp`  |

## Restricting Access by IP

For production services, you may want to restrict port access to specific IP addresses rather than opening them to the entire internet.

### Allow Only Your IP

```bash theme={null}
# Only allow your IP to access port 8888
sudo ufw allow from 203.0.113.50 to any port 8888 proto tcp
```

### Allow a Subnet

```bash theme={null}
# Allow an entire subnet
sudo ufw allow from 10.0.0.0/24 to any port 8080 proto tcp
```

<Tip>
  Find your public IP address by searching "what is my IP" in your browser, or run `curl ifconfig.me` from your local machine.
</Tip>

## Closing Ports

### Remove a Specific Rule

```bash theme={null}
# Close a port
sudo ufw delete allow 8888/tcp
```

### View and Delete by Rule Number

```bash theme={null}
# List rules with numbers
sudo ufw status numbered

# Delete rule by number
sudo ufw delete 3
```

## Example: Running Jupyter Notebook

Here's a complete example of setting up Jupyter Notebook accessible from your browser:

<Steps>
  <Step title="Connect to your instance">
    ```bash theme={null}
    ssh ubuntu@<your-vm-ip>
    ```
  </Step>

  <Step title="Open port 8888">
    ```bash theme={null}
    sudo ufw allow 8888/tcp
    ```
  </Step>

  <Step title="Install and start Jupyter">
    ```bash theme={null}
    pip install jupyterlab
    jupyter lab --ip=0.0.0.0 --port=8888 --no-browser
    ```

    Jupyter will print a URL with a token. Copy it.
  </Step>

  <Step title="Access from your browser">
    Open your browser and go to:

    ```
    http://<your-vm-ip>:8888/lab?token=<your-token>
    ```

    Replace `<your-vm-ip>` with your instance's IP and `<your-token>` with the token from the terminal output.
  </Step>
</Steps>

## Example: Serving a Model with vLLM

<Steps>
  <Step title="Connect to your instance">
    ```bash theme={null}
    ssh ubuntu@<your-vm-ip>
    ```
  </Step>

  <Step title="Open port 8000">
    ```bash theme={null}
    sudo ufw allow 8000/tcp
    ```
  </Step>

  <Step title="Start vLLM">
    ```bash theme={null}
    pip install vllm
    vllm serve meta-llama/Llama-3.1-8B-Instruct --host 0.0.0.0
    ```
  </Step>

  <Step title="Send a request from your local machine">
    ```bash theme={null}
    curl http://<your-vm-ip>:8000/v1/chat/completions \
      -H "Content-Type: application/json" \
      -d '{
        "model": "meta-llama/Llama-3.1-8B-Instruct",
        "messages": [{"role": "user", "content": "Hello!"}]
      }'
    ```
  </Step>
</Steps>

## Security Best Practices

<Warning>
  Opening ports exposes your instance to the internet. Follow these practices to stay secure.
</Warning>

* **Only open ports you need.** Every open port is a potential attack surface.
* **Use IP restrictions** for sensitive services. Don't expose database ports (3306, 5432, 6379) to the entire internet.
* **Use authentication.** Always configure services with authentication tokens or passwords (e.g., Jupyter's token, API keys).
* **Bind to `0.0.0.0` only when needed.** Services bound to `127.0.0.1` are only accessible from the instance itself (via SSH tunneling), which is more secure.
* **Consider SSH tunneling** as an alternative to opening ports. See below.

## Alternative: SSH Tunneling

Instead of opening ports in the firewall, you can use SSH tunneling to securely access services through your SSH connection. This is more secure because the service never needs to be exposed to the internet.

```bash theme={null}
# Forward local port 8888 to the instance's port 8888
ssh -L 8888:localhost:8888 ubuntu@<your-vm-ip>
```

Then access the service at `http://localhost:8888` in your browser. The traffic is encrypted through your SSH connection.

### Tunnel Multiple Ports

```bash theme={null}
ssh -L 8888:localhost:8888 -L 6006:localhost:6006 ubuntu@<your-vm-ip>
```

This forwards both Jupyter (8888) and TensorBoard (6006) at once.

<Tip>
  SSH tunneling is ideal for development and testing. For production services that need to be accessible by others, open the port with `ufw` instead.
</Tip>

## Troubleshooting

<AccordionGroup>
  <Accordion title="I opened a port but can't connect">
    Check these in order:

    1. **Is the service running?** SSH into the instance and verify: `ss -tlnp | grep <port>`
    2. **Is the service bound to the right address?** It must be bound to `0.0.0.0`, not `127.0.0.1`. Start your service with `--host 0.0.0.0` or `--bind 0.0.0.0`.
    3. **Is the port open in UFW?** Check with: `sudo ufw status | grep <port>`
    4. **Is the instance running?** Verify in the console dashboard.
  </Accordion>

  <Accordion title="UFW command not found">
    UFW should be pre-installed on all Nova Cloud instances. If it's missing:

    ```bash theme={null}
    sudo apt update && sudo apt install ufw -y
    sudo ufw enable
    sudo ufw allow 22/tcp  # Don't lock yourself out!
    ```
  </Accordion>

  <Accordion title="Locked myself out (can't SSH in)">
    If you accidentally blocked port 22, you cannot SSH in. Use the console to **Stop** and then **Destroy** the instance, and create a new one. Always ensure port 22 is allowed before modifying UFW rules.
  </Accordion>

  <Accordion title="Service works locally but not remotely">
    The service is probably bound to `127.0.0.1` (localhost only). Change the bind address to `0.0.0.0`:

    ```bash theme={null}
    # Instead of:
    jupyter lab --port=8888

    # Use:
    jupyter lab --ip=0.0.0.0 --port=8888
    ```

    Most frameworks have a `--host` or `--bind` flag for this.
  </Accordion>
</AccordionGroup>

## What's Next?

<CardGroup cols={2}>
  <Card title="Connecting to an Instance" icon="plug" href="/guides/connecting">
    Learn about SSH access and the WebUI portal.
  </Card>

  <Card title="Choosing a GPU" icon="microchip" href="/guides/choosing-gpu">
    Pick the right GPU and configuration for your workload.
  </Card>
</CardGroup>
