Dockerfile ports?

I have a Flask app that is running within a Docker container (app.run(host="0.0.0.0", port=3000), with EXPOSE 3000 in the Dockerfile. I’m deploying to fly with
flyctl deploy --config ./myapp/fly.toml --dockerfile ./myapp/Dockerfile --remote-only -a my-app.
My fly.toml file is

app = "my-app"
kill_signal = "SIGINT"
kill_timeout = 5
primary_region = "sjc"
processes = []

[env]

[experimental]
  auto_rollback = true

[http_service]
  internal_port = 3000
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0
  processes = ["app"]

[[services]]
  internal_port = 3000
  protocol = "tcp"

  [services.concurrency]
    hard_limit = 25
    soft_limit = 20

  [[services.ports]]
    handlers = ["http"]
    port = "80"

  [[services.ports]]
    handlers = ["tls", "http"]
    port = "443"

  [[services.tcp_checks]]
    interval = 10000
    timeout = 2000

The deploy succeeds but I cannot access my app if I go to myapp.fly.dev, and if I go into the fly console and curl localhost:3000 I get connection refused. What am I doing incorrectly here with the ports?

The default flask port is 5000. What does your app.run statement look like?

app.run(host="0.0.0.0", port=3000)

Oh, sorry, I see you included that in your original post.

The next thing to do is to look in the logs, the easiest way to do that is to run fly logs.

Here’s an example that works:

# syntax = docker/dockerfile:1

FROM python:slim

RUN pip install flask

COPY <<-"EOF" /demo/hello.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

app.run(host="0.0.0.0", port=3000)
EOF

WORKDIR /demo
EXPOSE 3000
CMD [ "python3", "hello.py" ]

The logs I’m seeing include:

2023-12-15T23:26:10Z app[90806603bd0438] iad [info] INFO Preparing to run: `python3 hello.py` as root
2023-12-15T23:26:10Z app[90806603bd0438] iad [info] INFO [fly api proxy] listening at /.fly/api
2023-12-15T23:26:10Z app[90806603bd0438] iad [info]2023/12/15 23:26:10 listening on [fdaa:0:d445:a7b:229:74e9:ff44:2]:22 (DNS: [fdaa::3]:53)
2023-12-15T23:26:10Z app[90806603bd0438] iad [info] * Serving Flask app 'hello'
2023-12-15T23:26:10Z app[90806603bd0438] iad [info] * Debug mode: off
2023-12-15T23:26:10Z app[90806603bd0438] iad [info]WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
2023-12-15T23:26:10Z app[90806603bd0438] iad [info] * Running on all addresses (0.0.0.0)
2023-12-15T23:26:10Z app[90806603bd0438] iad [info] * Running on http://127.0.0.1:3000
2023-12-15T23:26:10Z app[90806603bd0438] iad [info] * Running on http://172.19.3.82:3000
2023-12-15T23:26:10Z app[90806603bd0438] iad [info]Press CTRL+C to quit

what does your toml look like? you’re able to curl port 3000 from the console?

the flask app does turn on when I deploy, I see

2023-12-16T00:22:37Z app[e286551c5e2986] sjc [info] * Running on all addresses (0.0.0.0)
2023-12-16T00:22:37Z app[e286551c5e2986] sjc [info] * Running on http://127.0.0.1:3000
2023-12-16T00:22:37Z app[e286551c5e2986] sjc [info] * Running on http://172.19.129.250:3000

in the logs

You should be able to put the Dockerfile that I gave you into an empty directory and run fly launch. If you do so, the fly.toml you will receive will look something like this:

app = "app-name"
primary_region = "iad"

[build]

[http_service]
  internal_port = 3000
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0
  processes = ["app"]

[[vm]]
  cpu_kind = "shared"
  cpus = 1
  memory_mb = 1024

If I shell in, and install curl, then yes, curl http://localhost:3000/ succeeds.

1 Like

I used fly launch to recreate my fly.toml, now it looks like this

app = "my-app"
primary_region = "sjc"
kill_signal = "SIGINT"
kill_timeout = "5s"

[experimental]
  auto_rollback = true

[build]

[http_service]
  internal_port = 3000
  force_https = true
  auto_stop_machines = true
  auto_start_machines = true
  min_machines_running = 0
  processes = ["app"]

[[services]]
  protocol = "tcp"
  internal_port = 3000

  [[services.ports]]
    port = 80
    handlers = ["http"]

  [[services.ports]]
    port = 443
    handlers = ["tls", "http"]
  [services.concurrency]
    hard_limit = 25
    soft_limit = 20

  [[services.tcp_checks]]
    interval = "10s"
    timeout = "2s"

[[vm]]
  cpu_kind = "shared"
  cpus = 1
  memory_mb = 1024

However I am still not able to curl port 3000. When I run netstat -tuln , the only port I see is the hallpass ssh port (22).

Can I get you to try this? It is self contained and should work.

At that point there is something different about your app. The problem isn’t in your fly.toml or in your app.run statement. But without seeing your app or the rest of your logs, I can’t speculate as to where that problem is.

1 Like

I was running two processes in the container. When I moved to individual containers and fly instances for each process, it works (not sure causal reason).

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.