Am trying deploy a Vapor 4 app on a standard Google Compute Engine instance and am getting an error at launch. I imagine its a permissions issue but there are few clues as to which they are.
$swift run Run
swift runServer failed to start: The operation could not be completed. (NIO.IOError error 1.)
[ NOTICE ] Server starting on [http://127.0.0.1:8080]
I've also attempted
$ sudo .build/release/Run
$ vapor run serve --env production
With the same result.
The reason why I'm on GCE instead of Heroku or some such is that its both an HTTP and socket server app thus need to expose multiple ports, which GCI allows with its configurable firewall rules.
Even tho Vapor is showing server is running on 8080 I'm not getting responses, perhaps due to the SwiftNIO error 1
as I'm binding to the GCE public IP here instead of the private IP. When I bind to the private IP, the error goes away and the server successfully binds to the port. However, when I try to connect to the public IP on that port no connection is possible.
The server failed to start error is weird but for connecting - however, are you attempting to connect from the same machine or a different one? You need to set the hostname to 0.0.0.0 if you want to be able to connect from outside the machine
Thanks guys. The firewall was configured correctly, but it wasn't attaching to the instance correctly.
When I use the private address in the bind call it works there and the error goes away, tho that is cumbersome to manage. It seems I can reach the machine remotely on that port with the private IP hard coded.
I can use 0.0.0.0 and it will just use the network interface the VM has to bind to? I am seeing that work on the VM, but when I try that locally on my Mac, its not reachable (tho the Mac has multiple network interfaces).
In this case, it's entirely possible that your GCE instance does not know what its public IP address is, and so binding to it will fail. Is your public IP address visible on any interface if you run ifconfig?
Thanks Cory. the public IP is not listed on any interface on the machine. But, public clients connecting to the public IP with the vapor server bound to the private IP (or 0.0.0.0) do connect and get data.
But another question, why are the connections flapping for the client 2 connections that I'm running? e.g.:
This is a signal that the public IP is not owned by your machine, but by GCE itself. This is why the bind to the public IP was failing: your machine doesn't think it owns that IP. Binding to 0.0.0.0 is a good solution here.
Seems like one or the other of the clients is closing the connection. Nothing exciting here, you still only ever have two connections outstanding. You're at no risk of running out of FDs here.
The interesting bit on the flapping is those clients are no longer connected. One is a telnet session I started but then stopped. Even if I reboot the instance and start the vapor app the flapping just starts with no new connections attempted.
While I wouldn't entirely be worried about this given that it seems to 'just work' but there is logic in the app that upon each new client a set of initial data has to be sent, which this flapping would flood the client with startup info when it shouldn't. Am wondering if this is something between the public and private IP address specific to GCE and can be remedied.
It may be worth logging whether there is any data being transferred, as well as trying to isolate what these two IP addresses have to do with your infrastructure. These could well be a TCP liveness probe from the GCE infrastructure, attempting to determine whether your app is still running by means of making inbound TCP connections.