Skip to content

Production & Docker ​

Deploying an Astris application is simple and standard.

1. Building Frontend Assets ​

Before running in production, compile your Vue 3 and Tailwind CSS assets into optimized bundles:

bash
npm run build

This compiles your frontend code into public/build/ with a production manifest (manifest.json).

2. Environment Configuration ​

In production, set your environment variables:

ini
APP_ENV=production
APP_DEBUG=false
APP_KEY=your_secure_32_byte_secret_key
SESSION_HTTPS_ONLY=true
DATABASE_URL=postgresql://user:password@db_host:5432/production_db

Database Driver Requirement ​

If connecting to PostgreSQL in production, install the driver package:

bash
uv add psycopg2-binary

For MySQL or MariaDB, install:

bash
uv add pymysql

Table Creation in Production (AUTO_CREATE_TABLES) ​

In local development, Astris automatically creates database tables on boot for speed. In production (APP_ENV=production), automatic table creation is disabled by default to safeguard your schema. Always apply database changes through versioned migrations.

3. Database Migrations in Production ​

Run all pending Alembic migrations before starting your production application:

bash
uv run orbit migrate

To verify the migration status and check that your database schema is up to date:

bash
uv run orbit migrate:status

4. Starting the Production Server (orbit serve --prod) ​

Launch your application in production mode using the Orbit CLI:

bash
uv run orbit serve --prod

This automatically:

  • Binds to 0.0.0.0
  • Disables development auto-reload and the Vite dev server
  • Enables multi-worker process management (defaults to 4 workers)

You can customize the port or worker count with flags:

bash
uv run orbit serve --prod --port 8000 --workers 8

5. Docker Deployment ​

Scaffolding with orbit make:docker ​

Astris can generate a production-ready Dockerfile and .dockerignore automatically:

bash
uv run orbit make:docker

For container deployment on Vercel, pass --vercel to generate Dockerfile.vercel:

bash
uv run orbit make:docker --vercel

Here is the official multi-stage Dockerfile generated by Astris:

dockerfile
# ==============================================================================
# Stage 1: Build Frontend Assets (Node.js & Vite)
# ==============================================================================
FROM node:24-alpine AS frontend-builder

WORKDIR /app

# Install npm dependencies first for optimal Docker layer caching
COPY package.json package-lock.json* ./
RUN if [ -f package-lock.json ]; then npm ci; else npm install; fi

# Copy frontend source files, styles, and configurations
COPY vite.config.* tsconfig.json* ./
COPY resources/ ./resources/
COPY public/ ./public/

# Compile production bundles and manifest into public/build/
RUN npm run build


# ==============================================================================
# Stage 2: Production Python Runtime
# ==============================================================================
FROM python:3.14-slim AS runner

# Install Astral uv binary
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

# Set production environment variables
ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    UV_COMPILE_BYTECODE=1 \
    UV_LINK_MODE=copy \
    PATH="/app/.venv/bin:$PATH" \
    PORT=8000 \
    APP_ENV=production

WORKDIR /app

# Create a non-root system user and group for container security
RUN groupadd -r astris && useradd -r -g astris -d /app -s /sbin/nologin astris

# Install Python dependencies first to leverage Docker layer caching
COPY pyproject.toml uv.lock* ./
RUN uv sync --frozen --no-dev --no-install-project || uv sync --no-dev --no-install-project

# Copy application source code, modules, and database configuration
COPY app/ ./app/
COPY database/ ./database/
COPY main.py ./
COPY README.md* ./

# Copy Inertia root template required for server-side HTML rendering
COPY resources/views/ ./resources/views/

# Copy all public static assets and compiled Vite bundles from frontend builder
COPY --from=frontend-builder /app/public ./public

# Finalize uv sync to install the project package into the virtual environment
RUN uv sync --frozen --no-dev || uv sync --no-dev

# Ensure writable directory for database operations and non-root ownership
RUN mkdir -p /app/database && chown -R astris:astris /app

# Switch to non-root user
USER astris

# Expose default application port
EXPOSE 8000

# Launch production server with dynamic port support
CMD ["sh", "-c", "exec orbit serve --prod --port ${PORT:-8000}"]

Next Steps ​

Released under the MIT License.