Deploy any Docker image on Bahriya
If your application builds into a container image, it runs on Bahriya — no matter the language or framework. This is the general case behind every other quickstart: whether you write Go, Python, Ruby, Rust, Java, or PHP, you deploy the same way. Package the app, declare the port, pick your regions.
If your application builds into a container image, it runs on Bahriya — no matter the language or framework. This is the general case behind every other quickstart: whether you write Go, Python, Ruby, Rust, Java, or PHP, you deploy the same way. Package the app, declare the port, pick your regions.
Use this guide when your stack is not covered by a dedicated quickstart, or when you already have a Dockerfile and just want to ship it.
What your image needs
An HTTP container has to satisfy a few requirements for the platform to route traffic to it and keep it healthy:
- Listen on a port. Pick the port your application serves on and declare it when you deploy.
- Bind to
0.0.0.0, not127.0.0.1. A process bound to loopback only is unreachable from outside the container, so no traffic can arrive. - Expose a health path. Provide an HTTP path that returns a 2xx status when the app is ready to serve (for example
/healthz). Bahriya uses it to decide when a new deployment is ready. - Log to standard output and error. Write logs to stdout/stderr rather than to a file inside the container, so they are captured and viewable.
If you do not need to accept public traffic — a queue consumer or a background processor — deploy it as a worker instead. For scheduled tasks, use a cron job.
A minimal Dockerfile
The exact contents depend on your language, but the shape is always the same: start from a base image, add your application, expose the port, and set the command that starts the server. A small Go service, for example:
# Build stage
FROM golang:1.23 AS build
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /server .
# Runtime stage
FROM gcr.io/distroless/static
COPY --from=build /server /server
EXPOSE 8080
CMD ["/server"]Whatever your base image, make sure the process it launches binds to 0.0.0.0 on the port you declare.
Public or private image
- Public images need no credentials — Bahriya pulls them directly. Leave the registry unset when you deploy.
- Private images need a registry with a server, username, and password. Add it to your project and deploy the credentials to the same regions as your container, then reference it when you create the container.
See Deploy your first container for the registry and secret set-up in full.
Deploy from the Console
- Create a new HTTP container in your project.
- Set the image to your image reference including tag, and select a registry if it is private.
- Set the port to whatever your application listens on, and the health check path to a route that returns 2xx.
- Choose regions, set CPU and memory, and create the container.
Once running, it is reachable at https://<handle>.<region>.x.on.bahriya.app.
Deploy with Reis
Set --port to your application's port — the example uses 8080, the Reis default:
reis container:create \
--type http \
--name "My Service" \
--handle my-service \
--image ghcr.io/myorg/service:1.0.0 \
--project my-project \
--registry ghcr \
--port 8080 \
--healthcheck /healthz \
--cpu 500 \
--memory 512 \
--replicas 2 \
--max_replicas 8 \
--regions falkenstein-1 \
--regions virginia-1Drop --registry for public images. --max_replicas enables autoscaling.
Environment variables, secrets, and domains
- Pass configuration as environment variables and sensitive values as secrets, injected at runtime and deployed per region.
- Serve the container on your own hostname with Custom domain setup.
Next steps
- HTTP containers — hostnames, autoscaling, and security.
- Health checks — how readiness is evaluated.
- Registries — pulling private images.
- Deploy an HTTP container with flags — the full Reis reference.