Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
105 posts found
Blue-Green Deployment: Two Environments with Nginx, App Service Slots and Instant Switchback
DevOps PART 04

Blue-Green Deployment: Two Environments with Nginx, App Service Slots and Instant Switchback

Blue-green installs the new version on the idle environment, runs a smoke test and switches traffic with a single reload; going back is the same reload. A preview port in Nginx, a smoke test with a version check, an error-free probe through switch and switchback, a 4 s request finishing on blue during the reload; App Service slot swap warm-up and slot setting pitfalls, a Service selector switch in Kubernetes, and the limit a shared database imposes.

8 Nov 2026 10 min 5
Rolling Deployments: Updating Servers One by One, maxSurge and maxUnavailable in Kubernetes
DevOps PART 03

Rolling Deployments: Updating Servers One by One, maxSurge and maxUnavailable in Kubernetes

A rolling deployment updates the fleet piece by piece; done right there is no outage, but two versions live side by side for a while. Three instances behind Nginx: a naive script dropped 2 of 90 GETs, while a script with drain and readiness checks passed 237 GETs and 90 POSTs without errors. Choosing maxSurge/maxUnavailable and minReadySeconds in Kubernetes, why exceeding progressDeadlineSeconds doesn't roll back, and when rolling is the wrong choice.

8 Nov 2026 12 min 6
Prerequisites for Zero Downtime: Graceful Shutdown, Readiness, Stateless Apps and Backward Compatibility
DevOps PART 02

Prerequisites for Zero Downtime: Graceful Shutdown, Readiness, Stateless Apps and Backward Compatibility

No deployment strategy can save an app that doesn't finish its work when stopping and doesn't tell the truth about being ready. With real runs: a 5 s request is cut with an RST when ShutdownTimeout is 2 s, Docker's 1 s wait produces exit code 137 (SIGKILL), readiness returns 503 during the drain while the API keeps serving 200, separate Data Protection key rings throw CryptographicException, and a deleted Angular chunk turns into a ChunkLoadError.

8 Nov 2026 13 min 5
Deploy vs Release: Why Downtime Happens and a Map of Deployment Strategies
DevOps PART 01

Deploy vs Release: Why Downtime Happens and a Map of Deployment Strategies

A deploy installs code in an environment, a release is when users see the new behavior; teams that can separate the two split the risk. In a single-container recreate deploy behind Nginx, 12 requests failed within 2.5 seconds. The five sources of downtime, a map of recreate, rolling, blue-green, canary, shadow, A/B and feature flags, a decision table, and the risk = blast radius × detection time calculation.

8 Nov 2026 10 min 4
Reading Old GitHub Actions Workflows: From set-output to GITHUB_OUTPUT, From Node 12/16/20 to Node 24
DevOps PART 16

Reading Old GitHub Actions Workflows: From set-output to GITHUB_OUTPUT, From Node 12/16/20 to Node 24

When updating an old workflow, change the runner label, action majors, SDK source, workflow commands and cache key together: ubuntu-18.04, @v2 actions and ::set-output either no longer work or warn in 2026. A 2018–2026 timeline, the Node 12→24 transitions, actionlint and act output for a 2021-style .NET 5 workflow, a checklist for moving to .NET 10 and a summary of 2026.

8 Nov 2026 11 min 5
Debugging, Speed and Cost in GitHub Actions: Debug Logging, act, Cache Strategy and Artifact Retention
DevOps PART 15

Debugging, Speed and Cost in GitHub Actions: Debug Logging, act, Cache Strategy and Artifact Retention

For debugging, turn on ACTIONS_STEP_DEBUG/ACTIONS_RUNNER_DEBUG for a single re-run, shorten the loop with act, build cache keys from the lock file hash with restore-keys, and keep artifacts briefly. Real cache miss, hit and restore-keys output from three act runs, a list of act's limits, the 10 GB quota and 7-day rule, retention, billing screens and a speed checklist.

8 Nov 2026 10 min 5
GitHub Actions Runners: Hosted Images, the ubuntu-latest Migration, ARM, Larger Runners and Self-Hosted
DevOps PART 14

GitHub Actions Runners: Hosted Images, the ubuntu-latest Migration, ARM, Larger Runners and Self-Hosted

Pin the runner label in release and deploy pipelines: ubuntu-latest moves from 24.04 to 26.04 between October 19 and November 19, 2026. The hosted image map, arm64 and larger runners, actionlint's label check, why a label in act is only a Docker image mapping, ephemeral self-hosted runners, the minimum version rule, ARC, 2026 prices and how multi-cloud affects IP allowlists.

8 Nov 2026 9 min 5
GitHub Actions Security: SHA Pinning, Lockfiles, pull_request_target and Preventing Script Injection
DevOps PART 13

GitHub Actions Security: SHA Pinning, Lockfiles, pull_request_target and Preventing Script Injection

Pin actions to full commit SHAs and keep them current with Dependabot and lockfiles, pass untrusted values through env: instead of run:, and never run PR code in pull_request_target. The tj-actions case, zizmor and actionlint findings, gh actions-lock, real script injection output under act, checkout@v7 and the December 2, 2026 change, a safe workflow_run pattern and read-only cache tokens.

8 Nov 2026 12 min 5
Reducing Duplication in GitHub Actions: Composite Actions, Reusable Workflows and YAML Anchors
DevOps PART 12

Reducing Duplication in GitHub Actions: Composite Actions, Reusable Workflows and YAML Anchors

Use a composite action to share steps, a reusable workflow to share jobs that need environments and approvals, and YAML anchors to repeat a block within one file. Bookstore's dotnet-ci action and reusable-deploy workflow under act; the risks of secrets: inherit, environment secrets, the 10-level/50-workflow limits, the $/ syntax, versioning and why merge keys are not supported.

8 Nov 2026 11 min 4
Deploying with GitHub Actions 2: Your Own Linux Server via SSH, Docker Images and GHCR
DevOps PART 11

Deploying with GitHub Actions 2: Your Own Linux Server via SSH, Docker Images and GHCR

Build the image once in GitHub Actions, push it to GHCR and send only the digest to the server over SSH; the server pulls it with Docker Compose and restarts. metadata-action, build-push-action and the gha cache backend (28 s down to 4 s), actions/attest, pinning known_hosts and what happens when the host key changes, rollback with .env.previous; real runs with act.

8 Nov 2026 12 min 4
Deploying with GitHub Actions 1: Azure App Service with OIDC and Secretless Cloud Access
DevOps PART 10

Deploying with GitHub Actions 1: Azure App Service with OIDC and Secretless Cloud Access

With OIDC, every job gets a signed, short-lived token from GitHub, and Azure verifies it against a federated credential and grants access without a client secret. id-token: write, sub claim formats, the July 2026 subject change with IDs, custom property claims, deploying to a staging slot, smoke testing and swapping; AWS and Google Cloud equivalents.

8 Nov 2026 12 min 5
GitHub Actions Environments: Protection Rules, Approvals and Deployment History
DevOps PART 09

GitHub Actions Environments: Protection Rules, Approvals and Deployment History

An environment is a named target that applies protection rules (required reviewers, wait timers, branch/tag policies) before a job reaches a runner, exposes its secrets only to that job and keeps a deployment history. Bookstore's staging/production deploy workflow, plan limits for private repositories, deployment: false, per-environment concurrency and queue: max; where act and actionlint stop, with real output.

8 Nov 2026 13 min 2
Blog Map