The Tech Pulse

January 30, 20269 min read
Tags
  • Cybersecurity
  • Cybersecurity Education
Share

I Built A Secret Server No One Can Trace

One Sentence Summary

This video demonstrates turning a Raspberry Pi into a private, secure home server using Docker, Portainer, TailScale, and DNS tricks.

Main Points

  • Use Raspberry Pi OS Lite to save space and avoid desktop overhead.
  • Enable SSH during setup and SSH into Pi remotely.
  • Avoid bare-metal apps; use Docker to isolate services.
  • Portainer provides a GUI to manage Docker containers easily.
  • Create a dedicated Portainer volume and run Portainer in Docker.
  • Docker Compose/Stacks help organize multi-service deployments.
  • TailScale creates a secure, encrypted mesh for remote access.
  • TailScale avoids opening inbound ports and public internet exposure.
  • Optional Mulvad VPN and magic DNS enhance security and usability.
  • Access containers by hostname via magic DNS, even on mobile.

Takeaways

  • Centralize apps in Docker/Portainer for portability and isolation.
  • Use TailScale for zero-trust remote access, not public ports.
  • Enable magic DNS to reference devices by hostname, not IPs.
  • Maintain the system with a container-focused approach to reduce maintenance.
  • Consider Mulvad as an optional exit-node for extra privacy.

SUMMARY

This tutorial walks you through turning a Raspberry Pi into a secure, remotely accessible home server by running services as Docker containers and managing them with Portainer. The main problem it addresses is keeping a home lab clean and maintainable (no dependency mess on “bare metal”), while still enabling safe remote access without opening router ports. The primary tools are Docker (container runtime), Portainer CE (container management UI), and Tailscale (encrypted mesh VPN with optional MagicDNS). (Docker Documentation)


DETAILED STEP-BY-STEP BREAKDOWN

Prerequisites (hardware/software)

  • Hardware
    • Raspberry Pi (model not specified; ensure it’s compatible with your chosen OS and Docker).
    • microSD card for OS installation.
  • Software
    • Raspberry Pi OS Lite (recommended in the transcript for smaller footprint).
    • Another computer to SSH into the Pi.
    • Docker Engine for Raspberry Pi OS. (Docker Documentation)
    • Portainer CE (runs as a Docker container). (Portainer Documentation)
    • Tailscale installed on the Pi (not inside Docker). (Tailscale)

Step 1 — Install Raspberry Pi OS Lite and enable SSH

  1. Flash Raspberry Pi OS to the SD card.
  2. During first-boot setup:
    • Enable SSH
    • Set a username/password

Common mistakes

  • Forgetting to enable SSH → you can’t manage the Pi headlessly.
  • Choosing the desktop image when you won’t use GUI → wastes storage and RAM.

(For OS choice: “Lite” is a practical default for servers; Docker doesn’t require a desktop.)


Step 2 — Find the Pi’s IP address and SSH in

  1. Determine the Pi’s IP address on your LAN.
  2. From another machine, SSH into it:
ssh <username>@<pi-ip-address>

Transcript notes

  • They mention using ifconfig on the Pi to see the IP.
  • They also use an SSH hostname alias like ssh pihub.

Common mistakes

  • Wrong IP (DHCP changed it) → consider DHCP reservation on your router.
  • SSH blocked by firewall/router rules on your LAN.

Step 3 — Install Docker Engine on Raspberry Pi OS

The transcript uses the convenience script approach (“curl … | sh”). The official Docker docs also provide supported install paths and OS requirements. (Docker Documentation)

Recommended reference (official):

Typical verification

docker --version docker info

Common mistakes / pitfalls

  • Installing an unsupported combination (32-bit vs 64-bit, older Pi CPU, etc.). The Docker docs list supported Raspberry Pi OS versions and warn about 32-bit support changes. (Docker Documentation)
  • Confusing “Docker installed” with “Docker usable by my user” (next step).

Step 4 — Add your user to the docker group (avoid sudo for every command)

Add the current user to the docker group (transcript describes this step):

sudo usermod -aG docker <username>

Then log out and back in (or reboot) so group membership applies:

exit # SSH back in groups

You should see docker in the output.

Common mistakes

  • Forgetting to re-login → group change doesn’t apply.
  • Typo in username → user isn’t actually added.

Step 5 — Install Portainer CE (Docker management dashboard)

Portainer runs as a container and manages your other containers. Official install docs show the standard pattern: pull the image, create a volume, and run the container with ports. (Portainer Documentation)

Typical flow

  1. Pull Portainer:
docker pull portainer/portainer-ce:latest
  1. Create a persistent volume:
docker volume create portainer_data
  1. Run Portainer (Portainer’s docs provide the authoritative command and port mapping for your desired setup): (Portainer Documentation)

Access Portainer UI

  • In the transcript, Portainer is hosted on port 9443 (HTTPS UI).
  • Open in a browser:
    • https://<pi-ip>:9443

Common mistakes

  • Forgetting the volume → Portainer config resets on container recreation.
  • Port collision (9443 already in use) → choose another host port.

Step 6 — Deploy your services as containers (via Portainer “Stacks”)

The transcript shows these apps running as containers managed in Portainer:

  • Plex
  • Pi-hole
  • Heimdall
  • Caddy
  • Portainer itself

Practical approach (recommended)

  • Use Docker Compose in Portainer Stacks so configuration is reproducible.
  • Confirm containers are running:
docker ps

Common mistakes

  • Incorrect volume paths → data doesn’t persist (Plex libraries/config, etc.).
  • Bad port mappings → UI unreachable from LAN.
  • Permissions issues on mounted directories.

Step 7 — Install Tailscale on the Pi (NOT in Docker)

The transcript explicitly warns: install Tailscale on the host OS (“bare metal”), not in a container.

Official Raspberry Pi OS install instructions: (Tailscale)

Bring the Pi onto your tailnet

sudo tailscale up

This command authenticates and connects the device. (Tailscale)

Common mistakes

  • Installing Tailscale inside Docker → makes networking and device identity messier than needed.
  • Forgetting to authenticate in the browser → device won’t join tailnet.

Step 8 — Enable MagicDNS (optional, makes hostnames work)

MagicDNS lets you use device names (like pihub) instead of IP addresses. (Tailscale)

Where

  • Tailscale admin console → DNS → enable MagicDNS. (Tailscale)

Common mistakes

  • Assuming MagicDNS automatically creates nice subdomains for each container. It mainly maps devices; containers still need ports or a reverse proxy.

Step 9 — Remotely access services securely (without opening router ports)

Once your phone/laptop is on the same tailnet, you can reach the Pi using:

  • http(s)://<device-name>:<port> (with MagicDNS), or
  • http(s)://<tailscale-ip>:<port>

Example from the transcript style:

  • Heimdall dashboard: http://pihub:<heimdall-port>

Common mistakes

  • Testing from a phone not connected to Tailscale.
  • Expecting access by “public IP” without port forwarding—Tailscale avoids that by design.

KEY TECHNICAL DETAILS

Brands / software / tools mentioned

  • Raspberry Pi
  • Raspberry Pi OS (Desktop vs Lite)
  • SSH
  • Docker / Docker Engine (Docker Documentation)
  • Portainer CE (Portainer Documentation)
  • Docker Compose (mentioned as “compose files” and “stacks”)
  • Plex
  • Pi-hole
  • Heimdall (dashboard)
  • Caddy (commonly used as reverse proxy)
  • Tailscale (Tailscale)
  • MagicDNS (Tailscale)
  • Mullvad VPN (as optional exit-node endpoint via Tailscale; mentioned conceptually)

Version numbers / editions

  • Portainer CE (Community Edition) explicitly.
  • No explicit versions for Raspberry Pi OS, Docker, or the containers in the transcript.
  • Docker’s Raspberry Pi OS install page includes OS version support notes (Bookworm/Bullseye and 32-bit support warnings). (Docker Documentation)

Download / installation sources


PRO TIPS (expert-level)

  • Prefer Raspberry Pi OS Lite for a headless server: fewer packages, less disk/RAM overhead.
  • Use Portainer Stacks (Compose) for every service so rebuilds/migrations are copy-paste reproducible.
  • Add your user to the docker group and re-login; it prevents constant sudo friction.
  • Turn on MagicDNS so you can use pihub instead of IPs across devices. (Tailscale)
  • Put Caddy (or another reverse proxy) in front of web apps to reduce “remember ports” fatigue and standardize TLS internally.

POTENTIAL LIMITATIONS / WARNINGS

  • Raspberry Pi compatibility: Not every Pi + OS + Docker combination is equally supported; Docker’s docs call out OS versions and architecture caveats. (Docker Documentation)
  • Storage wear: Running multiple containers on an SD card can accelerate wear; consider SSD boot/storage for heavier services (especially Plex).
  • Remote access assumptions: Tailscale secures access, but you still must manage:
    • Tailscale device approvals
    • Account security (2FA)
    • Which services you expose on which ports
  • Portainer isn’t a security boundary: It’s a management UI—protect it (strong password, restrict who can reach it, keep it updated). (Portainer Documentation)
  • Container networking pitfalls: Misconfigured port mappings or volumes are the #1 cause of “it works locally but not remotely.”

RECOMMENDED FOLLOW-UP RESOURCES

If you want, I can produce a clean “starter stack” Compose bundle (Portainer + Heimdall + Caddy) and a validation checklist (ports, volumes, backups, update routine).

Related reading

Get New Posts

Follow on your preferred channel for new articles, notes, and experiments.

Related Posts