Back to Blog
Tutorial10 min read2026-07-05

How to Deploy a Streamlit Data App

Deploy a Streamlit data app to the cloud: configure the server for containers, handle WebSockets and session state, cache expensive work, and ship with one Git push.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

Streamlit turns Python scripts into interactive data apps with almost no front-end code. Deploying one to production is mostly about configuring the Streamlit server correctly for a container environment — it uses WebSockets and has a few flags that trip people up. Here's the complete setup.

How Streamlit serves

Streamlit runs its own web server (Tornado) and uses a WebSocket connection between the browser and the server to push updates. This matters for deployment: your platform's ingress must support WebSockets, and you must bind the server to all interfaces.

Server configuration for containers

The flags that make Streamlit work in production:

streamlit run app.py \
  --server.address=0.0.0.0 \
  --server.port=${PORT:-8501} \
  --server.headless=true \
  --server.enableCORS=false \
  --server.enableXsrfProtection=true
  • --server.address=0.0.0.0 so the platform can reach it.
  • --server.headless=true stops Streamlit from trying to open a browser and from prompting for an email on first run.
  • Bind --server.port to the platform-provided PORT.

You can put these in .streamlit/config.toml instead of the command line:

[server]
address = "0.0.0.0"
headless = true
port = 8501

Caching expensive work

Streamlit reruns your whole script on every interaction. Without caching, that means re-loading data and re-running models on every click. Use the cache decorators:

import streamlit as st

@st.cache_data(ttl=600)
def load_dataframe():
    return expensive_query()

@st.cache_resource
def get_model():
    return load_model()

Use cache_data for serializable results (DataFrames, JSON) and cache_resource for non-serializable singletons (ML models, DB connections).

Session state

Streamlit's st.session_state is per-user-session and in-memory. It resets when the app restarts and is not shared across instances. If you scale to multiple replicas, a user could land on different instances between requests — so don't rely on session state for anything that must persist. Put durable data in a database.

Dockerfile

FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8501
CMD ["streamlit", "run", "app.py", "--server.address=0.0.0.0", "--server.port=8501", "--server.headless=true"]

Deploying on PandaStack

Streamlit is a container app — it's a stateful server process, not a static site:

  1. 1Connect your repo as a container app in the [dashboard](https://dashboard.pandastack.io). PandaStack auto-detects Python and installs from requirements.txt.
  2. 2Set the start command to the streamlit run line above, binding PORT.
  3. 3PandaStack's Kong ingress handles the WebSocket upgrade, so live updates work without extra configuration, and you get automatic SSL.
  4. 4For data, attach a managed PostgreSQL database and read DATABASE_URL; cache the connection with @st.cache_resource.

Scale-to-zero and Streamlit

Because Streamlit holds per-session WebSocket state, scale-to-zero on the free tier means an idle app cold-starts on the next visit and any open session is lost. For a personal dashboard that's fine. For a shared internal tool people keep open, run it on a tier that stays warm, and keep replica count at 1 unless your data is fully externalized — multi-replica Streamlit needs sticky sessions to avoid breaking the WebSocket.

ConcernRecommendation
WebSocketSupported via ingress; keep on
Replicas1 unless state is externalized
Heavy computeCache with cache_data/cache_resource
PersistenceManaged database, not session state

References

  • [Streamlit: Deploy with Docker](https://docs.streamlit.io/deploy/tutorials/docker)
  • [Streamlit configuration reference](https://docs.streamlit.io/develop/api-reference/configuration/config.toml)
  • [Streamlit caching: cache_data and cache_resource](https://docs.streamlit.io/develop/concepts/architecture/caching)
  • [Streamlit session state](https://docs.streamlit.io/develop/concepts/architecture/session-state)

Put your Streamlit dashboard online with WebSockets and a managed database on PandaStack's free tier — start at [dashboard.pandastack.io](https://dashboard.pandastack.io).

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also