Skip to main content
โšก Calmops

Developer Setup Automation Guide

Introduction

Every time you set up a new machine or rebuild your environment manually, you waste time and introduce inconsistencies. Automating your development environment ensures consistency, saves time, and makes it easy to recreate your setup anywhere.

Dotfiles Management

What to Version Control

# Typical dotfiles structure
DOTFILES=(
    ".bashrc"
    ".zshrc" 
    ".vimrc"
    ".gitconfig"
    ".tmux.conf"
    ".config/nvim/"
    ".config/alacritty/"
    ".ssh/config"
)

Using Dotfiles Repo

# bootstrap.sh - Dotfiles installation script
#!/bin/bash

# Clone dotfiles
git clone https://github.com/username/dotfiles.git ~/.dotfiles

# Create symlinks
for file in ~/.dotfiles/.*; do
    filename=$(basename $file)
    if [ "$filename" != "." ] && [ "$filename" != ".." ]; then
        ln -sf "$file" ~/$filename
    fi
done

# Install dependencies
./install_deps.sh

Docker-Based Development

Development Container

# Dockerfile.dev
FROM python:3.11-slim

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    curl \
    vim \
    && rm -rf /var/lib/apt/lists/*

# Install Python dependencies
COPY requirements.txt .
RUN pip install -r requirements.txt

# Set up working directory
WORKDIR /app

# Default command
CMD ["/bin/bash"]
# docker-compose.yml for development
version: '3.8'
services:
  dev:
    build:
      context: .
      dockerfile: Dockerfile.dev
    volumes:
      - .:/app
      - ~/.gitconfig:/root/.gitconfig
    environment:
      - EDITOR=vim
    ports:
      - "8000:8000"

Environment Scripts

Setup Script

#!/bin/bash
# setup.sh - Complete development environment setup

set -e

echo "Setting up development environment..."

# Check OS
if [ "$(uname)" = "Darwin" ]; then
    OS="macos"
elif [ "$(uname)" = "Linux" ]; then
    OS="linux"
else
    echo "Unsupported OS"
    exit 1
fi

# Install package manager
if [ "$OS" = "macos" ]; then
    if ! command -v brew &> /dev/null; then
        /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    fi
fi

# Install essential tools
install_tools() {
    echo "Installing essential tools..."
    
    if [ "$OS" = "macos" ]; then
        brew install git vim tmux zsh curl wget python
    elif [ "$OS" = "linux" ]; then
        apt-get update
        apt-get install -y git vim tmux zsh curl wget python3 python3-pip
    fi
}

# Configure shell
configure_shell() {
    echo "Configuring shell..."
    
    # Install Oh My Zsh
    sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools.sh)"
    
    # Install plugins
    git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
    git clone https://github.com/zsh-users/zsh-syntax-highlighting ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
}

# Install programming languages
install_languages() {
    echo "Installing language runtimes..."
    
    # Python
    pip install --upgrade pip setuptools wheel
    
    # Node.js
    if ! command -v node &> /dev/null; then
        curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
        apt-get install -y nodejs
    fi
}

# Install development tools
install_dev_tools() {
    echo "Installing development tools..."
    
    # VS Code
    if [ "$OS" = "linux" ]; then
        wget -q https://packages.microsoft.com/keys/microsoft.asc -O- | apt-key add -
        add-apt-repository "deb [arch=amd64] https://packages.microsoft.com/repos/code stable main"
        apt-get update && apt-get install -y code
    fi
    
    # Docker
    if ! command -v docker &> /dev/null; then
        curl -fsSL https://get.docker.com -o get-docker.sh
        sh get-docker.sh
    fi
}

# Run all installations
install_tools
configure_shell
install_languages
install_dev_tools

echo "Setup complete!"

Configuration Management

Using chezmoi

# Install chezmoi
brew install chezmoi

# Initialize with your dotfiles
chezmoi init https://github.com/username/dotfiles.git

# Apply configuration
chezmoi apply

# Edit configuration
chezmoi edit ~/.bashrc

# Update from remote
 chezmoi update

Ansible for Development Setup

# dev_setup.yml
---
- hosts: localhost
  connection: local
  become: yes
  
  tasks:
    - name: Update apt cache
      apt:
        update_cache: yes
      
    - name: Install basic packages
      apt:
        name:
          - git
          - vim
          - curl
          - wget
          - htop
          - tmux
          - zsh
        state: present
        
    - name: Install Python
      apt:
        name:
          - python3
          - python3-pip
        state: present
        
    - name: Install Node.js
      apt:
        name: nodejs
        state: present
        
    - name: Create development directory
      file:
        path: ~/dev
        state: directory

Package Management

Homebrew Bundle

# Brewfile - Define all dependencies
tap "homebrew/bundle"
tap "homebrew/cask"
tap "homebrew/core"

# Core utilities
brew "git"
brew "vim"
brew "tmux"
brew "zsh"
brew "fzf"
brew "ripgrep"
brew "jq"
brew "yq"

# Development tools
brew "docker"
brew "[email protected]"
brew "node"
brew "go"

# Applications
cask "visual-studio-code"
cask "iterm2"
cask "alfred"

# Install from Brewfile
brew bundle install

Cloud Development Environments

Dev Container Configuration

# .devcontainer/devcontainer.json
{
  "name": "My Project",
  "image": "mcr.microsoft.com/vscode/devcontainers/base:ubuntu",
  "features": {
    "ghcr.io/devcontainers/features/github-cli:1": {},
    "ghcr.io/devcontainers/features/node:1": {}
  },
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-azuretools.vscode-docker",
        "dbaeumer.vscode-eslint"
      ],
      "settings": {
        "editor.formatOnSave": true,
        "files.exclude": {
          "**/node_modules": true,
          "**/__pycache__": true
        }
      }
    }
  },
  "postCreateCommand": "pip install -r requirements.txt",
  "remoteUser": "vscode"
}

Backup and Sync

Syncing Configuration

#!/usr/bin/env python3
# sync_config.py - Sync configuration across machines

import os
import shutil
import subprocess
from pathlib import Path

CONFIGS = {
    "dotfiles": "~/.dotfiles",
    "ssh": "~/.ssh",
    "gitconfig": "~/.gitconfig",
    "vim": "~/.vim",
    "tmux": "~/.tmux.conf",
    "vscode": "~/Library/Application Support/Code/User",
}

REMOTE = "username@server:backup/"

def backup():
    """Backup local configs to remote."""
    for name, path in CONFIGS.items():
        expanded = os.path.expanduser(path)
        if os.path.exists(expanded):
            print(f"Backing up {name}...")
            # Use rsync or similar

def restore():
    """Restore configs from remote."""
    for name, path in CONFIGS.items():
        expanded = os.path.expanduser(path)
        print(f"Restoring {name}...")
        # Use rsync or similar

if __name__ == "__main__":
    import sys
    if len(sys.argv) > 1:
        if sys.argv[1] == "backup":
            backup()
        elif sys.argv[1] == "restore":
            restore()

Conclusion

Automating your development environment saves time and ensures consistency. Start with simple dotfiles, then gradually add Docker, scripts, and configuration management. The investment pays off quickly.

Resources

Comments