Your App Runs but You Still Can’t Access It Externally — Explained!

Ever built an app, deployed it inside a VM or container, saw it running perfectly — but when you tried accessing it from your browser or network, nothing worked?
You’re not alone. External access issues are among the most common headaches in cloud, virtualization, and DevOps setups. In this guide, I’ll explain how internal and external access works, why IP layers matter, the most common mistakes, and how I fixed a real-world Jenkins setup on OpenStack behind a VPN.

Internal vs External Access in Cloud Environments

  • Internal Access → The application is reachable only within your private network or cloud environment.
    Example: You can open the app from another VM inside the same OpenStack project or VPN, but not from your home laptop.
  • External Access → The application is reachable from outside your private network — for example, over the public internet.
    Example: Anyone can access it using a public IP address or a registered domain name.

By default, most cloud and virtualization platforms — including OpenStack, AWS, Azure, and GCP — keep applications private for security reasons.To make an app externally accessible, you generally need to:

  • Assign a Floating/Public IP to the VM.
  • Open the required ports in security groups or firewall rules.
  • Optionally set up a reverse proxy (e.g., Nginx, Apache) or load balancer to route traffic.
  • Ensure the application is bound to 0.0.0.0 so it listens for external requests.

How external access flows in the cloud

When a user opens your app, traffic takes these hops:

[ Browser ]
     |
     v
[ DNS (optional) ]
     |
     v
[ Public / Floating IP ]
     |
     v
[ Cloud Network ]
(Security Groups / Firewall)
     |
     v
[ Host or Load Balancer ]
     |
     v
[ Reverse Proxy / Ingress ]
     |
     v
[ VM / Container / Pod ]
     |
     v
[ Application ]

Common Mistakes Blocking External Access

  • Incorrect Network Rules – Missing or wrong firewall, security group, or NACL rules can silently block traffic, and as a result, users may be unable to access the application externally.
  • Port Restrictions – Required ports may be closed or blocked by a firewall or cloud provider settings.
  • Proxy or Load Balancer Issues – Misconfigured routing, SSL termination, or proxy paths can cause 503 errors.
  • Service Not Exposed – Kubernetes or VM services may not be configured for external access.

Real-World Use Case — OpenStack + VPN + Jenkins

I deployed Jenkins inside an OpenStack VM. Internally I could open Jenkins with http://<vm-ip>:8080 and the container logs showed healthy startup. Externally, When I tried the floating IP and hit 503 Service Unavailable. So, I changed proxy paths in Jenkins and tweaked configs, but the browser still returned 503. I needed to know where the request died.

Step 1: Verify Local Access

I first checked the obvious: I ran curl http://localhost:8080 on the Jenkins VM. The app answered locally. That told me Jenkins served requests, but external traffic never reached it.

Step 2: Open the Port in OpenStack

Next, I updated the OpenStack security group rules to allow incoming traffic on Jenkins’ port (8080). This ensured that external requests could actually reach the VM.

Step 3: Set Up Nginx Reverse Proxy

To cleanly expose Jenkins and manage routes, I installed Nginx on the VM. In /etc/nginx/sites-enabled/default, I added a proxy block for Jenkins:

server {
        listen 8080
      location /jenkins/  {
      sendfile off;
      proxy_pass  http://<ip>/jenkins/;
      proxy_http_version 1.1;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
}

After restarting Nginx, I tried opening Jenkins in the browser via /jenkins, but it still returned 503.

Step 4: The Hidden Catch — Jenkins Prefix

After digging deeper, I realized that Jenkins itself wasn’t aware it should run behind a prefix (/jenkins). To fix this, I updated the Jenkins configuration file (/etc/default/jenkins or jenkins.xml, depending on installation method) and set: PREFIX=/jenkins.

I restarted Jenkins, and finally, visiting: http://<vm-ip>/jenkins worked perfectly.

Key Takeaways

  • Internal access working doesn’t guarantee external accessibility.
  • Reverse proxy alone isn’t enough; the application must know its context path / prefix.
  • Cloud firewall rules (security groups) need to allow incoming traffic to the correct port.

Conclusion

In many cases, external access issues are often the result of a combination of networking, proxy, and application configuration problems. Therefore, by carefully understanding each layer and systematically troubleshooting step-by-step, you can ensure that your applications become fully accessible as intended

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top