|
@@ -0,0 +1,62 @@
|
|
|
+# This Dockerfile is used to deploy a single-container Reflex app instance
|
|
|
+# to services like Render, Railway, Heroku, GCP, and others.
|
|
|
+
|
|
|
+# If the service expects a different port, provide it here (f.e Render expects port 10000)
|
|
|
+ARG PORT=8080
|
|
|
+# Only set for local/direct access. When TLS is used, the API_URL is assumed to be the same as the frontend.
|
|
|
+ARG API_URL
|
|
|
+
|
|
|
+# It uses a reverse proxy to serve the frontend statically and proxy to backend
|
|
|
+# from a single exposed port, expecting TLS termination to be handled at the
|
|
|
+# edge by the given platform.
|
|
|
+FROM python:3.13 as builder
|
|
|
+
|
|
|
+RUN mkdir -p /app/.web
|
|
|
+RUN python -m venv /app/.venv
|
|
|
+ENV PATH="/app/.venv/bin:$PATH"
|
|
|
+
|
|
|
+WORKDIR /app
|
|
|
+
|
|
|
+# Install python app requirements and reflex in the container
|
|
|
+COPY requirements.txt .
|
|
|
+RUN pip install -r requirements.txt
|
|
|
+
|
|
|
+# Install reflex helper utilities like bun/fnm/node
|
|
|
+COPY rxconfig.py ./
|
|
|
+RUN reflex init
|
|
|
+
|
|
|
+# Install pre-cached frontend dependencies (if exist)
|
|
|
+COPY *.web/bun.lockb *.web/package.json .web/
|
|
|
+RUN if [ -f .web/bun.lockb ]; then cd .web && ~/.local/share/reflex/bun/bin/bun install --frozen-lockfile; fi
|
|
|
+
|
|
|
+# Copy local context to `/app` inside container (see .dockerignore)
|
|
|
+COPY . .
|
|
|
+
|
|
|
+ARG PORT API_URL
|
|
|
+# Download other npm dependencies and compile frontend
|
|
|
+RUN API_URL=${API_URL:-http://localhost:$PORT} reflex export --loglevel debug --frontend-only --no-zip && mv .web/_static/* /srv/ && rm -rf .web
|
|
|
+
|
|
|
+
|
|
|
+# Final image with only necessary files
|
|
|
+FROM python:3.13-slim
|
|
|
+
|
|
|
+# Install Caddy and redis server inside image
|
|
|
+RUN apt-get update -y && apt-get install -y caddy redis-server && rm -rf /var/lib/apt/lists/*
|
|
|
+
|
|
|
+ARG PORT API_URL
|
|
|
+ENV PATH="/app/.venv/bin:$PATH" PORT=$PORT API_URL=${API_URL:-http://localhost:$PORT} REDIS_URL=redis://localhost PYTHONUNBUFFERED=1
|
|
|
+
|
|
|
+WORKDIR /app
|
|
|
+COPY --from=builder /app /app
|
|
|
+COPY --from=builder /srv /srv
|
|
|
+
|
|
|
+# Needed until Reflex properly passes SIGTERM on backend.
|
|
|
+STOPSIGNAL SIGKILL
|
|
|
+
|
|
|
+EXPOSE $PORT
|
|
|
+
|
|
|
+# Apply migrations before starting the backend.
|
|
|
+CMD [ -d alembic ] && reflex db migrate; \
|
|
|
+ caddy start && \
|
|
|
+ redis-server --daemonize yes && \
|
|
|
+ exec reflex run --env prod --backend-only
|