How to Use port 80 and port 500

I am trying to run two web servers in balena, but I am not able to use port 5000, whereas port 80 is working fine, can I use the two-port simultaneously.
Note: port 80 is for (wifi-connect) and port 5000 will be for flask webapp

@iammatrix this should work fine, you can expose as many ports as you would like and they’ll be externally accessible via the device’s local IP address. Perhaps you can share your docker-compose.yml here for us to take a look?

It is however worth mentioning that if you’re not accessing the device locally and trying to use the balena public URL feature to access your Flask webapp remotely then you cannot share arbitrary ports such as 5000 or 500 and must stick to standard HTTP ports.

@chrisys here is the docker-compose you’ve asked for

version: '2.1'
services:
  nginx:
    build: 
      context: ./nginx
      dockerfile: Dockerfile.template
    ports:
      - 80:80

  wifi-connect:
        build: ./wifi-connect
        network_mode: "host"
        labels:
            io.balena.features.dbus: '1'
        cap_add:
            - net_admin
        environment:
            DBUS_SYSTEM_BUS_ADDRESS: "unix:path=/host/run/dbus/system_bus_socket"

  sample1:
    build: 
      context: ./sample-app
      dockerfile: Dockerfile.template
    environment:
      SERVICE_NAME: 'sample1'

the nginx if copied from - GitHub - balena-io-examples/nginx-reverse-proxy: Access multiple ports over public URL using nginx reverse proxy.
I have made some changes in http.conf
server {
listen 80;
server_name localhost;
resolver 127.0.0.11; # Docker DNS

  # Apps
  location ~/ {
    set $sample1 http://sample1:5000;
    proxy_pass $sample1/$1;
  }
}

My goal is to let the wifi-connect run like it is suppose to, on port 80 on a local http server, whereas I want to run my flask app on port 80 too as a public url

Let me know you want to see any other code

Hey there, thanks for sharing your compose file! Are you trying to access the flask app locally via the device IP or via the Public Device URL in the dashboard?

I ask because wifi-connect requires port 80 for correct operation, so your flask app should run on something else, like 5000 as you suggested.

version: '2.1'
services:
  nginx:
    build: 
      context: ./nginx
      dockerfile: Dockerfile.template
    ports:
    # can't use 80: here or it will conflict with wifi-connect
      - 5000:5000

  wifi-connect:
        build: ./wifi-connect
        network_mode: "host"
        labels:
            io.balena.features.dbus: '1'
        cap_add:
            - net_admin
        environment:
            DBUS_SYSTEM_BUS_ADDRESS: "unix:path=/host/run/dbus/system_bus_socket"

  sample1:
    build: 

Note in the example above I am assuming your flask app in the container is also set to port 5000. Otherwise you could use 5000:80 to map external port 5000 to the internal flask port 80. With the example above you should be able to reach your flask app on http://DEVICEIP:5000 where DEVICEIP is the local IP address of your device.

You can read a bit more about exposing ports for multiple services here:

Hey, @klutchell thanks for replying, I am trying to run the flask app as a public URL, it will act as an API Endpoint. I’ll tryout your solution and let you know here.

Unfortunately because wifi-connect requires port 80 you won’t be able to expose the flask app via the Public URL. Is there a reason you need both services? Maybe we can help find a workaround if we better understand your use case.

The reason why I want both of them running, the wifi-connect will do its job and the Flask web app is an API endpoint, the Flask web app is fetching data from the local mongo container and showing it as an API endpoint in the public url. Both of them are equally important for this project I am working on

I understand, and that use case does make sense, but ultimately they cannot both utilize port 80, and the public URL feature only allows for port 80. The only other thing that I can think of is to somehow programatically delay your Flask application from starting up while WiFi Connect is running and broadcasting the captive portal. Once a user chooses an access point and enters the WiFi password, the WiFi Connect portal is then finished and the service could be killed. At that point, the Flask app could start up, and “take over” port 80 duties. Now, with all of that said, it is not something we have ever tried, have no experience with, and if I recall correctly even after a service / application is dead port bindings can in fact remain. So you may need to research how to release those back out, as well.

But as it stands, there is no way for the applications to co-exist on port 80, that is for sure. Hope that helps, thanks!

@chrisys @dtischler @klutchell Thanks to you guys I found the solution for it. Only a sleep 600 before executing the python script did the job.

2 Likes