Can reach my app over http but not https

So the problem I’m facing is that I can’t reach my app over https but I can reach it over http via curl.

I can also ssh into my machine and reach it on http but again not https but I’m guessing thats to be expected because It’s my understanding that fly does SSL termination at the proxy so the proxy can communicate with my app over HTTP.

Why can’t I reach my website from the outside via HTTPS? Is there something wrong with my code/config?!

This is part of my fly.toml

[[services]]
  processes = ["web"]
  internal_port = 8080  # your app listens here
  protocol = "tcp"

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

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

[processes]
web = "app"
cron = "supercronic -json /crontab"

[[vm]]
size = "shared-cpu-1x"
memory = "256mb"
cpu_kind = "shared"
cpus = 1

my server is simply a golang app with part of the server code looks like this:

type server struct {
	http.Server
}

type Option func(*server) error

func WithHandler(h http.Handler) Option {
	return func(s *server) error {
		s.Handler = h
		return nil
	}
}

// Creates a new http server which defaults to port 8080
func NewServer(opts ...Option) (*server, error) {

	defaultMux := http.NewServeMux()

	defaultMux.HandleFunc("GET /", func(w http.ResponseWriter, r *http.Request) {
		_, err := w.Write([]byte("SUP"))
		if err != nil {
			log.Println("error writing response: ", err)
		}
	})

	s := &server{
		http.Server{
			Handler:      defaultMux,
			ReadTimeout:  time.Second * 5,
			WriteTimeout: time.Second * 5,
			Addr:         "0.0.0.0:8080",
		},
	}

	for _, fn := range opts {
		if err := fn(s); err != nil {
			return nil, err
		}
	}

	return s, nil
}

fly doctor shows everything appears to be working:

Testing authentication token... PASSED
Testing flyctl agent... PASSED
Testing local Docker instance... Nope
Pinging WireGuard gateway (give us a sec)... PASSED
Testing WireGuard DNS... PASSED
Testing WireGuard Flaps... PASSED

App specific checks for ***:
Checking that app has ip addresses allocated... PASSED
Checking A record for *** ... PASSED
Checking AAAA record for ***... PASSED

Build checks for ***:
Checking docker context size (this may take little bit)... PASSED (35 MB)
Checking for .dockerignore... PASSED

How are you accessing your app? If you want to access it from the public internet, use appname.fly.dev. This will do the TLS bit for you, and then your app only needs to reply in HTTP.

My working app just uses a much more bare-bones config:

app = '...'
primary_region = 'lhr'

[build]

[env]
  ...

[http_service]
  internal_port = 8080
  force_https = false

[[restart]]
  policy = 'always'

[[vm]]
  cpu_kind = 'shared'
  cpus = 1
  memory_mb = 256

I don’t know the [[services]] syntax in detail, but mine seems fine.

Hey, I’m just using the default url that came with my app e.g.

curl https://my-app.fly.dev ← this does not work
curl http://my-app.fly.dev ← this does work!

I can also try with the dedicated IP address I have again curl http://my-ip4-addr works but curl https://my-ip4-addr doesn’t!!

Maybe it’s the dedicated IPv4 address causing problems and needs extra setup??

Yeah, I am wondering whether IPs has something to do with it. I have this:

halfer@halfer-VirtualBox:~/Development$ flyctl ip list
VERSION	IP                   	TYPE              	REGION	CREATED AT        
v6     	2a09:8280:1::30:105:0	public (dedicated)	global	Mar 31 2024 18:18	
v4     	66.241.125.210       	public (shared)   	      	Jan 1 0001 00:00 	

What do you have for the same command?

It was this:

VERSION IP TYPE REGION CREATED AT
v4 137.66.34.183 public (dedicated, $2/mo) global May 17 2024 08:30
v6 2a09:8280:1::35:a003:0 public (dedicated) global May 14 2024 19:18

Although I have now just released the IP and switching to a shared IP (don’t need it anymore anyways), hopefully it will fix.

Yeah, let me know how you get on. That’s def what I would amend first.

Unfortunately still not working. Here’s what I’ve tried so far:

  • Removed dedicated IPv4 address and allocated myself a shared IPv4 instead
  • destroyed existing machines and restarted, didn’t change anything :frowning:
  • switched over to the config you provided me but still doesn’t allow https access :frowning:

Any ideas?

Hmm, OK. I’d next look at flyctl ip private, I have one IPv6 in here, which if memory serves was auto-allocated. I would assume the Fly proxy flows through that.

As far as I can remember, my apps just bind to 0.0.0.0 i.e. IPv4. It looks like you have that.

What happens if you use HTTPS; do you get a timeout, or an error, etc?

While I can’t spot any problems, I’m guessing that something is wrong with your toml.

If you don’t already have it, try installing jq. If you don’t want to install jq, you can manually extract the services section from the output of fly machines list --json.

Here’s what I see on a working app (there are two services sections listed as there are two machines):

% fly machine list --json | jq '.[].config.services'
[
  {
    "protocol": "tcp",
    "internal_port": 3000,
    "autostop": true,
    "autostart": true,
    "min_machines_running": 0,
    "ports": [
      {
        "port": 80,
        "handlers": [
          "http"
        ],
        "force_https": true
      },
      {
        "port": 443,
        "handlers": [
          "http",
          "tls"
        ]
      }
    ],
    "force_instance_key": null
  }
]
[
  {
    "protocol": "tcp",
    "internal_port": 3000,
    "autostop": true,
    "autostart": true,
    "min_machines_running": 0,
    "ports": [
      {
        "port": 80,
        "handlers": [
          "http"
        ],
        "force_https": true
      },
      {
        "port": 443,
        "handlers": [
          "http",
          "tls"
        ]
      }
    ],
    "force_instance_key": null
  }
]

3 hours ago a lot of my apps across several organisations went down with SSL errors. Might be related. If it’s still not working, then it’s probably something else

It definitely seems like an SSL issues.

curl https://my-app.fly.dev/ -v

* Host my-app.fly.dev:443 was resolved.
* IPv6: (none)
* IPv4: XX.XX.XX.XX
*   Trying XX.XX.XX.XX:443...
* Connected to my-app.fly.dev (XX.XX.XX.XX) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to my-app.fly.dev:443 
* Closing connection
curl: (35) LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to my-app.fly.dev:443 

flyctl ip private - outputs 3 ID’s and their IPV6 address. Which seems right, the ID’s correspond with the 2 web processes I have and 1 for the cron job.

This was the output of the command you gave me:

[
  {
    "protocol": "tcp",
    "internal_port": 8080,
    "ports": [
      {
        "port": 80,
        "handlers": [
          "http"
        ],
        "force_https": true
      },
      {
        "port": 443,
        "handlers": [
          "http",
          "tls"
        ]
      }
    ],
    "force_instance_key": null
  }
]
null
[
  {
    "protocol": "tcp",
    "internal_port": 8080,
    "ports": [
      {
        "port": 80,
        "handlers": [
          "http"
        ],
        "force_https": true
      },
      {
        "port": 443,
        "handlers": [
          "http",
          "tls"
        ]
      }
    ],
    "force_instance_key": null
  }
]

The fly.toml looks like this:

app = 'my-app'
primary_region = 'lhr'

[http_service]
  internal_port = 8080
  force_https = true
  processes = ["web"]

[processes]
web = "app"
cron = "supercronic -json /crontab"

[[vm]]
size = "shared-cpu-1x"
memory = "256mb"
cpu_kind = "shared"
cpus = 1

Out of curiosity halfer, do you have any certificates associated with your app? I’m wondering if mine got nuked when I bought the dedicated IPv4 and even though I’ve allocated the shared IPv4 it’s not set up the certs?

The docs suggest that I don’t need to add any certs myself: Public Network Services · Fly Docs

(post deleted by author)