# How to deploy any Docker image on Ownkube

> How to deploy a containerized app on Ownkube from a Dockerfile, set the port and environment variables, configure a health check, and choose metered or reserved pricing.

- **Published:** 2026-08-25
- **Author:** Ownkube team
- **Category:** How-To
- **Tags:** docker, container, deploy, tutorial, ownkube-compute
- **Canonical URL:** https://ownkube.io/blog/deploy-docker-image
- **Cover:** https://ownkube.io/blog/deploy-docker-image.png

---
If your app already runs in a container, Ownkube builds it from your Dockerfile and runs it with a public URL, TLS, health checks, and [autoscaling](/blog/autoscale-cpu-memory) attached, no Kubernetes manifests to write. This walks through deploying a Dockerfile-based app end to end: connecting the repo, setting the port and environment variables, adding a health check, and choosing between metered and reserved pricing.

One thing worth being upfront about: today the shipped path to a running container is a Dockerfile in a connected GitHub or GitLab repository, which Ownkube builds and pushes to a managed registry for you. Pulling a prebuilt image straight from an external registry like Docker Hub or a bare ECR repo is on the roadmap, not available yet. If your image already exists somewhere else, put its Dockerfile (or the source it's built from) in a repo and point Ownkube at that instead. In practice that covers the large majority of "deploy this container" needs: anything you can express as a Dockerfile, Ownkube can build and run.

**TL;DR**

- Connect a GitHub or GitLab repo with a Dockerfile. Ownkube builds the image and pushes it to a managed ECR it runs for you, no registry account of your own required.
- If the repo has more than one Dockerfile, you pick which one at deploy time. If it has none, Ownkube's automatic build detects the language and builds it for you instead.
- Set the port your container listens on, add environment variables, and point a health check at a real endpoint before you call it done.
- Every deployment gets an auto-allocated `*.ownkube.app` hostname with automatic TLS the moment it's live.
- Choose metered pricing (bills on actual CPU and memory usage, cheapest for anything that idles) or a flat reserved box (predictable price, better for a workload that runs hot around the clock), per deployment.
- Pulling a prebuilt image from an external registry isn't shipped yet. Deploying from a Dockerfile in a repo is the way to get any containerized app running today.

## What "any Docker image" means on Ownkube right now

A [Dockerfile](https://docs.docker.com/reference/dockerfile/) is a complete, portable recipe for an image: `FROM`, your dependencies, your `COPY`, your `CMD`. If you can [build an image locally](https://docs.docker.com/build/building/best-practices/) with `docker build`, that same Dockerfile is what Ownkube needs, it runs the identical build server-side and pushes the result to the managed registry it manages for you. That's true whether the container underneath is a Node API, a Go binary, a Python worker, or a piece of open-source software you're self-hosting; if it builds from a Dockerfile, it deploys the same way.

What isn't available yet is connecting your own existing registry (Docker Hub, a bare ECR repository, GCR, ACR) and pointing a deployment at an image that's already sitting there. The registry-connect screen exists in the UI as a "coming soon" placeholder for every provider. Until that ships, get the image's Dockerfile into a repo Ownkube can build from. For most self-hosted tools this is trivial, the project's own repo usually already has one.

## Before you start

- A GitHub or GitLab repository with a working Dockerfile (or no Dockerfile at all, if you want Ownkube's automatic build to detect the language for you).
- The port your container listens on internally.
- Any environment variables or secrets the app needs at runtime.

## Step 1: connect your repository

From the Ownkube dashboard, start a new deployment and connect the repository if you haven't already. GitHub goes through the GitHub App (installable on more than one account or organization per Ownkube org, so a personal repo and a work org can both connect); GitLab goes through a direct account connection. Personal access tokens work for either if you'd rather not install an app.

## Step 2: choose the build target

```text
Deploy new -> Web service
Source: your-org/your-repo
Branch: main
Build target: Dockerfile (api/Dockerfile)
```

If the repo has a Dockerfile, Ownkube builds from it, and if there's more than one, you choose which. If there's none, the deploy flow switches to **Auto**, Ownkube detects the language and builds the image itself, no Dockerfile required.

## Step 3: set the port your container listens on

Tell Ownkube which port your container's process binds to internally. This is the one setting a containerized deploy can't skip, get it wrong and the health check and public hostname both fail to find your app.

```text
Container port: 8080
```

## Step 4: add environment variables

Set the [environment variables](/blog/manage-secrets-env-vars) your container reads at runtime on the deployment's **Environment** tab.

```text
DATABASE_URL=postgres://...
NODE_ENV=production
LOG_LEVEL=info
```

Variables are set per deployment. If you're running the same image in more than one environment (staging and production, for instance), set them again in each; there's no shared, environment-wide variable set yet.

## Step 5: configure a health check

On the deployment's **Settings** tab, under **Health checks**, point the readiness and liveness probes at a real endpoint your container serves.

```text
Health check path: /health
Initial delay: 5s
Timeout: 3s
```

Without one, Ownkube can only infer that the container process is running, not that it's actually able to serve a request. A health check is what keeps a slow-starting database migration from getting real traffic before it's ready.

## Step 6: choose metered or reserved pricing

Every deployment on Ownkube Compute picks one of two billing modes, and you can switch later.

**Metered** is the default and fits most containerized apps: you set CPU and memory limits as ceilings, and the bill follows actual usage, both CPU and memory, per minute. A container that idles most of the day (a small API, a side project) costs almost nothing on the CPU line while it's quiet.

**Reserved** puts the deployment on a fixed-size box, a Spark box (shared CPU, from $5 a month) or a Core box (dedicated CPU, from $58 a month), that bills a flat rate whether it's busy or idle. Pick this for a container that runs hot continuously, a queue worker that's always processing something, where the flat price is more predictable than watching a meter.

Both modes draw from the same prepaid wallet, so switching a deployment from metered to reserved (or back) later doesn't change how you pay, only what you're billed for.

## Step 7: deploy and check the public URL

Once the build finishes and the health check passes, the deployment's **Overview** tab shows its public hostname, an auto-allocated `*.ownkube.app` domain with automatic TLS issued the moment it goes live. No certificate to request, no DNS record to add for this default hostname.

```text
https://your-app-a1b2c3.ownkube.app
```

[Custom domains](/blog/automatic-https-custom-domain) (pointing your own domain at the app) are on the roadmap for Ownkube Compute specifically; they're shipped today on the own-cloud (BYOC) path if you're running on your own AWS account instead.

## What happens on the next push

Every subsequent push to the connected branch triggers a new build and a zero-downtime rollout, the old container keeps serving traffic until the new one passes its health check, then traffic switches over. If a build or rollout goes wrong, roll back to the previous revision from the deployment's Revisions tab.

## Moving the same container to your own AWS later

Nothing about deploying from a Dockerfile locks you into Ownkube-managed compute specifically. The same app, built the same way, can move to your own (or a customer's) AWS account later with no rewrite, and its logs, metrics, and health checks come with it. That's the option to have in your pocket if a workload eventually needs to sit inside a specific AWS account rather than Ownkube's shared compute. If you're weighing that decision now, our [comparison of Fly.io and running your own AWS](/blog/fly-io-alternative-own-aws) walks through when that tradeoff is worth making.

For teams evaluating platforms broadly rather than just this one workflow, [Railway vs Render vs Northflank](/blog/railway-vs-render-vs-northflank-2026) is a useful side-by-side if Docker deploys are one requirement among several you're comparing.

## FAQ

### Can I deploy a prebuilt Docker image straight from Docker Hub or ECR?

Not yet. Connecting an external registry is on the roadmap and shows as a "coming soon" stub in the UI today. The shipped path is a [Dockerfile](https://docs.docker.com/) in a connected GitHub or GitLab repo, Ownkube builds it and pushes to a managed registry for you.

### Does my repo need a Dockerfile?

No. If it has one, Ownkube builds from it. If it doesn't, Ownkube's automatic build detects the language and builds the image for you, no Dockerfile required either way.

### What if my repo has more than one Dockerfile?

You pick which one at deploy time, useful for a monorepo with separate services under different paths.

### How do I choose between metered and reserved pricing?

Metered fits a container that idles some of the time, since CPU cost drops close to zero while it's quiet. Reserved fits a container that runs continuously at similar load, since a flat box gives you a price that doesn't move. You choose per deployment and can switch later.

### Does the deployment get HTTPS automatically?

Yes. Every deployment gets an auto-allocated `*.ownkube.app` hostname with automatic TLS the moment it's live, no certificate request or DNS record needed for that default hostname.

## Where Ownkube fits

If your app is already containerized, getting it running is a Dockerfile, a port, and a health check away, with a live TLS URL attached before you've thought about a certificate. The one gap to plan around today is pulling an image straight from an external registry; until that ships, a Dockerfile in a repo gets you the same result for almost any container. [Deploy your first app](https://app.ownkube.io/login).