Plugin Dockerfile
Container configuration for CyanPrint plugins
Plugin Dockerfile
Every plugin runs in a Docker container. The Dockerfile defines the runtime environment.
Basic Dockerfile
FROM oven/bun:1.0.11WORKDIR /app# Required: Mark as CyanPrint pluginLABEL cyanprint.dev=true# Install dependenciesCOPY package.json .COPY bun.lockb .RUN bun install# Copy plugin codeCOPY . .# Run pluginCMD ["bun", "run", "index.ts"]
Required Elements
Base Image
Use a Bun or Node.js base image:
# Bun (recommended)FROM oven/bun:1.0.11# Node.jsFROM node:20-alpine# With Alpine variant (smaller image)FROM oven/bun:1.0.11-alpine
CyanPrint Label
The cyanprint.dev=true label identifies the image as a CyanPrint component. The executor uses this label to filter and discover CyanPrint plugin images via the Docker API:
LABEL cyanprint.dev=true
Working Directory
Set a consistent working directory:
WORKDIR /app
Entry Point
Define how the plugin runs:
# Using BunCMD ["bun", "run", "index.ts"]# Using Node.jsCMD ["node", "index.js"]# Using tsx (TypeScript with Node)CMD ["npx", "tsx", "index.ts"]
Optimized Dockerfile
Multi-stage Build
Multi-stage builds can reduce final image size by copying only the necessary artifacts:
# Build stageFROM oven/bun:1.0.11 AS builderWORKDIR /appCOPY package.json .COPY bun.lockb .RUN bun installCOPY . .RUN bun build ./index.ts --outdir ./dist --target bun# Runtime stageFROM oven/bun:1.0.11-alpineWORKDIR /appLABEL cyanprint.dev=trueCOPY --from=builder /app/dist ./distCOPY --from=builder /app/node_modules ./node_modulesCMD ["bun", "run", "dist/index.js"]
Multi-stage builds add complexity. For most plugins, a simple single-stage build is sufficient and easier to maintain.
With Additional Tools
The apt-get command works with Debian-based images. For Alpine images, use apk add instead.
FROM oven/bun:1.0.11WORKDIR /appLABEL cyanprint.dev=true# Install additional tools if needed (Debian-based)RUN apt-get update && apt-get install -y \git \&& rm -rf /var/lib/apt/lists/*COPY package.json .COPY bun.lockb .RUN bun installCOPY . .CMD ["bun", "run", "index.ts"]
Minimal Image
FROM oven/bun:1.0.11-alpineWORKDIR /appLABEL cyanprint.dev=trueCOPY package.json .COPY bun.lockb .RUN bun installCOPY index.ts .CMD ["bun", "run", "index.ts"]
Dockerignore
Create a .dockerignore file to exclude unnecessary files. Here is a comprehensive template:
# Dependencies (must include to exclude)node_modules# Git.git.gitignore# IDE.idea.vscode# Documentation*.mddocs/# OS files.DS_StoreThumbs.db# Environment.env.env.*# Test files*.test.ts*.spec.ts__tests__/
A minimal .dockerignore with just node_modules, .idea, and .vscode is often sufficient for simple plugins. Exclude bun.lockb only if you want fresh dependency resolution.
Size Optimization
| Technique | Approximate Savings | Trade-off |
|---|---|---|
| Alpine base | ~100MB (estimated) | May need musl compatibility |
| Minimal copy | Varies | Manual optimization |
| Multi-stage | ~30% (estimated) | More complex build |
Keep images small for faster pulls. Plugins are downloaded on every generation. Savings are approximate and vary based on dependencies.
Environment Variables
Pass environment variables to the plugin:
FROM oven/bun:1.0.11WORKDIR /appLABEL cyanprint.dev=true# Set environment variablesENV NODE_ENV=productionCOPY package.json .COPY bun.lockb .RUN bun installCOPY . .CMD ["bun", "run", "index.ts"]
Port Configuration
Plugins communicate on port 5552 and serve the POST /api/plug endpoint:
# Expose plugin port (informational)EXPOSE 5552
Port 5552 is the standard plugin port with the /api/plug endpoint. Don't change it unless you have a specific reason.
Related
- Project Structure - Directory layout
- Push to Registry - Publishing
- First Plugin - Create your first plugin