Install Linux
Linux install is the process of placing the Linux operating system on a machine, and a clean single-user install on a spare 512 GB drive takes 20 to 30 minutes from the first boot of the USB stick to a working login.

The two skills that protect an existing Windows setup are a live session, where you test the drive and the network before the installer writes anything, and partitioning that leaves the EFI and data volumes untouched. This page runs the procedure on a Debian 12 base, the current stable release, then installs Docker Engine 27.0 on the result, so you finish with a container runtime on a distribution that the Debian project supports until 2028. The four anchor steps are: install Linux for the LAMP stack workloads, or choose Linux Mint for a desktop, pick from the Linux distros you actually trust, and treat Installing MySQL as a separate task you run only after the base install is proven. Each of those links appears on the site as its own page, and the order in that sentence is the order in which the work should happen on your machine.
The first decision is whether the install goes to a dedicated machine or shares the hardware with Windows, and the answer changes the partitioning, not the procedure. A dedicated drive is simpler, so if you have one free 256 GB SSD, use it. A dual boot install is fine too, as long as you boot in UEFI mode on both operating systems and leave the existing EFI system partition in place.
Prepare the disk before you boot the installer
Preparing the disk is what keeps a Windows setup intact, and it takes 15 minutes of screenshots against 20 minutes of reinstall. Work from a live session: boot the USB stick, open GParted, and read the current layout before the installer touches it. The layout you are looking for has 3 entries on a UEFI machine: an EFI system partition, an NTFS data partition, and a Windows Recovery partition. Write down their start sectors, because the installer will show you the same numbers and the match is your safety check.
- Snap the partition table into a text file, with a screenshot next to it, so two independent records exist.
- Shrink the NTFS data volume in Windows before you ever boot the Linux stick, because Linux tools refuse to shrink a partition that is mounted or has not been cleanly unmounted.
- Leave the freed space unformatted, so the Debian installer sees it as free space rather than as a volume to wipe.
- Boot in UEFI mode, not legacy mode, or the new install will create a second EFI partition and the boot order becomes a mess.
The numbers to keep straight are the sector counts: a 512 GB disk is 1,000,204,886,016 bytes, and GParted shows you that as roughly 931.51 GiB of addressable space. If your free space reads as 500 GB of addressable space, that is about 500 GiB of unallocated area, and it is enough for a 100 GB root and a 20 GB swap without touching the rest.
Partition the drive so Windows keeps its files
Partitioning is the step where the install either protects Windows or deletes it, and the rule is simple: the installer must only write to unallocated space. In the Debian installer, choose manual partitioning and assign exactly 3 new entries to the free area. The table below is the layout to aim for on a machine that dual boots.
| Partition | Filesystem | Size | Mount point |
|---|---|---|---|
| New EFI entry | FAT32 | 256 MB | /boot/efi |
| Root | ext4 | 100 GB | / |
| Swap | swap | 8 GB | swap |
Mark the EFI entry with the boot flag, leave the existing Windows partitions with their mount points unset, and confirm the write when the summary table appears. The summary is the moment to say no: if it lists a Windows partition as formatted, cancel and start over, because a second chance at partitioning costs minutes, and a second chance at Windows data costs a recovery project. Swap at 8 GB covers a machine with 16 GB of RAM and gives hibernate enough room to write the image, which is a reason to enable it in the kernel line even if you never hibernate.
Run the Debian base install without surprises
Running the Debian base install is a guided 20 minute pass once the partitions are safe, and the only decisions that matter are the software selection and the bootloader. Choose the standard system utilities, add the desktop environment only if the machine is a daily driver, and skip the server role packages if Docker is the only workload you intend to run. The bootloader question is where dual boot breaks for beginners: the installer finds GRUB, finds the Windows boot manager, and asks whether to install GRUB to the master boot record. Say yes, because GRUB 2 will chain-load Windows through its own EFI entry, and the boot menu you want is the one that lists both operating systems in one place.
Two settings survive the reboot and are worth checking while you are in. The first is the package mirror, which the installer pulls from the nearest Debian mirror and which you confirm with a single command in the terminal. The second is the timezone, which the installer sets from your locale and which Docker containers inherit unless you override it. Both are 5 minute checks, and both are the kind of thing that is annoying to fix after you have installed 400 packages on top of the default.
Install Docker Engine on the new system
Installing Docker on the result is the payoff, and the official path from Docker's own documentation uses the apt repository rather than the distro package, because the distro package lags the upstream release. The steps below are the sequence as written for Debian 12, and they take 5 minutes on a wired connection.
- Add the Docker apt key and the Docker apt repository, then refresh the package list.
- Install the 3 package names that make up the engine: docker-ce, docker-ce-cli, and containerd.io.
- Add your user to the docker group, so the next login runs commands without a password prompt.
- Pull the hello-world image and run it, which is the 30 second proof that the runtime, the daemon, and the network path all work.
The version to verify at the end is the engine version, which the hello-world run prints, and it should read 27.0 or newer if you installed today. The group membership is the step people miss, because it requires a logout and login to take effect, and a command that fails with a permissions error before the re-login is the symptom. Keep the containerd configuration at the default, which stores images under /var/lib/docker and caps the storage driver at overlay2, and treat any change to that path as a separate migration, not part of the install.
Check the result and harden the 2 default gaps
Checking the result is a 10 minute pass that catches the 2 gaps the install leaves open, and both are about the boundary between the host and the container. The first gap is the storage layout: the default install puts container images on the root filesystem, so a machine that runs 30 images at 2 GB each will fill the 100 GB root in a few months of normal use. The fix is a second partition or a dedicated volume for /var/lib/docker, and the move is a one-command re-point of the daemon configuration plus a restart. The second gap is the firewall: Debian 12 ships with ufw disabled, and Docker's bridge network will forward ports without asking, so a published container port is reachable from the network the moment the container starts.
Close both gaps before you treat the machine as production. Enable ufw with the default deny on inbound traffic, allow SSH by its 22 port, and list each container port you intend to publish as an explicit allow rule. Run a final check from a second machine on the network, and the pass/fail test is whether the closed ports time out. That single check, plus the hello-world run from the install section, is the evidence that the Linux install and the Docker install both landed where you left them, and it is the state from which the LAMP stack, MySQL, or any other workload starts.