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
bashcurl -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
bashcurl -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
- API — POST
/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 3000Use standalone output for smaller images
Express / Node.js
port 3000-8080Any Node.js HTTP server
Python (Django, Flask, FastAPI)
port 8000Use gunicorn or uvicorn in production
Go
port 8080Compile to a static binary for minimal image size
PHP (Laravel)
port 80Use php-fpm with nginx
Ruby (Rails)
port 3000Use puma as the application server
Rust
port 8080Multi-stage builds recommended
Static Sites
port 80Serve 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
bashcurl -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
envobject 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
- Go to your repository on GitHub
- Navigate to Settings → Webhooks → Add webhook
- Paste the webhook URL in the Payload URL field
- Set Content type to
application/json - Copy the webhook secret from the project settings and paste it into the Secret field
- Select "Let me select individual events" and enable:
- Push events
- Pull request events
- 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:
The deployment has been created and is waiting to be processed.
The Git repository is being cloned and the Docker image is being built. Build logs are available in real time.
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.
The new container is live and serving traffic. The previous container has been stopped.
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
refset 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:
| Setting | Default | Description |
|---|---|---|
| Memory Limit | 512 MB | Maximum memory the container can use. Formats: 256m, 512m, 1g, 2g |
| CPU Limit | 1.0 | Maximum 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.
Next up
Databases →See also
API Reference