Guide

Docker Image or GitHub Repository: Which Way to Deploy, and the ARM64 Rule

SnapDeploy Team 2026-11-20 Updated 2026-11-20 7 min read
dockerdeploymentarm64githubfree-tier

SnapDeploy will take your app three ways: a GitHub repository, a public Docker image, or an uploaded archive. They end in the same place, a running container with an HTTPS URL, but they differ in what you control, how long a deploy takes, and one rule that trips people up more than any other: prebuilt images have to run on ARM64. This guide is the decision, with the trade-offs and the commands to check your image before you press Deploy.

The three paths

GitHub repository Public Docker image Upload (tarball or JAR)
What you giveA repo and branch; a Dockerfile if you have oneAn image name such as ghcr.io/you/app:1.4A zip of the source, or a built JAR
BuildOn the platform, from your Dockerfile or a generated oneNone; the image is pulled as-isOn the platform, same as a repository
Time to liveA few minutes (build plus start)About a minute (pull plus start)A few minutes
Redeploy on pushYes, automaticallyNo; you deploy a new tagNo; you upload again
ArchitectureHandled for you (built for ARM64)Must include an ARM64 variantHandled for you
Best forYour own apps; anything you change oftenOff-the-shelf software; images you already build in CIPrivate code without GitHub; Java builds from your machine

Path 1: a GitHub repository

This is the default and the right choice for code you are working on. Connect the repository, pick the branch, and every push builds and deploys. If the repository has a Dockerfile, it is used exactly as written and the port is read from its EXPOSE line. If it does not, one is generated for Node.js, Python, Java, Go, PHP, Ruby or a static HTML site, with the start command inferred from the project (Gunicorn for Django and Flask, Uvicorn for FastAPI, npm start for Node, java -jar for Maven and Gradle builds). The generated file is a sensible first deploy; our language guides explain when to replace it with your own, usually for a newer runtime version or a multi-stage build.

Builds count against the free tier's deploy allowance (5 per rolling 12 hours, failed builds included), so the habit that pays for itself is docker build on your machine before you push. Environment variables that the code needs are detected from the repository (Dockerfile ENV lines, a .env.example, framework configuration files) and offered to you before the first deploy, so the usual "it crashed because SECRET_KEY was missing" round trip is skipped.

Path 2: a public Docker image

Give an image reference from Docker Hub, GitHub Container Registry or any public registry, set the port and the environment variables, and the container is live in about a minute. No build, no deploy allowance spent on builds, and it is the natural path for software you did not write (an admin tool, a dashboard, a bot) or for images your own CI already produces. What you give up is the push-to-deploy loop: a new version is a new tag and a manual deploy.

The ARM64 rule. Containers run on ARM64. Official images on Docker Hub are multi-architecture and work unchanged; many third-party images are built for x86 only, and those fail at start with a message that says the image was built for a different CPU architecture. Check before you deploy:

docker manifest inspect ghcr.io/you/app:1.4 | grep -A1 '"architecture"'
# you want to see "arm64" among the platforms

If it is x86-only and you control the build, produce a multi-architecture image once and forget about it:

docker buildx build --platform linux/amd64,linux/arm64 -t ghcr.io/you/app:1.4 --push .

If you do not control the build, deploy the project's repository instead and let the platform build it for ARM64, or find the project's arm64 tag; most maintained images have one.

Path 3: an upload

A zip of the source goes through the same build as a repository, without GitHub in the loop; a JAR is wrapped in a Java runtime and started. It suits code that lives somewhere GitHub is not, and Java projects you would rather build locally. Redeploys are manual, so it is the least convenient path for anything that changes daily.

Choosing, in one paragraph

Your own app that you change: repository. Someone else's software, or an image your CI already builds for ARM64: image. Code that cannot be on GitHub: upload. If you are unsure, start with the repository; the generated Dockerfile gets a first version live, and switching to an image later is a matter of pointing the container at a tag.

What is the same on every path

  • The container reads PORT from the environment or you set the port in the container settings; the app must listen on 0.0.0.0, not localhost.
  • Environment variables are set in the dashboard and injected at start; database add-ons inject their connection string automatically.
  • The filesystem is ephemeral: anything that must survive a redeploy or a wake goes in a database or object storage.
  • Free containers sleep after 15 minutes without traffic and wake in about a minute; Always-On ($12/month per container) never sleeps and unlocks custom domains.
  • Build and runtime logs are in the dashboard; when a deploy fails, the reason (wrong port, x86 image, missing library, a start command pointing at a file that is not there) is stated at the top of the deployment.

Trying each path in five minutes

  1. Image: deploy nginx:alpine (multi-architecture) on port 80. You have a page in about a minute. Deploying a sample from the first-deploy wizard is the same path and does not count against deploys.
  2. Repository: push a folder with an index.html and no Dockerfile; watch the generated static build, then add your own Dockerfile and see it take over.
  3. Upload: zip the same folder and upload it. Same result, no GitHub involved.

Free tier: 4 containers, 512 MB and 0.25 vCPU each, 100 container-hours a month, 10 deploys a day, no card. Details on the free tier docs page; the Docker hosting page covers the image path in more depth.

Ready to Deploy?

Deploy free. 10 deploys a day, 100 hours a month, no credit card.

Run this yourself: Get a dedicated NVIDIA T4 (16 GB) for a flat $499/mo or A10G (24 GB) for $999/mo — never shared, never spot, no hourly metering. See dedicated GPU hosting →

One-click Ollama, vLLM, ComfyUI, Whisper, PyTorch & more — or deploy your own GitHub repo or Docker image. Compare plans.

FIRST OF ITS KIND

Sprint Pack — ₹99 for 24 hours

The first managed container PaaS to offer a one-time 24-hour Always-On pass under $5. Unlimited deploys + Always-On for one Small (512 MB) container — including WebSockets & real-time apps. No subscription, no auto-renewal. Stack two for 48 hours.

Need a managed database too? DB Sprint Pack — ₹99 / 12h for Postgres, MySQL, MariaDB, Mongo, Redis, or RabbitMQ.

Tip: Need 24 hours of Always-On for a demo, weekend, or quick test — or WebSockets & real-time apps? Sprint Pack is ₹99 one-time — no subscription, no auto-renewal.

Need a managed Postgres / MySQL / Mongo / Redis instead? DB Sprint Pack — ₹99 / 12h.

Take SnapDeploy with you

Deploy, monitor and wake your containers from your iPhone.

Download on the App Store

Get DevOps Tips & Updates

Container deployment guides, platform updates, and DevOps best practices. No spam.

Unsubscribe anytime. We respect your privacy.

More Articles