Menu
About Services Journey Work With Me
Server room with network cables and blinking lights
Technology Mar 12, 2026 • 18 min read

Docker Packaging, NVIDIA Sequencing, and the Debugging Lesson That Saved Hours

Kali's Docker packaging isn't what you'd expect. NVIDIA on a hybrid laptop is a minefield. And the order you install things can save or waste hours. Here's how AI helped me sequence the final build layers.

Share:
Lee Foropoulos

Lee Foropoulos

18 min read

Prompt Your Way to Linux: A 4-Part Series

Part 1: Picking Your DistroPart 2: Storage and EncryptionPart 3: Manual InstallPart 4: Services and GPU

Your base system is solid. Encrypted root booting clean, user account working, storage verified. Now comes the part that separates a functioning OS from a functioning platform: Docker, NVIDIA, and the service stack.

These are the decisions where getting the order wrong costs you hours of debugging. Kali's Docker packaging isn't what you'd expect. NVIDIA on a hybrid laptop is a minefield of compounding failures. And the emergency mode incident that looks like a GPU problem? It's almost always something else entirely.

This is the final part of the series. You're covering Docker packaging pitfalls on Kali, NVIDIA hybrid GPU sequencing, and a consolidated 9-stage build recipe distilled from four parts of hands-on work. By the end, you'll have a complete playbook for turning bare metal into a production-ready service platform.

Server room with organized network cables and blinking status lights
The goal: a clean, stable service platform. Getting there requires more decisions than most people expect.

The Docker Question Nobody Warns You About

First instinct: install docker.io from Kali's repos. Simple, right? One apt command, done.

And honestly, Kali's own documentation tells you to do exactly that. They specifically say to use docker.io (not docker) because Kali already has a completely different package called docker. It's a system tray app from the '90s. Not the container runtime. Naming is hard.

So you install docker.io and it works fine. Containers run. Everything seems good. Then you try to install docker-compose-v2 alongside it.

"Unable to locate package."

That's the moment the simplicity falls apart. Kali's repos don't carry the modern Compose plugin that matches Docker CE's architecture. You're stuck with the old standalone docker-compose (Python-based, slower, different syntax) or you're hunting for workarounds.

Here's the prompt that gets you the right answer: "I installed docker.io on Kali but docker-compose-v2 isn't available. Should I use the official Docker CE repo instead?"

Here's the Reasoning

The right answer depends on what the machine is for.

For a throwaway Kali lab machine you'll wipe next week? docker.io from the Kali repos is perfectly fine. It works, it's simple, and you don't need Compose v2 for quick experiments.

But for a long-lived service host running Compose-based stacks, databases, monitoring tools, and future GPU containers? Docker CE from the official repository is the right call. Here's why:

  • Modern Compose plugin support. docker compose (no hyphen) ships as a built-in plugin with Docker CE. No separate install, no version mismatch headaches.
  • Upstream consistency. When you follow Docker's own install docs, you get the same package tree that every tutorial, Stack Overflow answer, and NVIDIA guide assumes you have.
  • NVIDIA container toolkit alignment. The nvidia-container-toolkit documentation is written against Docker CE. If your Docker install doesn't match their assumptions, you're debugging phantom issues.
  • Predictable upgrades. Docker CE repos track upstream releases directly. You won't get surprised by Kali rebasing their fork or dropping a package.

If your machine isn't a throwaway lab, it's a permanent service platform. The Docker path needs to match that reality.

The Correct Docker CE Install Path

Here's the approach, step by step. The reasoning behind each phase matters more than the exact commands:

First, remove conflicting packages. If you've already installed docker.io, old docker-compose, podman-docker, containerd, or runc from Kali's repos, get rid of them. Leftover binaries and socket files from mixed installs cause the worst kind of debugging: things that work sometimes.

Add Docker's official GPG key and apt repository. This points your package manager at Docker's own servers instead of Kali's repackaged versions. You're telling apt: "I trust Docker upstream for this specific set of packages."

Install the full stack. That means docker-ce, docker-ce-cli, containerd.io, docker-buildx-plugin, and docker-compose-plugin. All five. Not just the engine. The CLI, the container runtime, and both plugins.

Enable the service and handle group membership. Start the Docker daemon, add your user to the docker group, and then actually log out and back in. If you read Part 3, you already know why: group membership changes don't apply to your current session. Same lesson, different context.

Verify everything independently. This is the part people skip, and it's the part that saves you hours later:

  • docker --version proves the CLI binary is installed and in your PATH
  • docker compose version proves the Compose plugin loaded correctly
  • docker buildx version proves multi-platform build support is available
  • docker run --rm hello-world proves the daemon is running, can pull images, and can execute containers

Each verification step proves a different layer of the stack. If step four fails but steps one through three pass, you know the daemon is the problem, not the CLI or the plugins. That's not pedantry. That's diagnostic isolation, and it's the kind of thinking that prevents you from chasing ghosts for two hours.

Package Security Prompts: The Decisions That Shape Your System

During the Kali package installation, several interactive prompts appear. These are the kind of questions that make people nervous because they look important but provide zero context about what you should actually pick.

The right answer for each one depends on the machine's role. For a stable internal service host, here's what to choose and why:

"Every security prompt is a policy decision. The right answer depends on the machine's role, not on what sounds most secure."

MAC changer automatic randomization? No. This machine sits on a home network running services that other devices need to find. A randomized MAC address means your DHCP leases, firewall rules, and device trust all break unpredictably. Stable service hosts need predictable LAN identities.

Kismet setuid root? No. Kismet is a wireless network detector. Setting it setuid root means any user who can run it gets root-level access to network interfaces. On a service host, that's an unnecessary privilege escalation path you don't need.

Wireshark non-superuser capture? No. Allowing regular users to capture packets sounds convenient, but on a machine that's meant to run services, you want packet capture restricted to root or explicit sudo. Convenience isn't worth the attack surface.

sslh mode? Standalone. sslh is a protocol multiplexer that shares a port between SSH, HTTPS, and other protocols. Standalone mode runs as a persistent process, which is the right choice for a service host that needs predictable SSH access.

These answers follow a consistent philosophy: stable, predictable, least-privilege behavior. Every "No" is a conscious choice to reduce attack surface on a box that needs to be reliable above all else. Don't guess at security prompts. Match them to the machine's purpose.

Terminal window showing command-line output on a dark screen
Every prompt during installation is a policy decision. Make each one deliberately instead of guessing.

The NVIDIA Sequencing Rule

If you're working with a GTX 1070 Mobile (or any hybrid GPU setup paired with Intel integrated graphics), you already know NVIDIA on Linux is tricky. If you've been following the series, the graphical installer already crashed because of this exact hardware combination (that's why Part 3 ended up as a manual debootstrap install).

So NVIDIA was always going to need careful handling. But the critical insight here isn't about which driver package to install or which kernel module to blacklist. It's about order of operations.

The Correct Sequence

The 6-Layer Verification Stack

Each layer must be stable and verified before you touch the next one. Skip a verification, and you won't know which layer broke when things go wrong.

  1. Stable base OS - boots cleanly, user works, sudo works
  2. Stable encrypted storage - root crypto verified, optional mounts tested or deferred
  3. Stable Docker - CE installed, Compose verified, hello-world passes
  4. NVIDIA host driver - install, reboot, verify nvidia-smi
  5. NVIDIA container toolkit - only after host driver passes
  6. GPU container test - only after toolkit is configured

Why This Order Prevents Disaster

This isn't just a nice checklist. It's a diagnostic dependency chain. Each layer depends on the one below it, and if you install things out of order, failures become ambiguous.

If you install NVIDIA while storage issues are unresolved, you can't tell which layer caused your boot failure. Was it the new kernel module? The broken fstab entry? The missing crypttab unlock? You've just created a debugging puzzle with multiple suspects and no witnesses.

If you install the NVIDIA container toolkit before Docker is stable, you're debugging two complex subsystems at the same time. The toolkit wraps Docker's runtime. If Docker itself has issues, every toolkit failure is a false lead.

The nvidia-smi milestone is the gatekeeper. If nvidia-smi doesn't show your GPU on the host, the container toolkit cannot possibly work. Full stop. Don't even attempt it. Fix the host driver first.

If nvidia-smi doesn't show your GPU on the host, container GPU passthrough is dead on arrival. Fix the host layer first.

Here's where this gets real. After the NVIDIA driver install, the system dropped into emergency mode on reboot. Every instinct screams "blame the GPU driver" because that was the last thing you touched. But the real cause? Bad fstab entries for the optional encrypted data disks (the exact issue covered in Part 3).

If the storage layer had been fully resolved before touching NVIDIA, that confusion wouldn't have happened. The boot failure would have been unambiguous: new driver, new problem. Instead, it was an old storage bug masquerading as a GPU issue, and it cost extra time to untangle.

That's the entire point of the sequencing rule. It's not about being slow or cautious. It's about making sure that when something breaks, you know exactly where to look.

Your Complete 9-Stage Build Recipe

Over the course of this series, every decision, mistake, and fix has distilled down into one consolidated build sequence. Not just for one specific machine, but as a general-purpose recipe for anyone building a purpose-built Linux system from scratch.

9
stages from bare metal to running services, each verified before the next begins

Stage 1: Discovery. Inventory your hardware. Disks, SMART health, firmware mode (UEFI or legacy), GPU model, network interfaces. You can't design a build for hardware you haven't examined. This is where Part 1 started.

Stage 2: Storage architecture. Assign disks by workload role. The OS disk isn't the data disk isn't the backup disk. Design your encryption strategy, your partition layout, and your LVM structure on paper before touching a single command. Part 2 covered this in depth.

Stage 3: Manual storage build. Create your LUKS containers, LVM volumes, and filesystems from the live environment. Don't trust the installer to interpret your design correctly, especially on complex multi-disk setups with full encryption.

Stage 4: Base install. If the graphical installer works, use it. If it doesn't (hybrid GPU, complex storage, installer bugs), fall back to debootstrap. Part 3 was entirely about this fallback path.

Stage 5: Boot stabilization. Your one and only goal: clean, repeatable boots. User account works, sudo works, networking is up, encrypted root unlocks correctly. Nothing else matters until this is solid.

Stage 6: Optional encrypted data disks. If you have secondary disks, configure crypttab and fstab now. Use nofail on optional mounts. Test by rebooting with and without the disks available. Resolve every mount issue before moving forward.

Stage 7: Docker platform. Docker CE, Compose plugin, Buildx. Verified independently with version checks and a hello-world run. The container runtime is infrastructure, and infrastructure must be quiet before you build on top of it.

Stage 8: GPU path. Host NVIDIA driver first. Reboot. Verify with nvidia-smi. Only then install the NVIDIA container toolkit. Only then test GPU passthrough in a container.

Stage 9: Application deployment. Your actual services, databases, monitoring stacks, security tools. Only after every infrastructure layer beneath them is stable and verified.

"The temptation is always to jump to Stage 9. The discipline is recognizing that Stages 1 through 8 are what make Stage 9 boring, which is exactly what you want."

The Field Guide: Do This, Not That

Four parts of lessons, compressed into one reference list. Bookmark this. Print it. Tape it to your monitor.

Do:

  • Start with hardware discovery before making any storage decisions
  • Design storage by workload role, not by what's convenient in the installer
  • Use UEFI, not legacy BIOS (unless you have a genuine reason)
  • Build encrypted storage manually when the installer misreads your layout
  • Add nofail to optional data mounts so a locked disk doesn't block your boot
  • Use Docker CE + Compose plugin for machines that will run services long-term
  • Verify each layer independently before adding the next one
  • Debug by evidence (logs, failed units, mount output), not by timeline ("I just installed X, so X must be broken")

Don't:

  • Let the installer flatten your encrypted LVM into one big ext4 partition
  • Point fstab at raw LUKS partitions as ext4 (you need to unlock them first)
  • Assume group membership changes apply to your current session (they don't; re-login)
  • Install Docker, NVIDIA, and fix storage problems simultaneously
  • Blame the GPU driver for boot failures without checking mount logs first
  • Leave exposed credentials unrotated after they've appeared on screen during debugging
Data center with rows of servers and organized cable management
A stable service platform isn't built in one step. It's built in verified layers, each one quiet before the next begins.

Now Go Build Something

Four parts. Nine stages. Dozens of prompts, errors, reboots, and fixes. And here you are at the end of it with a complete blueprint for building a Linux system from bare metal to running services.

But blueprints don't build machines. You do.

The skill isn't "how to install Kali Linux." The skill is knowing how to have a productive technical conversation with any tool that can reason about your specific situation.

Here's what you actually learned across this series, whether you realized it or not:

You learned how to ask the right questions. Not "how do I install Linux" but "I have an NVMe drive, a hybrid GPU, and I need six encrypted LVM volumes. What's the install path?" Specific questions get specific answers. Vague questions get blog posts that don't match your hardware.

You learned diagnostic thinking. When emergency mode hit after an NVIDIA install, the reflex was to blame the last thing that changed. But you checked the logs, found the fstab issue, and fixed the actual problem. That pattern works everywhere: observe, hypothesize, verify, fix. Not guess, reinstall, hope.

You learned layered verification. Every stage gets tested before the next one starts. Boring? Yes. Effective? Absolutely. The hours you save by not debugging two broken layers at once are hours you get to spend actually using your machine.

The machine from this series is real. It's running right now. Docker containers humming, NVIDIA driver stable, encrypted storage unlocking on boot. It went from a bare NVMe drive to a fully operational service platform, and every single decision along the way was deliberate and documented.

Your hardware is different. Your distro might be different. Your use case is definitely different. That's fine. The 9-stage recipe doesn't care about specifics. It cares about sequence and verification. Follow the stages, verify each layer, and you'll get to Stage 9 with a system you actually understand and can maintain.

So pick your hardware. Inventory your disks. Open a conversation with your AI of choice and tell it exactly what you're building. Then start at Stage 1 and work your way through, one verified layer at a time.

You've got the recipe. You've got the field guide. You've got four parts of war stories showing you exactly what goes wrong and how to fix it.

The only thing left is the build itself. Go.

Your Build Checklist 0/10

This is the final part of the "Prompt Your Way to Linux" series. If you missed the earlier installments:

How was this article?

Share

Link copied to clipboard!

You Might Also Like

Lee Foropoulos

Lee Foropoulos

Business Development Lead at Lookatmedia, fractional executive, and founder of gotHABITS.

🔔

Never Miss a Post

Get notified when new articles are published. No email required.

You will see a banner on the site when a new post is published, plus a browser notification if you allow it.

Browser notifications only. No spam, no email.