Configuración de entorno de desarrollo profesional en 2025: Setup completo y optimizado

Configuración de entorno de desarrollo profesional en 2025: Setup completo y optimizado

La eficiencia en el desarrollo de software no solo depende de las habilidades técnicas, sino también de un entorno de trabajo bien configurado. Un setup optimizado puede aumentar la productividad hasta un 40% según estudios recientes de desarrolladores. Este post explora configuraciones esenciales, herramientas y optimizaciones para crear un entorno de desarrollo robusto y eficiente.

:desktop_computer: Terminal y Shell: El corazón del desarrollo moderno

Elección de terminal

La terminal es la herramienta más utilizada en el desarrollo diario. Las opciones actuales ofrecen características avanzadas que superan ampliamente las terminales tradicionales:

Opciones recomendadas:

  • WezTerm: Terminal GPU-acelerada escrita en Rust con configuración en Lua, soporte multiplataforma y rendimiento excepcional
  • Alacritty: Ultra rápida, minimalista, perfecta para sistemas con recursos limitados
  • iTerm2 (macOS): Estándar de facto con funcionalidades maduras y plugins extensivos
  • Windows Terminal: Solución nativa moderna de Microsoft con tabs, perfiles y personalización completa

Configuración de Zsh con Oh My Zsh

Zsh se ha convertido en el shell predeterminado en macOS y la preferencia de muchos desarrolladores Linux por sus capacidades de autocompletado y personalización.

Instalación base:

# Instalar Zsh
sudo apt install zsh  # Ubuntu/Debian
brew install zsh      # macOS

# Instalar Oh My Zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

Plugins esenciales en .zshrc:

plugins=(
  git
  docker
  docker-compose
  npm
  node
  python
  kubectl
  terraform
  rust
  zsh-autosuggestions
  zsh-syntax-highlighting
  z
  colored-man-pages
  extract
  jsontools
)

Instalación de plugins externos:

# zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions

# zsh-syntax-highlighting
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

Aliases productivos

# Git aliases
alias gs='git status'
alias ga='git add'
alias gc='git commit -m'
alias gp='git push'
alias gl='git log --oneline --graph --decorate --all'
alias gco='git checkout'
alias gb='git branch'
alias gd='git diff'
alias gds='git diff --staged'

# Docker aliases
alias dps='docker ps'
alias dpa='docker ps -a'
alias di='docker images'
alias dex='docker exec -it'
alias dlog='docker logs -f'
alias dcu='docker-compose up -d'
alias dcd='docker-compose down'
alias dcl='docker-compose logs -f'

# Navegación y utilidades
alias ll='ls -lah'
alias la='ls -A'
alias ..='cd ..'
alias ...='cd ../..'
alias ....='cd ../../..'
alias c='clear'
alias h='history'
alias ports='netstat -tulanp'
alias meminfo='free -m -l -t'
alias psg='ps aux | grep -v grep | grep -i -e VSZ -e'

# Desarrollo
alias nrd='npm run dev'
alias nrb='npm run build'
alias nrs='npm run start'
alias nrt='npm run test'
alias nrl='npm run lint'

# Python
alias py='python3'
alias pip='pip3'
alias venv='python3 -m venv'
alias activate='source venv/bin/activate'

# Kubernetes
alias k='kubectl'
alias kgp='kubectl get pods'
alias kgs='kubectl get services'
alias kgd='kubectl get deployments'
alias kl='kubectl logs -f'
alias kex='kubectl exec -it'

Prompt personalizado con Starship

Starship es un prompt universal, rápido y altamente personalizable compatible con cualquier shell:

# Instalación
curl -sS https://starship.rs/install.sh | sh

# Agregar al final de .zshrc o .bashrc
eval "$(starship init zsh)"  # o bash

Configuración en ~/.config/starship.toml:

[character]
success_symbol = "[➜](bold green)"
error_symbol = "[✗](bold red)"

[git_branch]
symbol = " "
format = "on [$symbol$branch]($style) "

[git_status]
format = '([\[$all_status$ahead_behind\]]($style) )'
conflicted = "🏳"
ahead = "⇡${count}"
behind = "⇣${count}"
diverged = "⇕⇡${ahead_count}⇣${behind_count}"
untracked = "?${count}"
stashed = "📦"
modified = "!${count}"
staged = "+${count}"
renamed = "»${count}"
deleted = "✘${count}"

[nodejs]
symbol = " "
format = "via [$symbol($version )]($style)"

[python]
symbol = " "
format = 'via [${symbol}${pyenv_prefix}(${version} )(\($virtualenv\) )]($style)'

[rust]
symbol = " "
format = "via [$symbol($version )]($style)"

[docker_context]
symbol = " "
format = "via [$symbol$context]($style) "

[kubernetes]
disabled = false
symbol = "☸ "
format = 'on [$symbol$context( \($namespace\))]($style) '

[aws]
symbol = "  "
format = 'on [$symbol($profile )(\($region\) )]($style)'

[time]
disabled = false
format = '🕙[\[ $time \]]($style) '
time_format = "%T"

[directory]
truncation_length = 3
truncate_to_repo = true
format = "[$path]($style)[$read_only]($read_only_style) "

[cmd_duration]
min_time = 500
format = "took [$duration](bold yellow) "

:memo: Editor: Visual Studio Code optimizado

Extensiones esenciales por categoría

Productividad general:

  1. GitHub Copilot / Codeium: Asistentes de código con IA
  2. Error Lens: Muestra errores inline inmediatamente
  3. Better Comments: Categoriza comentarios con colores
  4. TODO Highlight: Resalta TODOs, FIXMEs y NOTEs
  5. Project Manager: Cambia rápidamente entre proyectos
  6. Path Intellisense: Autocompleta nombres de archivos

Control de versiones:

  1. GitLens: Superpoderes para Git dentro de VS Code
  2. Git Graph: Visualiza el historial de commits
  3. Git History: Explora el historial de archivos y commits

Lenguajes y frameworks:

  1. ESLint: Linting para JavaScript/TypeScript
  2. Prettier: Formateador de código
  3. Pylance: Inteligencia avanzada para Python
  4. rust-analyzer: Soporte completo para Rust
  5. Go: Soporte oficial para Go
  6. Docker: Syntax highlighting y snippets para Dockerfiles
  7. YAML: Validación y autocompletado YAML

Frontend:

  1. Tailwind CSS IntelliSense: Autocompletado para Tailwind
  2. ES7+ React/Redux/React-Native snippets: Snippets para React
  3. Auto Rename Tag: Renombra tags HTML/XML pareadas
  4. CSS Peek: Navega a definiciones CSS
  5. Live Server: Servidor de desarrollo con recarga automática

Testing y debugging:

  1. Jest: Soporte para tests con Jest
  2. Test Explorer UI: Interfaz unificada para tests
  3. Debugger for Chrome: Debug de aplicaciones web

Visualización y temas:

  1. One Dark Pro: Tema oscuro popular
  2. Material Icon Theme: Iconos para archivos y carpetas
  3. Indent Rainbow: Colorea niveles de indentación
  4. Bracket Pair Colorizer: Colorea paréntesis pareados

Configuración settings.json optimizada

{
  // Editor
  "editor.fontSize": 14,
  "editor.fontFamily": "'JetBrains Mono', 'Fira Code', 'Cascadia Code', Consolas, monospace",
  "editor.fontLigatures": true,
  "editor.lineHeight": 22,
  "editor.letterSpacing": 0.5,
  "editor.tabSize": 2,
  "editor.insertSpaces": true,
  "editor.detectIndentation": true,
  "editor.wordWrap": "on",
  "editor.rulers": [80, 120],
  "editor.minimap.enabled": true,
  "editor.minimap.renderCharacters": false,
  "editor.suggestSelection": "first",
  "editor.quickSuggestions": {
    "strings": true
  },
  "editor.acceptSuggestionOnCommitCharacter": false,
  "editor.snippetSuggestions": "top",
  "editor.inlineSuggest.enabled": true,
  "editor.bracketPairColorization.enabled": true,
  "editor.guides.bracketPairs": true,
  "editor.linkedEditing": true,
  "editor.formatOnSave": true,
  "editor.formatOnPaste": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit",
    "source.organizeImports": "explicit"
  },
  
  // Files
  "files.autoSave": "onFocusChange",
  "files.trimTrailingWhitespace": true,
  "files.insertFinalNewline": true,
  "files.trimFinalNewlines": true,
  "files.exclude": {
    "**/.git": true,
    "**/.DS_Store": true,
    "**/node_modules": true,
    "**/__pycache__": true,
    "**/.pytest_cache": true,
    "**/venv": true,
    "**/.venv": true,
    "**/target": true,
    "**/dist": true,
    "**/build": true,
    "**/*.pyc": true
  },
  
  // Terminal
  "terminal.integrated.fontSize": 13,
  "terminal.integrated.fontFamily": "'JetBrains Mono', 'Fira Code', monospace",
  "terminal.integrated.cursorBlinking": true,
  "terminal.integrated.cursorStyle": "line",
  "terminal.integrated.defaultProfile.linux": "zsh",
  "terminal.integrated.defaultProfile.osx": "zsh",
  "terminal.integrated.tabs.enabled": true,
  
  // Workbench
  "workbench.colorTheme": "One Dark Pro",
  "workbench.iconTheme": "material-icon-theme",
  "workbench.startupEditor": "none",
  "workbench.editor.enablePreview": false,
  "workbench.editor.limit.enabled": true,
  "workbench.editor.limit.value": 10,
  "workbench.list.smoothScrolling": true,
  
  // Git
  "git.enableSmartCommit": true,
  "git.confirmSync": false,
  "git.autofetch": true,
  "git.fetchOnPull": true,
  "gitlens.hovers.currentLine.over": "line",
  "gitlens.currentLine.enabled": true,
  
  // JavaScript/TypeScript
  "javascript.updateImportsOnFileMove.enabled": "always",
  "typescript.updateImportsOnFileMove.enabled": "always",
  "javascript.suggest.autoImports": true,
  "typescript.suggest.autoImports": true,
  "js/ts.implicitProjectConfig.checkJs": true,
  
  // Python
  "python.linting.enabled": true,
  "python.linting.pylintEnabled": true,
  "python.formatting.provider": "black",
  "python.analysis.typeCheckingMode": "basic",
  "python.analysis.autoImportCompletions": true,
  
  // Prettier
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[json]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[jsonc]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[css]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[markdown]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  
  // ESLint
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact"
  ],
  
  // Emmet
  "emmet.includeLanguages": {
    "javascript": "javascriptreact",
    "typescript": "typescriptreact"
  },
  
  // Copilot
  "github.copilot.enable": {
    "*": true,
    "yaml": true,
    "plaintext": false,
    "markdown": true
  },
  
  // Otros
  "explorer.confirmDelete": false,
  "explorer.confirmDragAndDrop": false,
  "search.exclude": {
    "**/node_modules": true,
    "**/dist": true,
    "**/build": true,
    "**/.git": true,
    "**/venv": true,
    "**/__pycache__": true
  },
  "telemetry.telemetryLevel": "off"
}

Snippets personalizados útiles

JavaScript/TypeScript snippets (javascript.json):

{
  "Console log": {
    "prefix": "clg",
    "body": ["console.log('$1:', $1);"],
    "description": "Console log with label"
  },
  "Console table": {
    "prefix": "ctb",
    "body": ["console.table($1);"],
    "description": "Console table"
  },
  "Arrow function": {
    "prefix": "af",
    "body": ["const $1 = ($2) => {", "  $3", "};"],
    "description": "Arrow function"
  },
  "Async arrow function": {
    "prefix": "aaf",
    "body": ["const $1 = async ($2) => {", "  $3", "};"],
    "description": "Async arrow function"
  },
  "Try catch": {
    "prefix": "tryc",
    "body": [
      "try {",
      "  $1",
      "} catch (error) {",
      "  console.error('Error:', error);",
      "  $2",
      "}"
    ],
    "description": "Try catch block"
  },
  "Import module": {
    "prefix": "imp",
    "body": ["import $2 from '$1';"],
    "description": "Import module"
  },
  "Import destructured": {
    "prefix": "imd",
    "body": ["import { $2 } from '$1';"],
    "description": "Import destructured"
  },
  "Export default": {
    "prefix": "exp",
    "body": ["export default $1;"],
    "description": "Export default"
  },
  "React functional component": {
    "prefix": "rfc",
    "body": [
      "import React from 'react';",
      "",
      "const $1 = () => {",
      "  return (",
      "    <div>",
      "      $2",
      "    </div>",
      "  );",
      "};",
      "",
      "export default $1;"
    ],
    "description": "React functional component"
  },
  "React useState": {
    "prefix": "ust",
    "body": ["const [$1, set${1/(.*)/${1:/capitalize}/}] = useState($2);"],
    "description": "useState hook"
  },
  "React useEffect": {
    "prefix": "uef",
    "body": ["useEffect(() => {", "  $1", "}, [$2]);"],
    "description": "useEffect hook"
  }
}

Keybindings personalizados (keybindings.json)

[
  {
    "key": "ctrl+shift+d",
    "command": "editor.action.duplicateLine"
  },
  {
    "key": "ctrl+shift+k",
    "command": "editor.action.deleteLines"
  },
  {
    "key": "ctrl+shift+up",
    "command": "editor.action.moveLinesUpAction"
  },
  {
    "key": "ctrl+shift+down",
    "command": "editor.action.moveLinesDownAction"
  },
  {
    "key": "ctrl+b",
    "command": "workbench.action.toggleSidebarVisibility"
  },
  {
    "key": "ctrl+shift+e",
    "command": "workbench.view.explorer"
  },
  {
    "key": "ctrl+shift+g",
    "command": "workbench.view.scm"
  },
  {
    "key": "ctrl+shift+f",
    "command": "workbench.view.search"
  },
  {
    "key": "ctrl+shift+t",
    "command": "workbench.action.terminal.toggleTerminal"
  }
]

:wrench: Git: Configuración avanzada

.gitconfig optimizado

[user]
    name = Tu Nombre
    email = tu@email.com

[core]
    editor = code --wait
    autocrlf = input
    excludesfile = ~/.gitignore_global
    pager = delta

[init]
    defaultBranch = main

[pull]
    rebase = true

[push]
    default = current
    autoSetupRemote = true

[fetch]
    prune = true

[merge]
    conflictstyle = diff3
    tool = vscode

[mergetool "vscode"]
    cmd = code --wait $MERGED

[diff]
    tool = vscode
    colorMoved = zebra

[difftool "vscode"]
    cmd = code --wait --diff $LOCAL $REMOTE

[interactive]
    diffFilter = delta --color-only

[delta]
    navigate = true
    line-numbers = true
    side-by-side = true
    syntax-theme = Dracula

[alias]
    # Status y info
    st = status -sb
    s = status
    
    # Add
    a = add
    aa = add --all
    ap = add --patch
    
    # Commit
    c = commit -m
    ca = commit --amend
    can = commit --amend --no-edit
    
    # Branch
    b = branch
    ba = branch -a
    bd = branch -d
    bD = branch -D
    
    # Checkout
    co = checkout
    cob = checkout -b
    com = checkout main
    
    # Pull/Push
    p = push
    pf = push --force-with-lease
    pl = pull
    
    # Log
    l = log --oneline --decorate --graph
    la = log --oneline --decorate --graph --all
    ll = log --graph --pretty=format:'%C(yellow)%h%C(reset) - %C(cyan)%an%C(reset) %C(green)(%ar)%C(reset)%C(auto)%d%C(reset)%n          %s' --abbrev-commit
    
    # Diff
    d = diff
    ds = diff --staged
    dc = diff --cached
    
    # Stash
    ss = stash save
    sl = stash list
    sp = stash pop
    sa = stash apply
    
    # Reset
    unstage = reset HEAD --
    undo = reset --soft HEAD~1
    
    # Workflow
    wip = commit -am "WIP: work in progress"
    save = !git add -A && git commit -m 'SAVEPOINT'
    redo = commit --amend --no-edit
    
    # Cleanup
    clean-branches = !git branch --merged | grep -v '\\*\\|main\\|master\\|develop' | xargs -n 1 git branch -d
    
    # Info
    contributors = shortlog -sn
    count = !git log --oneline | wc -l
    
    # Aliases útiles
    please = push --force-with-lease
    commend = commit --amend --no-edit
    it = !git init && git commit -m "root" --allow-empty
    stsh = stash --keep-index
    staash = stash --include-untracked
    staaash = stash --all

.gitignore_global

# macOS
.DS_Store
.AppleDouble
.LSOverride
._*

# Windows
Thumbs.db
ehthumbs.db
Desktop.ini
$RECYCLE.BIN/

# Linux
*~
.directory

# IDEs
.vscode/
.idea/
*.swp
*.swo
*~
.project
.classpath
.settings/
*.sublime-*

# Dependencies
node_modules/
bower_components/
vendor/
venv/
.venv/
env/
.env

# Compiled files
*.com
*.class
*.dll
*.exe
*.o
*.so
*.pyc
__pycache__/
*.py[cod]
*$py.class

# Logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# OS files
.Trashes
.Spotlight-V100
.fseventsd

# Build outputs
dist/
build/
out/
target/
*.egg-info/
.next/
.nuxt/
.cache/

# Testing
coverage/
.nyc_output/
.pytest_cache/
.coverage
htmlcov/

# Environment
.env.local
.env.*.local
.envrc

# Temporary files
*.tmp
*.temp
*.bak
*.swp

Git hooks útiles

Pre-commit hook (.git/hooks/pre-commit):

#!/bin/bash

# Prevenir commits en main/master directamente
branch="$(git rev-parse --abbrev-ref HEAD)"
if [ "$branch" = "main" ] || [ "$branch" = "master" ]; then
  echo "No puedes hacer commit directamente a $branch"
  echo "Crea una rama feature y haz pull request"
  exit 1
fi

# Ejecutar linters
echo "Ejecutando linters..."
npm run lint 2>/dev/null || true

# Verificar archivos grandes
max_size=5242880 # 5MB
for file in $(git diff --cached --name-only); do
  if [ -f "$file" ]; then
    size=$(wc -c < "$file")
    if [ $size -gt $max_size ]; then
      echo "Error: $file es demasiado grande ($(($size / 1024 / 1024))MB)"
      exit 1
    fi
  fi
done

# Prevenir commits de archivos sensibles
files_pattern='(id_rsa|\.pem$|\.key$|\.env$)'
if git diff --cached --name-only | grep -E $files_pattern; then
  echo "Error: Intentando hacer commit de archivos sensibles"
  exit 1
fi

exit 0

Commit-msg hook (.git/hooks/commit-msg):

#!/bin/bash

commit_msg_file=$1
commit_msg=$(cat "$commit_msg_file")

# Validar formato de mensaje de commit (Conventional Commits)
pattern='^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{1,72}'

if ! echo "$commit_msg" | grep -qE "$pattern"; then
    echo "Error: El mensaje de commit no sigue Conventional Commits"
    echo ""
    echo "Formato: <type>(<scope>): <subject>"
    echo ""
    echo "Tipos válidos:"
    echo "  feat:     Nueva funcionalidad"
    echo "  fix:      Corrección de bug"
    echo "  docs:     Cambios en documentación"
    echo "  style:    Formato de código"
    echo "  refactor: Refactorización"
    echo "  test:     Tests"
    echo "  chore:    Tareas de mantenimiento"
    echo "  perf:     Mejora de performance"
    echo ""
    echo "Ejemplo: feat(auth): agregar login con OAuth"
    exit 1
fi

exit 0

:spouting_whale: Docker: Setup de desarrollo

Docker Compose para desarrollo local

docker-compose.yml para stack completo:

version: '3.8'

services:
  # PostgreSQL
  postgres:
    image: postgres:16-alpine
    container_name: dev_postgres
    environment:
      POSTGRES_USER: devuser
      POSTGRES_PASSWORD: devpass
      POSTGRES_DB: devdb
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init-scripts:/docker-entrypoint-initdb.d
    networks:
      - dev_network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U devuser"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Redis
  redis:
    image: redis:7-alpine
    container_name: dev_redis
    command: redis-server --appendonly yes
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data
    networks:
      - dev_network
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 5

  # MongoDB
  mongo:
    image: mongo:7
    container_name: dev_mongo
    environment:
      MONGO_INITDB_ROOT_USERNAME: devuser
      MONGO_INITDB_ROOT_PASSWORD: devpass
    ports:
      - "27017:27017"
    volumes:
      - mongo_data:/data/db
    networks:
      - dev_network

  # RabbitMQ
  rabbitmq:
    image: rabbitmq:3-management-alpine
    container_name: dev_rabbitmq
    environment:
      RABBITMQ_DEFAULT_USER: devuser
      RABBITMQ_DEFAULT_PASS: devpass
    ports:
      - "5672:5672"
      - "15672:15672"
    volumes:
      - rabbitmq_data:/var/lib/rabbitmq
    networks:
      - dev_network

  # Mailhog (SMTP testing)
  mailhog:
    image: mailhog/mailhog:latest
    container_name: dev_mailhog
    ports:
      - "1025:1025"  # SMTP
      - "8025:8025"  # Web UI
    networks:
      - dev_network

  # MinIO (S3-compatible storage)
  minio:
    image: minio/minio:latest
    container_name: dev_minio
    command: server /data --console-address ":9001"
    environment:
      MINIO_ROOT_USER: minioadmin
      MINIO_ROOT_PASSWORD: minioadmin
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - minio_data:/data
    networks:
      - dev_network

  # Elasticsearch
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.11.0
    container_name: dev_elasticsearch
    environment:
      - discovery.type=single-node
      - xpack.security.enabled=false
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ports:
      - "9200:9200"
      - "9300:9300"
    volumes:
      - elastic_data:/usr/share/elasticsearch/data
    networks:
      - dev_network

volumes:
  postgres_data:
  redis_data:
  mongo_data:
  rabbitmq_data:
  minio_data:
  elastic_data:

networks:
  dev_network:
    driver: bridge

Scripts útiles para Docker

Makefile para comandos frecuentes:

.PHONY: help up down restart logs ps clean prune stats

help: ## Mostrar ayuda
	@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}'

up: ## Levantar todos los servicios
	docker-compose up -d

down: ## Detener todos los servicios
	docker-compose down

restart: ## Reiniciar todos los servicios
	docker-compose restart

logs: ## Ver logs de todos los servicios
	docker-compose logs -f

ps: ## Ver estado de contenedores
	docker-compose ps

clean: ## Eliminar contenedores y volúmenes
	docker-compose down -v

prune: ## Limpiar sistema Docker
	docker system prune -af --volumes

stats: ## Ver estadísticas de recursos
	docker stats

shell-postgres: ## Shell en PostgreSQL
	docker-compose exec postgres psql -U devuser -d devdb

shell-redis: ## Shell en Redis
	docker-compose exec redis redis-cli

shell-mongo: ## Shell en MongoDB
	docker-compose exec mongo mongosh -u devuser -p devpass

:package: Gestión de paquetes y versiones

Node Version Manager (nvm)

# Instalación
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash

# Uso común
nvm install node        # Instalar última versión
nvm install 20          # Instalar Node 20
nvm install --lts       # Instalar LTS
nvm use 20              # Usar Node 20
nvm alias default 20    # Definir versión por defecto
nvm ls                  # Listar versiones instaladas
nvm ls-remote           # Listar versiones disponibles

Archivo .nvmrc en proyectos:

20.10.0

Python Version Manager (pyenv)

# Instalación (Linux/macOS)
curl https://pyenv.run | bash

# Agregar al .zshrc o .bashrc
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

# Uso común
pyenv install 3.12.0    # Instalar Python 3.12
pyenv global 3.12.0     # Definir versión global
pyenv local 3.11.0      # Definir versión para proyecto
pyenv versions          # Listar versiones instaladas

Rust Version Manager (rustup)

# Instalación
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Uso común
rustup update           # Actualizar Rust
rustup default stable   # Usar versión stable
rustup toolchain list   # Listar toolchains
rustup component add rustfmt    # Agregar componente
rustup component add clippy     # Linter de Rust

:hammer_and_wrench: Herramientas CLI esenciales

Herramientas modernas de línea de comandos

# Instalación en Ubuntu/Debian
sudo apt install -y \
  bat \          # cat mejorado con syntax highlighting
  exa \          # ls mejorado
  fd-find \      # find mejorado
  ripgrep \      # grep ultrarrápido
  fzf \          # fuzzy finder
  htop \         # monitor de procesos
  ncdu \         # analizador de disco
  tldr \         # páginas man simplificadas
  jq \           # procesador JSON
  httpie \       # cliente HTTP
  tmux           # multiplexor de terminal

# Aliases útiles
alias cat='bat'
alias ls='exa --icons'
alias ll='exa -la --icons'
alias tree='exa --tree --icons'
alias find='fd'
alias grep='rg'

fzf: Fuzzy finder configurado

Agregar a .zshrc:

# Configuración de fzf
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
export FZF_DEFAULT_OPTS='
  --height 40%
  --layout=reverse
  --border
  --preview "bat --style=numbers --color=always {}"
  --preview-window=right:60%
  --bind ctrl-u:preview-page-up
  --bind ctrl-d:preview-page-down
'

# Key bindings
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh

# Función para buscar y abrir archivos
vf() {
  local file
  file=$(fzf --preview 'bat --color=always {}') && code "$file"
}

# Función para buscar en git
fzf-git-branch() {
  git branch -a | grep -v HEAD | \
  fzf --preview 'git log --oneline --graph --date=short --pretty="format:%C(auto)%cd %h%d %s" $(sed s/^..// <<< {} | cut -d" " -f1)' | \
  sed 's/^..//' | cut -d' ' -f1 | \
  xargs git checkout
}

alias gb='fzf-git-branch'

tmux: Multiplexor de terminal

~/.tmux.conf:

# Remap prefix to Ctrl-a
unbind C-b
set-option -g prefix C-a
bind-key C-a send-prefix

# Split panes using | and -
bind | split-window -h
bind - split-window -v
unbind '"'
unbind %

# Switch panes using Alt-arrow without prefix
bind -n M-Left select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up select-pane -U
bind -n M-Down select-pane -D

# Enable mouse mode
set -g mouse on

# Don't rename windows automatically
set-option -g allow-rename off

# Start windows and panes at 1
set -g base-index 1
setw -g pane-base-index 1

# Reload config
bind r source-file ~/.tmux.conf \; display "Config reloaded!"

# Increase history
set-option -g history-limit 50000

# True color support
set -g default-terminal "screen-256color"
set -ga terminal-overrides ",xterm-256color:Tc"

# Status bar
set -g status-bg black
set -g status-fg white
set -g status-interval 60
set -g status-left-length 30
set -g status-left '#[fg=green](#S) #(whoami) '
set -g status-right '#[fg=yellow]#(cut -d " " -f 1-3 /proc/loadavg)#[default] #[fg=white]%H:%M#[default]'

# Plugins (usando TPM)
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'tmux-plugins/tmux-sensible'
set -g @plugin 'tmux-plugins/tmux-resurrect'
set -g @plugin 'tmux-plugins/tmux-continuum'

# Inicializar TPM
run '~/.tmux/plugins/tpm/tpm'

Un entorno de desarrollo bien configurado es una inversión que se paga con creces en productividad diaria. La clave está en iterar constantemente sobre la configuración, automatizar tareas repetitivas y mantener todo versionado en un repositorio de dotfiles.

¿Cuál es tu configuración favorita? ¿Qué herramientas consideras imprescindibles en tu setup de desarrollo?