Docker Containers
Deploy any language or framework to Telbase with a Dockerfile. Java, Ruby, Rust, PHP, C#, Elixir — if it runs in a container, it runs on Telbase.
When to Use Docker
- Your framework isn't auto-detected (Java, Ruby, Rust, PHP, C#, Elixir, Scala, etc.)
- You need custom system dependencies or native libraries (.so, .dll)
- You have an existing Dockerfile from another platform (Railway, Fly.io, Render)
- You want full control over the build and runtime environment
Paid plan required
Docker deployments are available on all paid plans. Starter: 1 container, Builder: 3, Pro: 15. See pricing for details.
Requirements
- Paid plan — Docker containers are available on all paid plans (Starter: 1, Builder: 3, Pro: 15)
- PORT environment variable — Telbase injects a
PORTenv var at runtime. Your container must listen on it. - Dockerfile in project root — Telbase auto-detects
Dockerfilein the directory you deploy from
bash
npx telbase deploy # auto-detects Dockerfile
npx telbase deploy ./backend # deploy a subdirectory with DockerfileThe ENTRYPOINT Pitfall
Docker's exec form (["command", "arg"]) does not expand environment variables. This means $PORT stays as a literal string, and your container fails to bind to the right port.
Dockerfile
# WRONG — exec form does not expand $PORT
ENTRYPOINT ["java", "-jar", "app.jar", "--server.port=$PORT"]
# RIGHT — shell form expands $PORT
CMD java -jar app.jar --server.port=$PORT
# RIGHT — explicit shell wrapper with exec form
ENTRYPOINT ["/bin/sh", "-c", "java -jar app.jar --server.port=$PORT"]Rule of thumb
Use shell form (no brackets) for any CMD or ENTRYPOINT that references environment variables like
$PORT.Build Context
When you deploy from a subdirectory, the build context is that subdirectory. All COPY and ADD paths in your Dockerfile are relative to it.
Dockerfile — deploying from project root
# If deploying from project root: npx telbase deploy
COPY backend/pom.xml .
COPY backend/src ./srcDockerfile — deploying from subdirectory
# If deploying from subdirectory: npx telbase deploy ./backend
COPY pom.xml .
COPY src ./srcExample Dockerfiles
Quick-start Dockerfiles for common languages. Each uses a multi-stage build to keep the final image small.
Java / Spring Boot
Dockerfile — Java 21 + Spring Boot
FROM maven:3.9-eclipse-temurin-21 AS build
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src ./src
RUN mvn package -DskipTests
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
CMD java -jar app.jar --server.port=$PORTRuby / Rails
Dockerfile — Ruby 3.3 + Rails
FROM ruby:3.3
WORKDIR /app
COPY Gemfile Gemfile.lock ./
RUN bundle install
COPY . .
RUN bundle exec rake assets:precompile
CMD bundle exec puma -p $PORTRust
Dockerfile — Rust (multi-stage)
FROM rust:1.77 AS build
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=build /app/target/release/myapp /usr/local/bin/
CMD myapp --port $PORTPHP / Laravel
Dockerfile — PHP 8.3 + Laravel
FROM php:8.3-cli
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev
COPY . .
CMD php artisan serve --host=0.0.0.0 --port=$PORTMigrating from Other Platforms
If you have an existing Dockerfile from Railway, Fly.io, or Render, it probably works with minimal changes:
- Remove platform config — delete
railway.toml,fly.toml,render.yaml. Telbase ignores these but they add confusion. - Replace hardcoded ports — change any hardcoded port (like
EXPOSE 8080+CMD app --port 8080) to use$PORT - Move secrets — platform dashboard secrets become:
npx telbase env set KEY=value - Health checks — Telbase defaults to
GET /on$PORT. Customize with--health-path /api/health
Common Issues
| Issue | Cause | Fix |
|---|---|---|
| Container exits immediately | Not listening on $PORT | Use shell form CMD with $PORT |
| Build fails on COPY | Wrong build context | Check which directory you're deploying from |
| Port mismatch at runtime | Hardcoded port number | Replace with $PORT environment variable |
| Native dependencies missing | Alpine base image | Use Debian-based image (e.g. bookworm-slim) |
| Build too slow | No dependency caching | Copy dependency files first, install, then copy source |
Next Steps
- Supported Frameworks — auto-detected frameworks that don't need Docker
- Databases — auto-provisioning PostgreSQL and SQLite
- Custom Domains — add your own domain with automatic SSL
- CLI Reference — every command and flag