Docker + Streamlit not working
I am trying to deploy a Streamlit app with Docker. The image runs fine locally. I let Railway detect the build and run command. Railway indicates the image is deployed successfully, get I cannot access via provided URL.
Project ID: ac828fce-6f54-43e9-825c-ac4871d226ba
Project ID: ac828fce-6f54-43e9-825c-ac4871d226ba
43 Replies
Project ID:
ac828fce-6f54-43e9-825c-ac4871d226ba
Dockerfile is here:
503 status code?
hi @Brody thanks for the response. I was actually able to resolve. the key was specifying the port in the dockerfile:
CMD streamlit run --server.port $PORT frontend.py
i saw this in the heroku knowledge base for streamlit, figured the same applied for Railway
awsome, glad you got it solved
hmm. still getting issues with this actually. Can I use the start command to specify the docker run command? I'm not sure how you are e.g. mapping ports or passing in env variables. But certain things aren't working as expected
you can't specific a docker run command.
and you can't only forward one internal port to the external 443 port over https
so it's totally possible that you won't be able to run streamlit, I have no experience with it myself so I don't actually know if it would be possible
I actually have the streamlit service running on Railway now. Service ID: 0eaf8754-ca2d-45cc-a225-737e2d7b3a49
the issue is, i need to define env variables so the staging/prod builds point to the correct staging/prod endpoints. but I'm not entirely sure how I do this with Railway.
i've read the docs (it's only one page on Docker). i've tried setting env variables in the Railway console, etc. is there maybe a sample dockerfile i can reference?
i've read the docs (it's only one page on Docker). i've tried setting env variables in the Railway console, etc. is there maybe a sample dockerfile i can reference?
ARG ARG_ENVIRONMENT="staging"
ARG ARG_PASSWORD="fake"
FROM python:3.9-slim
WORKDIR /app
COPY . /app
RUN pip3 install -r requirements.txt
EXPOSE 8501
ENV APP_ENVIRONMENT=$ARG_ENVIRONMENT
ENV APP_PASSWORD=$ARG_PASSWORD
ENV PORT=8501
CMD streamlit run frontend.py --server.port $PORT
i see in teh doc it says to pass in the args before from, but that's it. and that's what i try to do here
railway provides a
RAILWAY_ENVIRONMENT
variable
https://docs.railway.app/develop/variables#railway-provided-variablesah. that could work. do i define that as an ARG before the FROM in the file? or do I put this in the Variables section of the service in the dashboard?
its injected by railway, no need to define it yourself in the service, you would still need to reference it with ARG tho
in the dockerfile?
yes, where else would you use
ARG
lolbecause the app itself needs it. its a value i have in my .env file, and it uses this to pull the correct value for my backend api.
ha. yeah i figured u meant the dockerfile. but im new to railway so i dont know if there's somewhere else its used
in python you would just use
os.environ
or whatever method you wantyeah it works in python no problem.
ARG RAILWAY_ENVIRONMENT=
ARG APP_PASSWORD= "fake"
FROM python:3.9-slim
WORKDIR /app
COPY . /app
RUN pip3 install -r requirements.txt
EXPOSE 8501
ENV APP_ENVIRONMENT= $RAILWAY_ENVIRONMENT
ENV APP_PASSWORD= $ARG_PASSWORD
CMD streamlit run frontend.py --server.port $PORT
so would it be somethign like this? where i keep my python .env name as APP_ENVIRONMENT. Railway injects the RAILWAY_ENVIORNMENT at build time, passes that to my Env that my app can use?
please enclose your code (or dockerfiles) with triple back-ticks
ah ok perfect i'll try it!
thakns. really hope this works.
keep in mind i still have zero clue what streamlit is
its just a python frontend app
i assume since its dockerized the actual implementation shouldnt matter a ton
ive been a longtime heroku user. hate it. i just found Railway this week and love it so far. but gotta get my apps ported else im stuck with heroku
i see, well ill do my best to help with what i can
ugh. still not working. the deployment picked up my local configs:
vs. using the RAILWAY_ENVIRONMENT i passed in
vs. using the RAILWAY_ENVIRONMENT i passed in
are you trying to access
APP_ENVIRONMENT
after the build stage?yes
okay okay I see what's gone wrong
i thought i passed RAILWAY_ENV..
ok
you only need to do ARG <variable> in your dockerfile if you want to use that service variable during build, but you aren't using any variables during build
once your app starts, all variables are available automatically, service variables, railway variables, everything
correct. i just need them during runtime. but i cant call 'docker run' so im not sure how to do it
^
no need to docker run, after start, all variables are available, there's nothing you need to do but grab them in code like you normally would
its not working though. i have an APP_ENVIRONMENT that i use in a config.py file to determine the env value and then give me the right e.g. URLs to use in the app based on environment. when i deploy to railway, the app isn't finding this env so it defaults to localhost.
so im trying to set this through the dockerfile. also the railway dashboard. can't do docker-run. so i cant figure out how to get this value to my app.
i'll try to add some additonal logging to verify what the value is when i get it. but i'm pretty sure its nulls so defauilts to my localhost
no need for setting any variables in the dockerfile, if you aren't using them during build (you are not)
for example, if you set a service variable TEST = 123
you could access that variable with os.getenv("TEST")
like I said, there is no need for doing anything with docker run (you can't anyway) railway will automatically inject all your service variables, and all the service variables (along with railways variables) will be available at run time
so i removed my dockerfile ARGS. and set the env variables as Service Variables in Railway
and then my code looks like this
so the Railway service variables should be available to me at runtime, so that APP_ENVIRONMENT should be 'staging' so i should get my staging urls.
but what has been happening is it defaults to local (localhost/8000)
print the entire os.eviron dictionary
check if your variables are in the printed text
ah
i think i see the issue...
do tell
looks like its working 🙂
thanks for the help!
so see the file above. i actually dont call load_dotenv initially, so i dont ever set the env. it just goes to the case statement. i needed to call load_dotenv initially to get the local/railway env value, then use this to load the proper .env.[environment] file
ugh
i had just ported to railway, and dont use a ton of docker, so i was convinced this was the issue. when ultimately everything on railway was configured correctly 🙂
thanks for the patience. got this owrking now! on to the next issue 🙂
awsome glad you got it solved, and glad i was of some assistance