How I Set Up Docker for Development Enviroment
Back on August 31, 2021, Docker announced a major license update to Docker Desktop—requiring a paid subscription for commercial use in medium-to-large businesses.
Even though I’m a solo developer (and Docker Desktop is technically still free for individuals and small setups under 250 employees and $10M revenue), I personally choose not to use Docker Desktop at all.
Instead of running Docker locally on my main development PC or spinning up a local WSL VM, I install Docker Engine on a dedicated Linux server in my local network and point my Windows machine’s Docker CLI directly to it
Why I prefer this setup ?
- Offloading Heavy Workloads from My Main PC, Running multiple containers, database clusters, and background services is quickly draining my main development PC’s RAM and CPU.
- Total Control Over My Environment, I want to have full visibility and manage service startups, permissions, and configuration within Linux tools, and it helps me learn on my home-lab journey.
1. Install Docker Engine on Local Linux Server
This is setup is stright forward. There is a lot guide “how to install” but I will keep my script here for svaing and reference when i need.
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release
# Add Docker's official GPG key
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# Set up the repository
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Refresh Repo
sudo apt-get update
# Install Docker and his familiese
sudo apt-get install -y \
docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin
# Configure Permissions
sudo usermod -aG docker $USER
newgrp docker
# Enable docker Service
sudo systemctl enable --now docker
2. Update Firewall Rule
Since my Linux has UFW, I need to whitelist some ports so that I can call services running inside the Linux server from my Windows machine. I only want to open the ports that need to be accessed from my Windows machine instead of allowing all ports.
# Set default policies (if not already set)
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Allow SSH
sudo ufw allow from 192.168.0.0/24 to any port 22 proto tcp
# Allow container port ( e.g 8080 )
sudo ufw allow from 192.168.0.0/24 to any port 8080 proto tcp
# Reload UFW to apply the rules
sudo ufw enable
sudo ufw status
3. Install Docker CLI on Windows PC
Docker CLI and Compose can be easily installed using the winget command
winget install -e --id Docker.DockerCLI
winget install -e --id Docker.DockerCompose
Verify the client-only installation
docker version
TIP: You will see client details, but it will report that it cannot connect to the Docker daemon yet—which is expected
4. Install Docker CLI on Windows PC
This is the final step: I need to connect the Windows Docker CLI to the Docker daemon running inside the Linux server. I am going to use the SSH Context method. I have already generated an SSH key on my Windows machine. It is located under .ssh\id_rsa.pub in my case.
# Powershell
# Copy pubic key to remote linxu server - it make passwordless SSH connection
cat $env:USERPROFILE\.ssh\id_rsa.pub | `
ssh USER_NAME@SERVER_IP `
"mkdir -p ~/.ssh && chmod 700 ~/.ssh && tr -d '\r' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
# Register Remote Docker daemon from Window Docker CLI
docker context create remote-server --docker "host=ssh://USER_NAME@SERVER_IP"
# Make Docker CLI to use that context
docker context use remote-server
Replace USER_NAME and SERVER_IP with your own ones.
After completing the setup, I am able to run docker run hello-world from my Windows machine.
Final Thoughts
By running Docker Engine on a dedicated Linux server within my local network and connecting my Windows machine via SSH context, I get a clean setup for coding and an isolated Linux environment handling my container workloads.