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

Paid plan required
Docker deployments are available on all paid plans. Starter: 1 container, Builder: 3, Pro: 15. See pricing for details.

Requirements

  1. Paid plan — Docker containers are available on all paid plans (Starter: 1, Builder: 3, Pro: 15)
  2. PORT environment variable — Telbase injects a PORT env var at runtime. Your container must listen on it.
  3. Dockerfile in project root — Telbase auto-detects Dockerfile in the directory you deploy from
bash
npx telbase deploy              # auto-detects Dockerfile
npx telbase deploy ./backend    # deploy a subdirectory with Dockerfile

The 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 ./src
Dockerfile — deploying from subdirectory
# If deploying from subdirectory: npx telbase deploy ./backend
COPY pom.xml .
COPY src ./src

Example 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=$PORT

Ruby / 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 $PORT

Rust

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 $PORT

PHP / 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=$PORT

Migrating from Other Platforms

If you have an existing Dockerfile from Railway, Fly.io, or Render, it probably works with minimal changes:

Common Issues

IssueCauseFix
Container exits immediatelyNot listening on $PORTUse shell form CMD with $PORT
Build fails on COPYWrong build contextCheck which directory you're deploying from
Port mismatch at runtimeHardcoded port numberReplace with $PORT environment variable
Native dependencies missingAlpine base imageUse Debian-based image (e.g. bookworm-slim)
Build too slowNo dependency cachingCopy dependency files first, install, then copy source

Next Steps