Dockerfile
Deploy any application using a custom Dockerfile on Out Plane
This guide explains how to deploy any application on Out Plane using a custom Dockerfile. Use this approach when you need full control over your build process or when your language isn't covered by our framework-specific guides.
Prerequisites
- An Out Plane account
- A GitHub account with your application code
- A Dockerfile in your repository
Dockerfile Basics
A Dockerfile defines how to build your application container. Here's the basic structure:
# Base image
FROM node:20-alpine
# Set working directory
WORKDIR /app
# Copy dependency files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production
# Copy application code
COPY . .
# Expose port
EXPOSE 3000
# Start command
CMD ["node", "server.js"]Multi-Stage Builds
Use multi-stage builds to create smaller production images:
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]This separates build tools from the final image, reducing size significantly.
The .dockerignore File
Create a .dockerignore file to exclude unnecessary files from the build context:
# Dependencies
node_modules
vendor
# Version control
.git
.gitignore
# Environment files
.env
.env.*
# Build artifacts
dist
build
*.log
# IDE files
.vscode
.idea
*.swp
# OS files
.DS_Store
Thumbs.dbDeploy on Out Plane
Step 1: Push to GitHub
Ensure your repository contains:
- Your application code
- A
Dockerfilein the root (or specified subdirectory) - A
.dockerignorefile (recommended)
git add .
git commit -m "Add Dockerfile"
git push origin mainStep 2: Create Application
- Go to console.outplane.com
- Navigate to Applications
- Click Deploy Application
- Install the GitHub App if prompted
Step 3: Select Repository
- Find and select your repository
- Choose the branch to deploy
- Set Root Directory (where Dockerfile is located)
Step 4: Configure Build
| Setting | Value |
|---|---|
| Build Method | Select Dockerfile |
| Application Name | Enter a unique name |
| Port | The port your app listens on |
Step 5: Select Resources
| Instance | vCPU | RAM | Use Case |
|---|---|---|---|
| op-20 | 0.5 | 512 MB | Development |
| op-46 | 1 | 1 GB | Small apps |
| op-82 | 2 | 2 GB | Production |
| op-94 | 4 | 4 GB | High performance |
Step 6: Configure Scaling
- Min Scale:
0for scale-to-zero,1+for always-on - Max Scale: Maximum instances (1-10)
Step 7: Environment Variables
Add any environment variables your application needs.
Step 8: Deploy
Click Create Application to start the deployment.
Requirements for Your Application
Your application must:
1. Listen on the PORT environment variable
// Node.js
const port = process.env.PORT || 3000;# Python
port = int(os.environ.get("PORT", 8000))// Go
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}2. Bind to 0.0.0.0
Bind to all interfaces, not just localhost:
// Node.js
app.listen(port, '0.0.0.0');# Python/Uvicorn
uvicorn main:app --host 0.0.0.0 --port $PORT3. Log to stdout
Write logs to standard output. Out Plane captures and displays these in the console.
Best Practices
Use Specific Base Image Tags
# Good - specific version
FROM python:3.12-slim
# Avoid - mutable tag
FROM python:latestLeverage Layer Caching
Order your Dockerfile commands from least to most frequently changed:
# Dependencies change less often
COPY requirements.txt .
RUN pip install -r requirements.txt
# Source code changes frequently
COPY . .Run as Non-Root User
RUN adduser -D appuser
USER appuser
CMD ["./app"]Use EXPOSE for Documentation
EXPOSE 8080Note: The actual port is configured in Out Plane settings.
Language-Specific Examples
Ruby on Rails
FROM ruby:3.2-alpine AS builder
RUN apk add --no-cache build-base postgresql-dev
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install --deployment --without development test
FROM ruby:3.2-alpine
RUN apk add --no-cache postgresql-client
WORKDIR /app
COPY --from=builder /app/vendor/bundle vendor/bundle
COPY . .
ENV RAILS_ENV=production
EXPOSE 3000
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]Rust
FROM rust:1.75 AS builder
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
COPY src ./src
RUN cargo build --release
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*
COPY --from=builder /app/target/release/myapp /usr/local/bin/
EXPOSE 8080
CMD ["myapp"]PHP Laravel
FROM php:8.2-fpm-alpine AS builder
RUN apk add --no-cache composer
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader
FROM php:8.2-fpm-alpine
RUN docker-php-ext-install pdo pdo_pgsql
WORKDIR /app
COPY --from=builder /app/vendor vendor
COPY . .
EXPOSE 8000
CMD ["php", "artisan", "serve", "--host=0.0.0.0", "--port=8000"]Troubleshooting
Build fails
- Check build logs in the deployment detail page
- Verify Dockerfile syntax
- Ensure all dependencies are available
App not accessible
- Verify your app binds to
0.0.0.0 - Check that
PORTenvironment variable is used - Ensure the port in Out Plane matches your app
Image too large
- Use multi-stage builds
- Use Alpine-based images
- Add unnecessary files to
.dockerignore