--- title: "Open a port on an instance" description: "Make an app on a TIR Instance reachable from the internet by having it listen on all addresses and allowing its port in a security group." content_type: "how-to" product: "tir-instance" platform: "TIR" url: "/tir/tir-instance/how-to/open-a-port-on-an-instance/" topic: ["create-and-connect"] --- # Open a port on an instance Make an app you run on an instance, such as a web server, an API, or a demo, answer at the instance's public IP on the port you choose. The ports open on an instance are the ones in the inbound rules of its attached security groups. To open a port, add an inbound rule to a security group, and attach that group to the instance. For TensorBoard and Gradio, use the add-ons instead: TIR gives each one a web address of its own. See [Use TensorBoard on an instance](/tir/tir-instance/how-to/use-tensorboard-on-an-instance/) and [Use Gradio on an instance](/tir/tir-instance/how-to/use-gradio-on-an-instance/). ## Before you begin - A **Running** instance. An app on the instance answers only while the instance is **Running**. - A role in the project that lets you update instances. - A security group with an inbound rule for your app's port. **Default-SSH-Security-Group**, which every project has, opens only port 22 and its rules are fixed, so use a security group of your own for any other port. A security group belongs to one project and one region, and you can attach it only to instances there. Security groups and their rules are part of [Security Groups](/tir/tir-security-group/). ## Make the app listen on all addresses Your app is reached at the instance's public IP only when it listens on `0.0.0.0`, which means all addresses. An app that listens only on `localhost` or `127.0.0.1` answers inside the instance and nowhere else. Most servers accept the bind address as a command-line option. For example, these start a test web server, a FastAPI app with Uvicorn, and a Flask app on port 8000: ```bash python3 -m http.server 8000 --bind 0.0.0.0 uvicorn main:app --host 0.0.0.0 --port 8000 flask run --host 0.0.0.0 --port 8000 ``` A restart ends every program running in the instance, and the instance runs without `systemd` to start services for you. To have your app start again after each start and restart, start it from a start script. See [Run start scripts on an instance](/tir/tir-instance/how-to/run-start-scripts-on-an-instance/). ## Allow the port in a security group 1. In the side menu, under **PLATFORM SERVICES**, open **Networking** > **Security Groups**. For a group you already have, open its **Actions** menu and select **Manage Rules**. For a new group, select **Create Security Group** and enter a **Security Group Name** (letters, digits, hyphens, and underscores, unique in the project). Under **Manage Security Group Rules**, select **Add Rule**: a new group needs at least one inbound and one outbound rule. 2. Add an inbound rule with **Type** set to **Custom TCP**. Type your app's port in **Ports** and press Space or a comma, then choose a **Source**, which decides who can reach the port. Rules are TCP only, with one port per entry. You can use only ports 22, 80, 443, and 1024 to 65535. In **Manage Rules**, select **Apply All Changes**, then **Confirm**. 3. Open the instance and go to **Network & Security** > **Security Groups**. In **Select Security Groups**, pick the group and select **Attach**. The port opens at once, and the instance keeps running. If you change the group's rules later, the change also applies at once to every instance the group is attached to. For every rule option, see [Manage security group rules](/tir/tir-security-group/how-to/manage-security-group-rules/). An instance can have several security groups. Keep **Default-SSH-Security-Group** attached if you also connect over SSH, and attach your own group next to it. When you create an instance, you choose its security group under **Network & Security** on the **Create Instance** form. Check under **Open ports** that your port is there before you launch. If the instance has no reserved IP, it gets a public IP from E2E's pool once it has open security-group ports. While security groups are attached, the instance keeps at least one floating or reserved IP. ## Decide who can reach the port Anyone who can reach the instance's IP address and the port reaches your app directly: opening a port adds no sign-in of its own. If the app has no sign-in either, anyone on the internet who finds the address can use it. An app that runs code for its users, such as a Jupyter server you start yourself, gives anyone who reaches it control of your instance. Protect the app in one of these ways: - Turn on the app's own sign-in, password, or token. - Set the inbound rule's **Source** to **Manual Network** with the IPv4 address that needs the app, instead of **Any Network**. Each rule takes one address, so add a rule for each address you allow. For machines in one of your VPCs, choose **MyAccount VPC Network**. ## Check that the port answers Find the instance's public IP on **Network & Security** > **Network**, under **Public IP**. From your own computer, request the app at that address and port: ```bash curl http://:/ ``` Replace `` with the instance's public IP and `` with your app's port. The app's response prints in your terminal. If the request times out or is refused, check that: - The instance is **Running** and the app is running in it. - The app listens on `0.0.0.0`, all addresses, rather than only on `localhost`. - An attached security group has a **Custom TCP** inbound rule for the port, with a source that includes your address. ## Keep the same address The instance gives back a public IP from E2E's pool when it stops, and a start can bring a different one. Anyone using your app then needs the new address. To keep the address across stops and starts, reserve it. See [Manage IP addresses on an instance](/tir/tir-instance/how-to/manage-ip-addresses-on-an-instance/). To log in to the instance and manage the app from a terminal, see [Connect to an instance over SSH](/tir/tir-instance/how-to/connect-to-an-instance-over-ssh/). For other problems, see [Troubleshooting TIR Instances](/tir/tir-instance/troubleshooting/tir-instance/).