Coding 101

Setting Up a Real Local Development Environment: Git, Terminal, and Docker vs Browser Sandboxes

DD
Ankur Ishwar
10 min read Updated Sep 7, 2026
Terminal window and Docker configuration for local software development

In-browser coding sandboxes like CodePen, Replit, and online course playgrounds give beginners a dangerous illusion. You write three lines of JavaScript or Python inside a neat web textarea, hit a green Play button, and watch numbers appear in a simulated output box. It feels like you are programming. But the second you land your first junior job or clone an open-source project from GitHub, the illusion shatters. There is no green button. There is only a blinking terminal cursor, missing system binaries, broken environment variables, permission errors, and a port conflict saying listen EADDRINUSE: address already in use :::3000.

Software does not run in a browser sandbox. It runs on physical Linux kernels, Docker containers, and developer machines connected to real networks and file systems. If you want to escape tutorial hell and survive as a working engineer, you must build a real local development environment on your own laptop. Here is how to construct a professional workstation from the ground up, even if you are working on an 8GB RAM machine in a hostel room.

1. The Terminal Foundation: Shells, PATH, and Process Control

Your graphical desktop interface is a toy for browsing the web. The terminal is where serious software engineering happens. Whether you write Go, TypeScript, Python, or Rust, every build pipeline, test suite, and database migration executes through a shell command.

If you run Windows, stop fighting cmd.exe with its backward slashes and missing POSIX utilities. Install WSL2 (Windows Subsystem for Linux) immediately:

# Run in Windows PowerShell as Administrator
wsl --install -d Ubuntu

WSL2 runs a real Linux kernel alongside Windows. Your code, packages, and servers stay inside the Linux virtual environment while you edit files comfortably using VS Code on Windows via the WSL remote extension. If you run macOS or native Linux, you already have a POSIX shell (Zsh or Bash) built into your operating system.

Understanding the PATH Variable

The single most common beginner error is command not found. When you type a command like node, your shell does not search your entire hard drive. It checks an environment variable named PATH, which contains a colon-separated list of directories:

# Print your active PATH variable
echo $PATH
# /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/home/ankur/.nvm/versions/node/v20.12.0/bin

When you execute node script.js, the shell checks each directory in order from left to right. As soon as it finds an executable file named node, it executes it and stops searching. If an executable is installed in a directory not listed in $PATH, your shell will throw an error even if the binary exists on disk. You add directories to PATH by modifying your shell configuration file (~/.zshrc for Zsh or ~/.bashrc for Bash):

# Add custom scripts directory to PATH in ~/.zshrc
export PATH="$HOME/.local/bin:$PATH"

Inspecting Ports and Killing Stuck Processes

When you terminate a local development server with Ctrl + C, the background process sometimes stays alive in an orphaned state. When you try to restart it, you get an address collision error. Never reboot your computer to fix this. Inspect your networking state and kill the process directly:

# Find the process ID (PID) holding port 3000 on macOS or Linux
lsof -i :3000

# Sample output:
# COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
# node    41892 ankur   23u  IPv6 0x1234      0t0  TCP *:3000 (LISTEN)

# Terminate the process cleanly using its PID
kill -15 41892

# If the process refuses to exit, send SIGKILL
kill -9 41892

2. Runtime Version Managers: Stop Using Sudo

A classic beginner mistake is installing programming runtimes with system package managers using administrative privileges:

# NEVER do this for development tools:
sudo apt install nodejs
sudo npm install -g typescript
sudo pip install pandas

When you run sudo npm install, you pollute root system directories. Packages install with root ownership, causing permission errors later. Even worse, operating system package managers ship outdated language versions, and different projects often require different runtime versions. Project A might run on Node 18, while Project B requires Node 20.

Instead, manage runtimes in user space using dedicated version managers:

  • Node.js: Use fnm (Fast Node Manager, written in Rust) or nvm.
  • Python: Use uv or pyenv to manage isolated Python binaries without altering the system Python.
  • Java: Use sdkman to switch between OpenJDK 17 and OpenJDK 21.

Here is how fnm handles multiple Node versions in under two seconds:

# Install the current LTS release of Node
fnm install --lts

# Install an older legacy version for an enterprise project
fnm install 18.20.0

# Switch versions instantly per project directory
fnm use 20
node -v # v20.12.0

# Automatically switch versions using a .nvmrc file in the project root
echo "20.12.0" > .nvmrc
fnm use

3. Git Configuration and SSH Authentication

Using GitHub through browser upload buttons or entering your account password on every push is unacceptable. GitHub disabled password authentication for Git operations years ago. You must authenticate using public-key cryptography via SSH keys.

Generating an Ed25519 SSH Key

Ed25519 is faster, more secure, and generates shorter keys than legacy 2048-bit RSA keys:

# Generate key pair using Ed25519 algorithm
ssh-keygen -t ed25519 -C "ankur@example.com"

# When prompted for a file location, press Enter to accept default (~/.ssh/id_ed25519)
# Enter a secure passphrase when prompted

This command creates two files inside your ~/.ssh/ directory:

  1. id_ed25519 (Private Key): Never share, send, or commit this file. Keep it secret on your machine.
  2. id_ed25519.pub (Public Key): This is your public identity. You copy its content and paste it into GitHub under Settings -> SSH and GPG Keys.
# Display the public key to copy to GitHub
cat ~/.ssh/id_ed25519.pub

# Test your SSH connection to GitHub
ssh -T git@github.com
# Hi yourusername! You've successfully authenticated, but GitHub does not provide shell access.

Global Git Configuration and Hygiene

Configure your author credentials once so your commits match your GitHub profile:

git config --global user.name "Ankur Ishwar"
git config --global user.email "ankur@example.com"
git config --global init.defaultBranch main
git config --global pull.rebase true

Setting pull.rebase true prevents your git history from getting cluttered with pointless merge commits like Merge branch 'main' of github.com every time you pull changes from upstream.

4. Local Containers: Running Databases Without Bloat

Installing PostgreSQL, MySQL, Redis, and MongoDB directly onto your host laptop is a recipe for system degradation. Each database installs system daemons that start automatically at boot, consuming precious RAM in the background even when you are not developing. Uninstalling them leaves orphaned config files, data directories, and conflicting port allocations.

The professional solution is Docker. Run your application services locally in isolated containers that spin up and tear down with a single command.

Production-Grade Docker Compose Configuration

Create a file named docker-compose.yml inside your project directory:

version: '3.8'

services:
  postgres:
    image: postgres:16-alpine
    container_name: local_postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: dev_user
      POSTGRES_PASSWORD: dev_password_123
      POSTGRES_DB: application_db
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U dev_user -d application_db"]
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    container_name: local_redis
    restart: unless-stopped
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

Now manage your complete database stack with clean terminal commands:

# Start both PostgreSQL and Redis in detached background mode
docker compose up -d

# Check running status and health
docker compose ps

# Stop containers when you finish working to reclaim 100% of your RAM
docker compose down

Your database records persist safely inside named Docker volumes (postgres_data and redis_data), but when the containers are stopped, zero background processes run on your machine.

5. Managing Secrets: The .env Pattern

Hardcoding database passwords or API keys inside source code files is the fastest way to get your cloud account hijacked by automated GitHub scrapers. Every developer workstation must implement strict environment separation.

Store runtime secrets in a local file named .env in your project root:

# .env (NEVER commit this file to Git)
PORT=3000
DATABASE_URL="postgresql://dev_user:dev_password_123@localhost:5432/application_db"
REDIS_HOST="127.0.0.1"
REDIS_PORT=6379
JWT_SECRET="e4f1a8c9b2d3e5f7a0c1b4d6e8f0a2c4"

Immediately add .env to your .gitignore file so it can never be staged or pushed:

# .gitignore
node_modules/
.env
.env.local
*.log
dist/
build/
.DS_Store

To ensure teammates and CI pipelines know which environment variables the project requires, commit a template file named .env.example containing keys with blank values or safe placeholders:

# .env.example (Safe to commit to Git)
PORT=3000
DATABASE_URL="postgresql://user:password@localhost:5432/dbname"
REDIS_HOST="127.0.0.1"
REDIS_PORT=6379
JWT_SECRET=""

6. The 8GB RAM Survival Guide: Tuning Your Workstation

When I was preparing for engineering interviews from a shared room in Bangalore, my laptop had an older dual-core processor and 8GB of RAM. If I launched VS Code, opened twelve tabs in Google Chrome, and ran a local development server, the machine would freeze due to memory exhaustion.

If you are working with budget hardware, follow these rules to keep your machine fast and responsive:

  1. Configure Linux Swap Aggressiveness: By default, Linux swaps memory pages to disk aggressively. Reduce swappiness to keep active programs in physical RAM:
    # Check current swappiness (default is usually 60)
    cat /proc/sys/vm/swappiness
    
    # Set swappiness to 10 for better desktop responsiveness
    sudo sysctl vm.swappiness=10
  2. Trim VS Code Memory Consumption: Disable unnecessary visual extensions, live server plugins, and heavy AI code autocomplete assistants that eat 1.5GB of RAM. Exclude massive folders from file watchers by adding this to settings.json:
    {
      "files.watcherExclude": {
        "**/.git/objects/**": true,
        "**/.git/subtree-cache/**": true,
        "**/node_modules/**": true,
        "**/dist/**": true
      }
    }
  3. Enforce Tab Discipline: Google Chrome uses separate processes for every tab. Keep only your local development tab (localhost:3000) and official documentation open. Close social media tabs while coding.

Summary Checklist

Before writing another line of tutorial code, verify your local machine meets these standards:

  • You have a native POSIX terminal or Ubuntu running on WSL2.
  • Your shell PATH contains user binary directories without requiring sudo.
  • Node, Python, or your primary language runtimes are managed via fnm, uv, or pyenv.
  • Your GitHub account authenticates through an Ed25519 SSH key.
  • Databases run inside Docker containers with explicit volume mappings.
  • All application credentials reside in a .env file strictly ignored by Git.

Once you master your local machine, configuring remote Linux servers, debugging CI/CD pipelines, and deploying production services becomes second nature. Stop clicking play buttons in browser sandboxes. Take control of your terminal.

Found this useful?
View all articles
Free Technical Interview Prep

Practicing for Engineering Interviews?

Skip the expensive coaching bootcamps and dry LeetCode memorization. Practice real production scenarios with instant turn-by-turn AI feedback on Frontend, Backend, System Design, and DSA.

Free Utilities

Recommended Developer Tools for this Topic

Explore all 25+ tools→

Keep Reading

Related Articles

Learn with Dropout Developer

Build real software with AI

Step-by-step learning paths, vibe coding tutorials, and certified developer programs designed for the modern engineer.