DEV Community

Kunal
Kunal

Posted on Originally published at kunalganglani.com

How to Build a Linux Migration Plan for Developers [2026]

Originally published at kunalganglani.com — read it there for inline code, hero image, and live links.

How to Build a Linux Migration Plan for Developers [2026]

You’re going to end this guide with a working Linux dev machine that can:

  • build and run your existing projects in Dev Containers
  • use the same shell/editor setup via dotfiles
  • authenticate to GitHub/GitLab with SSH (and optionally signed commits)
  • run GPU workloads locally (including inside containers)
  • survive the three classic laptop landmines: sleep, audio, and drivers

Plan for a weekend to get to “productive”, then 1–2 weeks of low-risk hardening while your old OS stays as a rollback path. This post is a linux migration plan for developers that assumes you have real work on Monday.

What is a Linux migration plan for developers?

A Linux migration plan for developers is a phased approach to moving your day-to-day programming workflow (repos, tooling, credentials, containers, GPU compute, and laptop hardware quirks) onto a Linux desktop while keeping a rollback path at every step.

The no-regret phased plan (with rollback every week)

Most Linux-switch content is either “just install Ubuntu” or “use containers”. That advice is incomplete. The only sane way to switch is to treat it like a production migration: staged rollout, verification gates, and an escape hatch.

Here’s the plan I recommend in 2026.

  1. Phase 0 (1–2 hours): Inventory + backups + a rollback decision

    • Pick your fallback: dual-boot, VM, remote Linux host over SSH, or stay on Windows with WSL2.
    • Back up your home directory, SSH keys, password manager export recovery codes, and any GPG keys.
    • Write down the 5 projects you must be able to build and test.
    • Verification: you can restore one file from backup. Do it once.
  2. Phase 1 (half day): Boot Linux without committing

    • Live USB first (or VM). Confirm Wi‑Fi, Bluetooth, external monitor, and suspend/wake.
    • If you’re going to dual-boot, confirm your disk layout and encryption plan.
    • Verification: 30 minutes on battery, external display works, audio output works.
  3. Phase 2 (1 day): Make your dev environment portable

    • Dotfiles repo (shell, git, editor settings) without secrets.
    • SSH agent strategy (password manager or ssh-agent).
    • Install the container runtime (Docker or Podman) and Dev Containers.
    • Verification: clone repo via SSH, open in container, run tests.
  4. Phase 3 (1–2 days): Daily driver + laptop hardening

    • Fix sleep state (S2Idle vs deep), power profiles, and audio stack.
    • Confirm VPN/SSO for work.
    • Verification: close lid 10 times. It wakes 10 times.
  5. Phase 4 (optional, 2–3 hours): GPU compute + GPU containers

    • Install NVIDIA driver the “boring” way. Then NVIDIA Container Toolkit.
    • Verify nvidia-smi on host, then in a container.
    • Verification: a CUDA container sees the GPU.

If you want a deeper “safety-first” approach for running risky tooling, I also wrote an AI agents adjacent guide on isolating tool execution in an AI agent sandbox Linux VM.

Should developers use Linux in 2026?

Yes, if you care about reproducibility, containers, and local AI workflows.

The thing that changed is not the Linux kernel. It’s the workflow around it:

  • Dev Containers let you keep the same toolchain across Windows/macOS/Linux and CI.
  • Laptop defaults improved: Wayland is normal on mainstream distros now, PipeWire replaced the old audio zoo, and driver install is less of a forum quest.
  • Local AI is a real reason. When your workflow includes a local LLM or GPU-backed tooling, Linux tends to be the least weird environment.

Also, developer interest is spiking again. A recent “switch to Linux” video by Charles (NetworkChuck) pulled huge attention fast. I don’t take YouTube as truth, but I do take it as signal.

My opinionated take: Linux is not “better” in the abstract. It’s better when you optimize for control and repeatability, and you’re willing to fix 2–3 hardware paper cuts once.

What is the easiest Linux distro to switch to from Windows for programming?

Pick boring. Pick what your teammates can help you debug.

  • Ubuntu LTS: safest default for developers who want drivers, corporate VPNs, and a huge package ecosystem.
  • Fedora Workstation: great if you want newer kernels and a cleaner base. In 2026 it’s a strong “modern Linux desktop” pick.
  • Immutable desktops (like Fedora Silverblue): excellent if you want an OS that’s hard to break. But you’re opting into a different mental model (ostree, layering).
  • Arch-based: amazing if you want full control. Also a higher chance you become your own IT department.

If you want my distro-specific take, start with Ubuntu 24.04 LTS Developer Review: Toolchain Caught Up [2026] and compare it to Linux Mint vs Ubuntu for Developers [2026 Compared].

Concrete rule: if you need NVIDIA + containers + fewer surprises, Ubuntu LTS is still the path of least regret.

Is dual boot or VM better for switching to Linux?

It depends on what you’re trying to de-risk.

Here’s the comparison I give people on my team.

Option Best for Pros Cons My 2026 default
Dual boot Full performance, GPU, battery life True native drivers, easiest GPU compute Partitioning risk, reboot context switch If you have 1 laptop and need GPU
VM (VirtualBox/VMware) Trying Linux UI + basics Zero disk risk, fast rollback Weak battery, weaker I/O, GPU passthrough pain If you’re unsure you’ll like Linux
Remote Linux host over SSH “Same laptop, different OS” Your laptop stays stable; Linux is clean Needs good network; local USB/devices tricky Best for cautious enterprise setups
Windows + WSL2 Staying on Windows but wanting Linux tooling Great CLI experience; low friction GUI + USB + GPU can be inconsistent per stack If corporate Windows is non-negotiable

If your workflow includes GPU containers or you want real laptop battery life, VMs are the first thing that feels fake.

If your main anxiety is “I can’t break my work machine”, remote host + SSH is the least stressful bridge. You can even combine it with Dev Containers.

What should I back up before I repartition or install Linux?

Backups are boring until they’re the only thing that matters.

My minimum list before you touch partitions:

  • Your entire home directory (or at least Documents, Desktop, repos, and .config)
  • SSH keys (~/.ssh) and known_hosts
  • GPG keys (if you sign commits)
  • Browser/exported passwords only if you’re moving away from a password manager
  • Work VPN configs, SSO recovery codes, and any 2FA backup codes
  • A list of installed apps and licenses

If you have any database state locally (Postgres, Redis, etc.), don’t “hope” you’ll remember. Dump it. If you want a boring, reliable pattern: How to Back Up PostgreSQL With pgBackRest [S3 + Restore Test].

Verification step (seriously): restore a single file to a different folder and open it. If you don’t test restores, you don’t have backups.

How do I transfer my SSH keys and Git config to Linux?

Don’t cargo-cult-copy your whole ~/.ssh directory and call it done. Do it deliberately.

SSH keys: the safe migration pattern

  1. Copy your private key files (id_ed25519, etc.) to the new machine with a trusted channel.
  2. Fix permissions: private keys should be 600, the .ssh dir should be 700.
  3. Decide how you’ll unlock keys:
    • password manager integration (cleanest for most people)
    • ssh-agent + ssh-add on login
    • hardware keys (FIDO2) for work accounts

A good north star is: your keys are usable, but not lying around in dotfiles.

Git config: keep it small, keep it portable

I keep .gitconfig mostly to:

  • name + email
  • default branch/pull behavior
  • signing config (optional)
  • include other files by OS (includeIf)

If you’re already investing in clean tooling, it’s worth reading my workflow post on CI/CD hygiene and secrets scanning: How to Set Up gitleaks + pre-commit + CI [2026].

How do I structure dotfiles so a reinstall doesn’t hurt?

Dotfiles are the difference between “Linux is fun” and “Linux is a time sink.” But only if you treat them like a product.

My rules:

  • Dotfiles repo contains zero secrets. Not API keys, not npmrc tokens, not cloud creds.
  • Bootstrap order matters:
    1. shell + terminal (zsh/bash, prompt)
    2. git
    3. ssh
    4. editor settings
    5. language toolchains (Node/Python/Rust)
  • One install script that is idempotent. Run it 10 times. It should still work.

For secret material, use:

  • your password manager
  • age for encrypted files
  • environment injection via direnv/mise

If you want a reproducible terminal setup that survives distro swaps, I’d pair this post with Reproducible Terminal Dev Environment: direnv + mise [2026].

Docker vs Podman on a dev laptop: what breaks?

This is where ideology meets reality.

  • Docker Desktop is not the point on Linux. On Linux you typically run Docker Engine (dockerd) directly.
  • Podman is daemonless and can run rootless. That’s great. It also means certain assumptions and integrations behave differently.

What breaks most often on laptops:

  1. Volume permissions: rootless Podman can surprise you if your container expects host paths with certain ownership.
  2. Networking differences: port mapping works, but debugging network namespaces can be more “Linux-y”.
  3. Compose workflows: Podman supports Compose-style workflows, but your team’s scripts and docs may assume Docker.
  4. GPU integration: Docker has more “copy-paste known good” examples. Podman works, but you need to configure it explicitly.

My stance: if you’re migrating and you want fewer unknowns, start with Docker. Once you’re stable, experiment with Podman.

If you want the deeper runtime comparison, I’ve got a full breakdown here: Docker vs Podman 2026: Which Container Runtime Should You Use?.

Dev Containers: the bridge that makes migration low-risk

This is the trick that makes the whole windows to linux developer setup story less scary. You stop installing pet toolchains on your laptop. Your laptop becomes a thin host for containers.

The official Microsoft guide is still the best starting point: VS Code Dev Containers documentation.

What matters for migration is that Dev Containers can open:

  • a local folder
  • a remote SSH host
  • even a WSL folder

That’s exactly what a phased migration needs.

Getting started (devcontainers)

On Linux, I want you to get to a single outcome as quickly as possible: open one repo inside a container and run tests.

The minimum ingredients:

  • VS Code
  • Docker or Podman
  • the Dev Containers extension

Once it works for one repo, you can standardize.

For a remote-first setup (great for cautious rollouts), see: [How to Set Up Self Hosted DevContainers 2026](/blog/self-hosted-devcontainers-ssh-vscode).

Create a devcontainer.json file

A devcontainer.json file is the contract for your environment. You’re defining:

  • base image
  • mounts
  • ports
  • editor extensions
  • post-create commands

I’m not pasting a giant template here because it turns into decoration. Start from a small one, then grow it per project.

If you maintain multiple services, treat the devcontainer config like you treat infra: review it, version it, and test it.

Dev Container Features

Dev Container Features are the right way to add common tooling (git, language runtimes, CLIs) without baking your own images from scratch.

This is where the “no-regret” part really shows up.

  • New laptop? Same dev container.
  • Changed distro? Same dev container.
  • Onboarding a teammate? Same dev container.

Pre-building dev container images

Prebuilds are the difference between “containers are nice” and “containers are the default.”

If your image build takes 8–15 minutes, people will quietly stop using it. Prebuilds move that cost to CI.

Even if you don’t use a hosted prebuild service, you can do this in your own CI system: build the image on every merge to main, push it to a registry, and have devcontainers reference it.

Managing extensions

You want your devcontainer to declare extensions that are part of the project experience.

Rule of thumb:

  • If an extension is required to work on the repo, declare it.
  • If it’s personal preference, keep it in your local settings.

That separation reduces churn and prevents the “why do I have 47 random extensions installed” problem.

Forwarding or publishing a port

Port forwarding is where Dev Containers stop being “dev tooling” and start being “a laptop virtualization layer.”

A concrete checklist that catches issues early:

  • backend API on localhost:3000
  • db admin UI on localhost:8080
  • hot reload actually hot reloads across bind mounts

If hot reload feels slow, the culprit is often file watching across mounts. Fixing it is project-specific, but the first move is always: reduce filesystem churn and make sure you’re not doing millions of tiny file ops on a networked mount.

Personalizing with dotfile repositories

VS Code Dev Containers has a first-class mechanism for dotfiles bootstrapping. Microsoft documents a workflow specifically for “personalizing with dotfile repositories” in the Dev Containers docs: dotfile repositories.

This is perfect for migration:

  • your container gets your shell + prompt
  • you don’t reconfigure every laptop rebuild
  • you can version the setup like code

Again: dotfiles yes, secrets no.

Known limitations

Dev Containers are not magic. The limitations I see most in real teams:

  • hardware access (USB devices, serial ports) can be fiddly
  • file I/O performance can degrade if you mount giant monorepos with bad watcher defaults
  • GUI apps inside containers are still a niche workflow

That’s fine. You’re using containers to stabilize the dev toolchain, not to recreate your entire desktop.

Troubleshooting

The best troubleshooting pattern is: isolate whether the failure is in (1) Linux host, (2) container runtime, or (3) the container image.

  • If Docker/Podman can’t pull images: runtime/network.
  • If the container runs but your toolchain fails: image/config.
  • If everything works in container but your laptop is glitchy: host hardware stack.

Now let’s talk about the host breakpoints that actually ruin migrations.

The top laptop breakpoints (sleep, audio, Wi‑Fi/Bluetooth, monitors)

If Linux migrations fail, they don’t fail because apt install git is hard. They fail because the laptop feels unreliable.

Here are the first fixes I try.

Sleep/wake is broken: s2idle vs deep

Modern laptops often default to a light suspend mode that looks like sleep but drains battery and sometimes fails to wake.

The Linux kernel documents multiple sleep states, including Suspend-to-Idle (S2Idle) and deeper suspend variants like standby/suspend-to-RAM. The official kernel docs are worth skimming: Rafael J. Wysocki explains what each sleep state really does.

First checks:

  • What states are supported?
    • cat /sys/power/mem_sleep
  • If you see [s2idle] deep, you can try switching to deep via a kernel parameter or system config, depending on distro.

Verification loop:

  • close lid, wait 2 minutes, open lid
  • do that 10 times
  • then do it once on battery after 30 minutes idle

If it fails once, it’s not “mostly fine.” It’s broken.

No sound after install: PipeWire basics

In 2026, most mainstream distros are PipeWire-first. PipeWire is “a low-level server and multimedia framework for handling audio and video streams on Linux,” created by Wim Taymans. That’s the center of the modern Linux audio stack.

Reference: Wim Taymans.

First fixes (in order):

  • confirm output device isn’t muted or set to the wrong profile
  • restart user services (often WirePlumber is the culprit)
  • test with a wired headset vs Bluetooth to isolate the path

Bluetooth headsets are their own mini-universe. If your headset connects but has no mic, you’re usually fighting profiles (HFP/HSP vs A2DP) and app permissions.

External monitors + fractional scaling weirdness

If you’re coming from macOS, Linux scaling will feel different.

What I look for:

  • Wayland vs X11 session: try both once
  • dock firmware (yes, really)
  • GPU driver alignment (especially on hybrid graphics laptops)

If you live on a dock, consider reading my hardware workflow notes from the dev desk side: Thunderbolt 5 Docking Station Review: I Tested the Ugreen Revodok Max 213 as a Developer Hub [2026].

NVIDIA GPU compute on Linux (host + containers)

If you don’t need GPU compute, skip this entire section and enjoy your life.

If you do need it, do it properly. The GPU workflow most developers want in 2026 is:

  1. NVIDIA driver installed via distro packages
  2. CUDA works on the host (nvidia-smi works)
  3. CUDA works in a container

Installation (NVIDIA Container Toolkit)

NVIDIA’s official guidance is clear: install the NVIDIA GPU driver for your distro, preferably via the package manager, then install the NVIDIA Container Toolkit.

The toolkit install guide is here: NVIDIA documentation (NVIDIA Container Toolkit install guide).

Concrete details that matter:

  • The guide provides distro-specific steps for apt (Ubuntu/Debian), dnf (RHEL/Fedora/Amazon Linux), and zypper (openSUSE/SLE).
  • It supports multiple runtimes. Not just Docker.

Configuration (NVIDIA Container Toolkit)

The migration footgun is thinking “driver installed” means “GPU containers work.” They are different layers.

You need to configure your container runtime to use the NVIDIA hooks.

Also, NVIDIA explicitly documents how to configure Podman for GPU containers. If you’re going the daemonless route, follow the official instructions instead of random gists.

Same source: NVIDIA documentation (NVIDIA Container Toolkit install guide).

Here’s the verification checklist I use:

  • nvidia-smi shows your GPU on the host
  • your container runtime can run a CUDA base image
  • inside the container, nvidia-smi works

If your endgame is local AI dev, you’ll also want to think about the ecosystem split (CUDA vs alternatives). My ROCm/CUDA compatibility view is here: ROCm vs CUDA 2026: Consumer GPU Compatibility Matrix.

Here’s a solid CUDA-focused walkthrough video if you learn better by watching a full run-through:

[YOUTUBE:poPLvev_MvU|Unlocking CUDA Your Ultimate Guide]

The post-move validation checklist (don’t skip this)

You don’t “finish” a migration when the desktop boots. You finish when your machine is boring.

Run this checklist after each phase, and again after a kernel update.

  • Networking: Wi‑Fi works on reboot. VPN works. DNS isn’t flaky.
  • Sleep: lid close/open works 10/10 times.
  • Audio: speakers + wired headset work. Bluetooth output works.
  • Monitors: dock + external monitor works at expected refresh rate.
  • Repos: git clone via SSH works.
  • Signing (if used): commit signing works.
  • Containers: docker ps or podman ps works.
  • Dev Containers: at least 2 repos open and pass tests.
  • Ports: at least 2 services reachable via forwarded ports.
  • GPU (if needed): nvidia-smi works on host and in container.
  • Backups: automated backups run once. Restore test passes.

If you’re building anything adjacent to AI development, migrating your workstation is also a good moment to review what “production-ready” means for the stuff you’re shipping. I keep a bunch of that thinking under production AI, and if you’re building AI agents specifically, don’t ignore the security side. Start with prompt injection and work outward.

What comes next

My prediction: by the end of 2026, “I develop inside containers” will be as normal as “I use git.” Not because Linux won, but because reproducible dev environments won.

If you follow this plan, you’re not really switching operating systems. You’re switching your dev machine from a pet to cattle.

Do the boring verification steps. Keep a rollback path. Then, once it’s stable, start removing the training wheels. That’s when Linux stops being a weekend project and becomes your default.


Originally published on kunalganglani.com

Top comments (0)