R
Railway13mo ago
bephrem

Sending http requests to new service

hey - I just deployed a service on railway & added a custom domain, from the deploy logs it looks like the application process is starting on & listening on 0.0.0.0:{PORT} (following https://docs.railway.app/deploy/exposing-your-app, using the railway provided env port for PORT. But sending external requests to the service on the /status health endpoint (that just returns a 200 status code and { "message": "OK" } does not work. There's a lot of in-between stuff that I'm wondering on - if I send a HTTP request to https://{HOST}/status I imagine that the request goes to port 443 then railway forwards that internally to the internal PORT...so my application should be picking it up. Everything works fine locally, just have this last small thing to work out on how packets are getting routed. Thanks
No description
Solution:
swap to a foreground process, you generally want that when in a docker container anyway
Jump to solution
28 Replies
Percy
Percy13mo ago
Project ID: 8f12a5b5-c874-4220-8712-b3709fa9bc73
bephrem
bephremOP13mo ago
project id: 8f12a5b5-c874-4220-8712-b3709fa9bc73
bephrem
bephremOP13mo ago
No description
bephrem
bephremOP13mo ago
No description
bephrem
bephremOP13mo ago
No description
bephrem
bephremOP13mo ago
I wonder if there is a way I can enter a virtual shell to see what's going on but ik that the application is living in abstraction-world & maybe not possible to shell into anywhere maybe I need to give the PORT env variable a concrete value & proxy? (https://docs.railway.app/deploy/exposing-your-app#tcp-proxying) (or maybe I need to map 443 -> to a concrete PORT value) But I imagine the above isn't necessary - probably something im missing
Brody
Brody13mo ago
is this just a plain http (not https) server?
bephrem
bephremOP13mo ago
plain http
Brody
Brody13mo ago
accepts http 1.1?
bephrem
bephremOP13mo ago
not sure - checking looks like it does curl -I --http1.1 localhost:8080 HTTP/1.1 404 Not Found date: Thu, 09 Nov 2023 21:20:04 GMT server: uvicorn content-type: text/plain curl -I --http1.1 https://{...host-redacted...}/status HTTP/1.1 503 Service Unavailable content-type: text/html x-railway-fallback: true content-length: 2942 date: Thu, 09 Nov 2023 21:20:33 GMT server: railway
Brody
Brody13mo ago
oh this is a uvicorn app?
bephrem
bephremOP13mo ago
locally runs uvicorn let me grab listen()
Brody
Brody13mo ago
on railway, are you starting uvicorn from within your code or from the command line?
bephrem
bephremOP13mo ago
def listen():
app_import_string = "src.server.core:app"

if Environment.is_production() or Environment.is_staging():
# background process
args = [
"gunicorn",
app_import_string,
"--workers",
"1",
"--worker-class",
"uvicorn.workers.UvicornWorker",
"--bind",
f"{HOSTNAME}:{PORT}",
]
logs_path = PathManager.service_logs_path()

with open(logs_path, "w") as logs_file:
subprocess.Popen(
args, stdout=logs_file, stderr=STDOUT, text=True, encoding="utf-8"
)

logger.info(f"started server on {HOSTNAME}:{PORT}")
else:
# foreground process (for development)
uvicorn.run(
app=app_import_string,
host=HOSTNAME,
port=PORT,
reload=True,
log_level="info",
)
def listen():
app_import_string = "src.server.core:app"

if Environment.is_production() or Environment.is_staging():
# background process
args = [
"gunicorn",
app_import_string,
"--workers",
"1",
"--worker-class",
"uvicorn.workers.UvicornWorker",
"--bind",
f"{HOSTNAME}:{PORT}",
]
logs_path = PathManager.service_logs_path()

with open(logs_path, "w") as logs_file:
subprocess.Popen(
args, stdout=logs_file, stderr=STDOUT, text=True, encoding="utf-8"
)

logger.info(f"started server on {HOSTNAME}:{PORT}")
else:
# foreground process (for development)
uvicorn.run(
app=app_import_string,
host=HOSTNAME,
port=PORT,
reload=True,
log_level="info",
)
railway will run python3 main.py which triggers the above - all env variables resolve fine (Environment is a wrapper class where I do some processing)
Brody
Brody13mo ago
background progress, maybe your app is exiting right after it starts
bephrem
bephremOP13mo ago
hmmm good point
Solution
Brody
Brody13mo ago
swap to a foreground process, you generally want that when in a docker container anyway
bephrem
bephremOP13mo ago
does the driver process of railway expect a foreground process to keep the driver alive? noted. I imagine Railway is running a driver process spawning the child, and it is just seeing the child exit
Brody
Brody13mo ago
railway is just docker containers, there's nothing super special going on
bephrem
bephremOP13mo ago
i see so is the container shutting down? I'm less familiar with docker (hands-on)
Brody
Brody13mo ago
what's the status of the deployment?
bephrem
bephremOP13mo ago
failed (btw working on switching to foreground running)
Brody
Brody13mo ago
oh well yeah lol forgot about the healthcheck haha let me know how that goes!
bephrem
bephremOP13mo ago
sure - will update. ok - back, still refactoring (grabbed food)
bephrem
bephremOP13mo ago
No description
bephrem
bephremOP13mo ago
looks like we're good running in the foreground
def listen():
app_import_string = "src.server.core:app"

if Environment.is_production() or Environment.is_staging():
# run gunicorn in the foreground (production)
subprocess.run(
(
f"gunicorn {app_import_string} "
f"--workers 1 "
f"--worker-class uvicorn.workers.UvicornWorker "
f"--bind {HOSTNAME}:{PORT} "
f"--access-logfile - " # '-' means log to stdout
f"--error-logfile - " # '-' means log to stderr
),
shell=True,
check=True,
)

logger.info(f"started server on {HOSTNAME}:{PORT}")
else:
# foreground uvicorn process (for development)
uvicorn.run(
app=app_import_string,
host=HOSTNAME,
port=PORT,
reload=True,
log_level="info",
)
def listen():
app_import_string = "src.server.core:app"

if Environment.is_production() or Environment.is_staging():
# run gunicorn in the foreground (production)
subprocess.run(
(
f"gunicorn {app_import_string} "
f"--workers 1 "
f"--worker-class uvicorn.workers.UvicornWorker "
f"--bind {HOSTNAME}:{PORT} "
f"--access-logfile - " # '-' means log to stdout
f"--error-logfile - " # '-' means log to stderr
),
shell=True,
check=True,
)

logger.info(f"started server on {HOSTNAME}:{PORT}")
else:
# foreground uvicorn process (for development)
uvicorn.run(
app=app_import_string,
host=HOSTNAME,
port=PORT,
reload=True,
log_level="info",
)
Brody
Brody13mo ago
awsome, glad you could solve this!
bephrem
bephremOP13mo ago
No description
Want results from more Discord servers?
Add your server