Loading...

Deploy · 8 min read

Deploy from Git: push to your branch, the new version goes live

Git deployment removes the most error-prone step in shipping software: the manual one. Instead of building on your laptop, uploading files and restarting something over SSH, you connect a repository once and every push to the chosen branch builds a fresh image and replaces the running app. This guide explains what actually happens between your push and the live site, what your repository needs for it to work, how to keep production separate from your daily work, and — the part most guides skip — how to tell which link in the chain broke when a push does not show up.

8 min read Beginner friendly Updated

Deploy from Git: push to your branch, the new version goes live

What "deploy from Git" actually means

For most of the industry's history, deployment meant a person doing a sequence by hand: build locally, copy files to a server, run a migration, restart a process, hope nothing was missed. Every step was a chance to do it slightly differently than last time — and the difference between "works on my machine" and a broken production site usually lived in exactly those steps.

Git deployment replaces that sequence with a rule: the branch is the source of truth, and whatever is on it is what runs. You do not upload anything. You push, and the platform does the identical build every single time. The repeatability is the point — not the convenience.

What happens between your push and the live app

The chain is short and worth knowing, because when something goes wrong you want to know which link to look at.

Your push reaches the repository, which notifies us. We check whether that specific repository and branch is connected to an app; if it is, a build starts. The build runs in an isolated sandbox — your code never shares a process with anyone else's — and produces a container image from your Dockerfile. Only when the image is ready does the platform start the new version and retire the old one. If the build fails, nothing is replaced: the previous version keeps serving traffic, which is the behaviour you want at 2 a.m.

Access is short-lived by design: the credential used to read your repository is minted at deploy time rather than stored, so a token sitting in our database cannot outlive its usefulness.

What your repository needs

Deploy from Git: push to your branch, the new version goes live — What your repository needs
Managed platforms and container apps on cdn.com.tr.

One thing, mainly: a **Dockerfile**. It is the recipe that turns your source into a runnable image — base image, dependencies, build step, start command. If your project does not have one yet, writing it is a one-time task and the same file works on your laptop.

Two details save people the most time. First, your app must listen on the port you told the platform about, and on all interfaces (`0.0.0.0`) rather than only `localhost` — a container that binds to localhost is unreachable from outside itself. Second, anything secret (database URLs, API keys) belongs in environment variables, not in the image: images get rebuilt and moved around, and a secret baked into one is a secret you cannot rotate.

A multi-service project works the same way through a Compose file — every service that has no prebuilt image needs a buildable Dockerfile, and the stack comes up wired together.

Branches: keep production away from your daily work

This is where teams get hurt, and the fix is a decision rather than a feature. If production is connected to the branch you develop on, every half-finished commit ships. Connect production to a branch you only merge into when you mean it — commonly `main` while daily work happens on feature branches, or a dedicated `production` branch if `main` is where you iterate.

The useful mental test: "if I push right now, am I comfortable with visitors seeing it?" If the answer is ever no for the connected branch, the branch is wrong, not the process.

A release flow that keeps production boring

# gundelik is: feature dalinda
git checkout -b feature/yeni-fiyatlandirma
git commit -am "pricing page"
git push origin feature/yeni-fiyatlandirma   # deploy TETIKLEMEZ

# yayina hazir oldugunda
git checkout main
git merge feature/yeni-fiyatlandirma
git push origin main                         # deploy BU push ile baslar

When a push does not show up

Deployment feels like magic until it silently does nothing, so diagnose in the order the chain runs.

Start at the end: did a build even start? If no build appears for your push, the link that broke is the connection — the repository or branch is not the one attached, or the integration lost access (a revoked installation, a repository renamed or transferred). If a build started and failed, the build log tells you exactly where; the most common causes are a Dockerfile step that works locally because of a file your `.dockerignore` excludes, or a dependency install that needs a credential the build does not have. If the build succeeded but you still see the old version, you are almost certainly looking at a cached response rather than a stale app — request the page with a cache-buster or check the cache status header before suspecting the deploy.

One non-obvious case worth knowing: re-running a deploy for a commit that already failed will not fix it by itself. The commit is the input; if the input is unchanged, so is the result. Push a fix — even an empty commit — rather than retrying the same one.

Check state and force a deploy from the terminal

# calisan uygulamanin durumu
cdnctl container apps list --account <uuid>

# son deploy ne yapti
cdnctl container apps logs --account <uuid> --app <app_uuid>

# elle yeniden dagit (ayni commit)
cdnctl container apps deploy --account <uuid> --app <app_uuid>

What you get once it is boring

The real payoff of git deployment is not speed, it is that deploying stops being an event. When shipping is a push, small changes go out on their own instead of piling into a risky monthly release — and small changes are the ones you can debug, because when something breaks you know exactly which commit did it.

It also makes rollback a normal operation rather than an emergency: the previous image is still there, and going back is a deploy like any other. Teams that ship daily are not braver than teams that ship monthly; they have made each individual deploy small enough to be uninteresting.

Frequently asked questions

Do I need a Dockerfile, or can the platform guess how to build my app?

You need a Dockerfile. We do not guess a build for you — the file is explicit about the base image, dependencies and start command, which is exactly why the build is reproducible. The same file builds identically on your machine.

What happens to the running app while a new version builds?

It keeps serving. The new version replaces the old one only after the image is built successfully; a failed build leaves production exactly as it was.

Can I deploy without pushing — for example to re-run the last version?

Yes. A deploy can be triggered manually from the panel or with cdnctl, using the same commit. Useful after changing an environment variable, which does not create a new commit.

How do I keep secrets out of the repository?

Put them in environment variables on the app, not in the Dockerfile or the code. Anything baked into an image travels with that image and cannot be rotated without a rebuild.

I pushed but nothing happened. Where do I look first?

Check whether a build started at all. No build means a connection problem (wrong branch, revoked access, renamed repo). A failed build points at the build log. A successful build with an old-looking site usually means you are seeing a cached response.