Build app and start machine without running the crashing Golang app

My golang app panics if it is unable to connect to my deployed and working MongoDB app. I am able to connect to the MongoDB app from my laptop using mongosh and it is listening on IPv6.

I would like to alter the fly.toml spec so that it builds virtual machine containing the Golang app, launches it without starting the app. I would like to be able to ssh in and start the app manually from a shell (currently the crash of the app leads to the virtual machine shutting down before I can ssh in). That way, I can examine environment variables, inspect the filesystem, and ping my MongoDB app to understand why the connection is failing.

My app is not in the top-level directory as in the example at https://github.com/fly-apps/go-example. Thus use of environment variables as shown in my fly.toml below:

app = "bar-web"
primary_region = "sea"

[build]
  builder = "paketobuildpacks/builder:base"
  buildpacks = ["gcr.io/paketo-buildpacks/go"]
  [build.args]
    BP_GO_BUILD_IMPORT_PATH = "cmd/webapp"
    BP_GO_TARGETS = "cmd/webapp"
    BP_LOG_LEVEL = "DEBUG"

[env]
  <snipped for brevity>
  MONGODB_HOST = "sea.foobardb.internal"
  MONGODB_PORT = "27017"
  MONGODB_PROTOCOL = "mongodb"
  MONGODB_USER_NAME = "barwebapp"
  WEB_APP_PORT = "8080"
  WEB_APP_STATIC_FILE_PATH = "static"
  WEB_APP_TEMPLATE_PATH = "templates"

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

[[files]]
  guest_path = "/templates/index.gohtml"
  local_path = "internal/webapp/templates/index.gohtml"
  secret_name = ""
  raw_value = ""

[[files]]
  guest_path = "/templates/dashboard.gohtml"
  local_path = "internal/webapp/templates/dashboard.gohtml"
  secret_name = ""
  raw_value = ""

[[files]]
  guest_path = "/templates/baredit.gohtml"
  local_path = "internal/webapp/templates/baredit.gohtml"
  secret_name = ""
  raw_value = ""

[[files]]
  guest_path = "/templates/bardisplay.gohtml"
  local_path = "internal/webapp/templates/bardisplay.gohtml"
  secret_name = ""
  raw_value = ""

[[files]]
  guest_path = "/static/images/favicon.ico"
  local_path = "internal/webapp/static/images/favicon.ico"
  secret_name = ""
  raw_value = ""

Is there a way to accomplish this?

Thank you.

@adpacifico Hello! The container terminating upon entrypoint process exit is by design. As far as I’m aware, containers don’t persist once their task is done.

What you could do temporarily is to set the entrypoint of the Docker image to /bin/sh or similar, which will make the container open a shell and wait for further instructions, as that shell wouldn’t exit until specifically told so.

Whilst I’m not familiar with Paketo, this seems to be doable like so:

https://paketo.io/docs/howto/nodejs/#specify-a-custom-entrypoint

Otherwise, perhaps using a custom Dockerfile and setting that there.

@devpikachu Thanks

I am not using a Dockerfile for the build. TLDR: I had some sort of issue using solely a Docker image when developing the app, even though the app runs fine on my laptop using a Docker image plus a Docker compose specification.

On your suggestion, I did look at the Paketo documentation for node.js (you pointed to) and tried using using `BP_LAUNCHPOINT = “/bin/sh”, but that didn’t change the shutting down of the virtual machine once the app found it couldn’t contact the MongoDB server and exited.

I suppose I could alter the app error handling code to wait ten minutes before exit in the event it cannot reach the MongoDB server, but that would limit possible avenues of investigation (unless I could stop the app).

Hey @adpacifico

Odd that Paketo didn’t respect that setting. Either way, I completely forgot about a feature within flyctl itself:

This will, by default, spin up an ephemeral machine instance with the latest deployed image and exec /bin/sleep inf as root on it. As long as that command exists in the container (i.e. not using scratch as base), it’ll wait indefinitely without exiting. After that, flyctl opens a SSH session to that ephemeral machine, allowing you to troubleshoot your installation.

After disconnecting (Ctrl+D), the machine will be destroyed automatically.

Example:

[andrei@fedora Projects]$ fly console -a nats-dev
Created an ephemeral machine 9080402b19e487 to run the console.
Connecting to fdaa:2:8fc2:a7b:6a:b77f:3491:2... complete
root@9080402b19e487:/# ls -la
total 76
drwxr-xr-x  22 root root 4096 Aug 20 06:18 .
drwxr-xr-x  22 root root 4096 Aug 20 06:18 ..
drwxr-xr-x   2 root root 4096 Aug 20 06:18 .fly
drwxr-xr-x   2 root root 4096 Aug 14 00:00 bin
drwxr-xr-x   2 root root 4096 Apr  2 11:55 boot
drwxr-xr-x  10 root root 2280 Aug 20 06:18 dev
drwxr-xr-x  30 root root 4096 Aug 20 06:18 etc
drwxr-xr-x   2 root root 4096 Apr  2 11:55 home
drwxr-xr-x   8 root root 4096 Aug 14 00:00 lib
drwxr-xr-x   2 root root 4096 Aug 14 00:00 lib64
drwxr-xr-x   2 root root 4096 Aug 14 00:00 media
drwxr-xr-x   2 root root 4096 Aug 14 00:00 mnt
drwxr-xr-x   2 root root 4096 Aug 14 00:00 opt
dr-xr-xr-x 108 root root    0 Aug 20 06:18 proc
drwx------   2 root root 4096 Aug 14 00:00 root
drwxr-xr-x   3 root root 4096 Aug 14 00:00 run
drwxr-xr-x   2 root root 4096 Aug 14 00:00 sbin
drwxr-xr-x   2 root root 4096 Aug 14 00:00 srv
dr-xr-xr-x  12 root root    0 Aug 20 06:18 sys
drwxrwxrwt   2 root root 4096 Aug 14 00:00 tmp
drwxr-xr-x  11 root root 4096 Aug 14 00:00 usr
drwxr-xr-x  11 root root 4096 Aug 14 00:00 var
root@9080402b19e487:/# 
logout
Waiting for ephemeral machine 9080402b19e487 to be destroyed ... done.
1 Like

Awesome! As it turns out, I managed to address my issue with a bit of trial and error based on log output. This would have been a huge time-saver had I known about it.