Deploying Apps

Learn how to deploy any application to the Rouic Platform. The platform builds Docker images from your Git repository and performs blue-green deployments with zero downtime and automatic SSL.

Step-by-Step Deployment

1. Create a project

Navigate to the dashboard and click "New Project", or use the API:

Create project via API

bash
curl -X POST https://system.rouic.com/api/v1/projects \
  -H "Authorization: Bearer rk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My App",
    "slug": "my-app",
    "gitUrl": "https://github.com/you/my-app.git",
    "gitBranch": "main"
  }'

2. Add a service

In the project settings, add a service. A service is a single deployable unit (a Docker container). Configure:

  • Name — Identifier for this service (e.g., "web", "api", "worker")
  • Port — The port your application listens on inside the container
  • Public — Whether this service is exposed to the internet
  • Subdomain — The subdomain this service will be available at (e.g., my-app.rouic.com)
  • Dockerfile — Path to Dockerfile relative to build context (default: Dockerfile)
  • Build Context — Directory to use as Docker build context (default: .)

3. Set environment variables

Add any environment variables your app needs. Variables are encrypted at rest and injected at runtime. You can set them per environment (production, preview).

Set env vars during deploy

bash
curl -X POST https://system.rouic.com/api/v1/deploy \
  -H "Authorization: Bearer rk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "my-app",
    "ref": "main",
    "env": {
      "DATABASE_URL": "postgresql://user:pass@db:5432/mydb",
      "REDIS_URL": "redis://redis:6379",
      "NODE_ENV": "production"
    }
  }'

4. Trigger the deploy

Deployments can be triggered three ways:

  • Dashboard — Click the "Deploy" button on the project page
  • APIPOST /api/v1/deploy
  • GitHub Webhook — Push to a configured branch to auto-deploy

5. Monitor the deployment

Watch the deployment progress in the dashboard, or poll the status via API:

curl https://system.rouic.com/api/v1/deployments/DEPLOYMENT_ID \
  -H "Authorization: Bearer rk_YOUR_TOKEN"

The response includes the deployment status, build log, and the URL where your service is running.

Supported Project Types

Anything that can be containerized can be deployed. Here are examples of common project types:

Next.js

port 3000

Use standalone output for smaller images

Express / Node.js

port 3000-8080

Any Node.js HTTP server

Python (Django, Flask, FastAPI)

port 8000

Use gunicorn or uvicorn in production

Go

port 8080

Compile to a static binary for minimal image size

PHP (Laravel)

port 80

Use php-fpm with nginx

Ruby (Rails)

port 3000

Use puma as the application server

Rust

port 8080

Multi-stage builds recommended

Static Sites

port 80

Serve with nginx or caddy

Dockerfile Requirements

Your repository must contain a Dockerfile. The platform builds the image using standard Docker build and expects the container to listen on the port you configured for the service.

Next.js Example

FROM node:20-alpine AS base

# Install dependencies
FROM base AS deps
WORKDIR /app
COPY package.json package-lock.json* ./
RUN npm ci

# Build the application
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

# Production image
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs
EXPOSE 3000
ENV PORT=3000
CMD ["node", "server.js"]

Express Example

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["node", "index.js"]

Go Example

FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o server .

FROM alpine:3.19
WORKDIR /app
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]

Important: Your Dockerfile must not hardcode the port. Use the PORT environment variable or ensure it matches the port configured in your service settings.

Multi-Service Projects (Monorepos)

A single project can contain multiple services. This is useful for monorepos where you have a frontend and backend in the same repository.

Example monorepo structure

my-monorepo/
  frontend/
    Dockerfile
    package.json
    ...
  backend/
    Dockerfile
    package.json
    ...
  docker-compose.yml  (optional, not used by the platform)

For each service, set the build context to the subdirectory containing the Dockerfile. For example:

  • Service "web": build context = frontend/, port = 3000
  • Service "api": build context = backend/, port = 8080

You can deploy specific services using the services field in the deploy request, or omit it to deploy all services.

Deploy specific services

bash
curl -X POST https://system.rouic.com/api/v1/deploy \
  -H "Authorization: Bearer rk_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "project": "my-monorepo",
    "ref": "main",
    "services": ["web", "api"]
  }'

Environment Variables

Environment variables are encrypted at rest using AES-256-GCM and injected into containers at runtime. They are never included in the Docker image.

Setting variables

  • Dashboard: Go to project settings and add variables in the Environment Variables section.
  • API: Include an env object in your deploy request. Variables are upserted (created or updated).

Per-environment variables

Variables can be scoped to an environment (production or preview). Production variables apply to all deployments unless overridden by environment-specific values.

Built-in variables

The platform automatically injects these variables:

PORT=<configured port>
NODE_ENV=production
ROUIC_PROJECT=<project-slug>
ROUIC_SERVICE=<service-name>
ROUIC_DEPLOYMENT_ID=<deployment-id>

Custom Domains

By default, services are available at a subdomain of rouic.com. You can also configure custom domains.

Default subdomains

When you set a subdomain for a service, it becomes available at https://<subdomain>.rouic.com. SSL is automatically provisioned via Traefik and Let's Encrypt.

Custom domains

To use a custom domain, add a CNAME record pointing to the platform:

DNS configuration

; CNAME record
myapp.example.com.  CNAME  rouic.com.

Then add the domain in the service settings. SSL will be automatically provisioned.

Preview Deployments

Preview deployments are automatically created when a pull request is opened on a connected GitHub repository. Each PR gets its own isolated environment.

  • Preview URL format: https://pr-<number>-<slug>.rouic.com
  • Preview deployments use the same environment variables as production, but you can override specific values for the preview environment.
  • Preview deployments are automatically cleaned up when the PR is closed or merged.
  • The deploy status is reported back to GitHub as a commit check.

GitHub Webhook Setup

Enable push-to-deploy by configuring a GitHub webhook for your repository.

Step 1: Get your webhook URL

In the project settings under "Webhooks", copy the webhook URL. It will look like:

https://system.rouic.com/api/webhooks/github/<project-id>

Step 2: Add the webhook in GitHub

  1. Go to your repository on GitHub
  2. Navigate to Settings → Webhooks → Add webhook
  3. Paste the webhook URL in the Payload URL field
  4. Set Content type to application/json
  5. Copy the webhook secret from the project settings and paste it into the Secret field
  6. Select "Let me select individual events" and enable:
    • Push events
    • Pull request events
  7. Click "Add webhook"

Step 3: Test it

Push a commit to the configured branch. You should see a new deployment start in the dashboard within seconds.

Deployment Lifecycle

Every deployment goes through the following stages:

pendingbuildingdeployingrunning
pending

The deployment has been created and is waiting to be processed.

building

The Git repository is being cloned and the Docker image is being built. Build logs are available in real time.

deploying

The image has been built successfully. The platform is performing a blue-green deploy: starting the new container, waiting for it to pass health checks, then switching traffic.

running

The new container is live and serving traffic. The previous container has been stopped.

failed

The deployment failed during the build or deploy phase. Check the build log for details. The previous deployment remains live.

Rollbacks

If a deployment causes issues, you can roll back to any previous successful deployment:

  • Dashboard: Navigate to the deployment history and click "Rollback" on any previous deployment.
  • API: Trigger a new deployment with the ref set to the Git ref of the working version (commit SHA, tag, or branch).

Rollbacks are fast because the previous Docker image is still cached. The platform skips the build step and redeploys the cached image.

Resource Limits

Each service can have memory and CPU limits configured:

SettingDefaultDescription
Memory Limit512 MBMaximum memory the container can use. Formats: 256m, 512m, 1g, 2g
CPU Limit1.0Maximum CPU cores. E.g., 0.5 for half a core, 2.0 for two cores
Health Check/HTTP path to check during blue-green deploy. Returns 200 = healthy

If a container exceeds its memory limit, it will be killed and restarted by the runtime. Configure limits based on your application's needs.