Python y Entornos Virtuales: Instalación (venv) - Guía Completa de Producción
Introducción
Python es uno de los lenguajes de programación más populares del mundo, ampliamente utilizado para desarrollo web, ciencia de datos, aprendizaje automático, automatización y DevOps. Los entornos virtuales (venv) son esenciales para el desarrollo en Python, permitiéndote crear entornos Python aislados para diferentes proyectos con sus propias dependencias, evitando conflictos y garantizando la reproducibilidad. Esta guía completa cubre la instalación de Python, gestión de entornos virtuales y mejores prácticas de despliegue en producción.
Qué Aprenderás
- Instalación de Python 3 en Ubuntu/Debian y CentOS/Rocky Linux
- Gestión de múltiples versiones de Python
- Creación y gestión de entornos virtuales con venv
- Instalación y gestión de paquetes Python con pip
- Gestión de requirements.txt para entornos reproducibles
- Estrategias de despliegue en producción
- Optimización del rendimiento
- Mejores prácticas de seguridad
- Solución de problemas comunes
¿Por Qué Usar Entornos Virtuales?
- Aislamiento de Dependencias: Cada proyecto tiene sus propias dependencias
- Control de Versiones: Diferentes proyectos pueden usar diferentes versiones de paquetes
- Reproducibilidad: Fácil replicación de entornos
- Sistema Limpio: Mantener el Python del sistema limpio y estable
- Sin Problemas de Permisos: Instalar paquetes sin sudo
- Pruebas: Probar contra diferentes versiones de Python y paquetes
Requisitos Previos
- Ubuntu 20.04+, Debian 10+, CentOS 8+, o Rocky Linux 8+
- Acceso root o sudo
- Al menos 512MB de RAM
- 2GB de espacio libre en disco
- Conocimientos básicos de línea de comandos
Instalación
Instalar Python 3
Instalación en Ubuntu/Debian
# Actualizar lista de paquetes
sudo apt update
# Instalar Python 3 (usualmente preinstalado)
sudo apt install -y python3 python3-pip python3-venv python3-dev
# Instalar herramientas adicionales
sudo apt install -y build-essential libssl-dev libffi-dev python3-setuptools
# Verificar instalación
python3 --version
pip3 --version
# Crear alias python/pip (opcional)
echo 'alias python=python3' >> ~/.bashrc
echo 'alias pip=pip3' >> ~/.bashrc
source ~/.bashrc
Instalación en CentOS/Rocky Linux
# Actualizar sistema
sudo dnf update -y
# Instalar Python 3
sudo dnf install -y python3 python3-pip python3-devel
# Instalar herramientas de desarrollo
sudo dnf groupinstall -y "Development Tools"
# Verificar instalación
python3 --version
pip3 --version
# Crear alias
echo 'alias python=python3' >> ~/.bashrc
echo 'alias pip=pip3' >> ~/.bashrc
source ~/.bashrc
Instalar Versión Específica de Python
Usando PPA deadsnakes (Ubuntu/Debian)
# Agregar PPA deadsnakes
sudo add-apt-repository ppa:deadsnakes/ppa -y
sudo apt update
# Instalar Python 3.11
sudo apt install -y python3.11 python3.11-venv python3.11-dev
# Instalar Python 3.10
sudo apt install -y python3.10 python3.10-venv python3.10-dev
# Verificar
python3.11 --version
python3.10 --version
Usando pyenv (Todas las Distribuciones)
# Instalar dependencias
sudo apt install -y make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev \
libffi-dev liblzma-dev
# Instalar pyenv
curl https://pyenv.run | bash
# Agregar a ~/.bashrc
cat >> ~/.bashrc <<'EOF'
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
EOF
source ~/.bashrc
# Instalar versiones de Python
pyenv install 3.11.7
pyenv install 3.10.13
pyenv install 3.9.18
# Listar versiones instaladas
pyenv versions
# Establecer versión global
pyenv global 3.11.7
# Establecer versión local para proyecto
cd /ruta/al/proyecto
pyenv local 3.10.13
Configuración
Gestión de Entornos Virtuales
Crear Entornos Virtuales
# Crear directorio del proyecto
mkdir ~/miproyecto && cd ~/miproyecto
# Crear entorno virtual
python3 -m venv venv
# Crear con versión específica de Python
python3.11 -m venv venv
# Crear con paquetes del sistema (no recomendado)
python3 -m venv venv --system-site-packages
# Verificar creación
ls -la venv/
Activar Entornos Virtuales
# Activar entorno virtual
source venv/bin/activate
# Tu prompt debería cambiar para mostrar (venv)
(venv) usuario@servidor:~/miproyecto$
# Verificar que Python es del entorno virtual
which python
# Debería mostrar: /home/usuario/miproyecto/venv/bin/python
# Verificar versión de Python
python --version
# Desactivar cuando termines
deactivate
Múltiples Entornos Virtuales
# Crear diferentes entornos para diferentes proyectos
mkdir ~/proyecto1 && cd ~/proyecto1
python3 -m venv venv
mkdir ~/proyecto2 && cd ~/proyecto2
python3 -m venv venv
# O usar diferentes nombres
mkdir ~/miaplicacion && cd ~/miaplicacion
python3 -m venv venv-dev
python3 -m venv venv-prod
python3 -m venv venv-test
Gestión de Paquetes con pip
Instalar Paquetes
# Activar entorno virtual primero
source venv/bin/activate
# Instalar paquete único
pip install requests
# Instalar versión específica
pip install Django==4.2.7
# Instalar versión mínima
pip install numpy>=1.24.0
# Instalar desde requirements.txt
pip install -r requirements.txt
# Instalar en modo editable (para desarrollo)
pip install -e .
# Instalar desde repositorio git
pip install git+https://github.com/usuario/repo.git
Gestionar Requisitos
# Listar paquetes instalados
pip list
# Mostrar detalles del paquete
pip show Django
# Generar requirements.txt
pip freeze > requirements.txt
# Generar con comentarios (mejor)
pip list --format=freeze > requirements.txt
# Crear requirements-dev.txt para dependencias de desarrollo
pip freeze > requirements-dev.txt
Actualizar Paquetes
# Actualizar paquete único
pip install --upgrade requests
# Actualizar pip mismo
pip install --upgrade pip
# Actualizar todos los paquetes (¡con cuidado!)
pip list --outdated
pip install --upgrade $(pip list --outdated --format=freeze | cut -d = -f 1)
Mejores Prácticas de Estructura de Proyecto
# Estructura recomendada de proyecto Python
miproyecto/
├── venv/ # Entorno virtual (no en git)
├── src/ # Código fuente
│ ├── __init__.py
│ ├── main.py
│ └── utils.py
├── tests/ # Archivos de prueba
│ ├── __init__.py
│ └── test_main.py
├── requirements.txt # Dependencias de producción
├── requirements-dev.txt # Dependencias de desarrollo
├── .gitignore # Archivo ignore de Git
├── README.md # Documentación del proyecto
├── setup.py # Configuración del paquete (si se distribuye)
└── .env # Variables de entorno (no en git)
# Crear estructura
mkdir -p miproyecto/{src,tests}
cd miproyecto
python3 -m venv venv
touch src/{__init__.py,main.py,utils.py}
touch tests/{__init__.py,test_main.py}
touch requirements.txt requirements-dev.txt .gitignore README.md .env
# Crear .gitignore
cat > .gitignore <<EOF
venv/
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
*.so
*.egg
*.egg-info/
dist/
build/
.env
.venv
*.log
EOF
Despliegue
Configuración de Despliegue en Producción
Ejemplo de Aplicación Flask
# Crear proyecto Flask
mkdir flask-app && cd flask-app
python3 -m venv venv
source venv/bin/activate
# Instalar Flask
pip install Flask gunicorn python-dotenv
# Crear estructura de aplicación
mkdir app
cat > app/__init__.py <<'EOF'
from flask import Flask
def create_app():
app = Flask(__name__)
@app.route('/')
def index():
return {'message': 'API Flask funcionando', 'status': 'healthy'}
@app.route('/health')
def health():
return {'status': 'healthy'}
return app
EOF
# Crear archivo principal de aplicación
cat > wsgi.py <<'EOF'
from app import create_app
app = create_app()
if __name__ == '__main__':
app.run()
EOF
# Crear requirements.txt
cat > requirements.txt <<EOF
Flask==3.0.0
gunicorn==21.2.0
python-dotenv==1.0.0
EOF
# Crear archivo .env
cat > .env <<EOF
FLASK_APP=wsgi.py
FLASK_ENV=production
SECRET_KEY=tu-clave-secreta-aqui
EOF
# Probar localmente
flask run
# Ejecutar con gunicorn (producción)
gunicorn --bind 0.0.0.0:8000 --workers 4 wsgi:app
Ejemplo de Aplicación Django
# Crear proyecto Django
mkdir django-app && cd django-app
python3 -m venv venv
source venv/bin/activate
# Instalar Django
pip install Django psycopg2-binary gunicorn python-dotenv
# Crear proyecto
django-admin startproject misitio .
# Crear requirements.txt
pip freeze > requirements.txt
# Crear archivo .env
cat > .env <<EOF
DEBUG=False
SECRET_KEY=tu-clave-secreta-django
DATABASE_URL=postgresql://usuario:pass@localhost:5432/nombredb
ALLOWED_HOSTS=ejemplo.com,www.ejemplo.com
EOF
# Configurar settings.py para usar .env
pip install python-decouple
# En settings.py:
from decouple import config
SECRET_KEY = config('SECRET_KEY')
DEBUG = config('DEBUG', default=False, cast=bool)
ALLOWED_HOSTS = config('ALLOWED_HOSTS', default='').split(',')
# Ejecutar migraciones
python manage.py migrate
# Recopilar archivos estáticos
python manage.py collectstatic
# Ejecutar con gunicorn
gunicorn --bind 0.0.0.0:8000 --workers 4 misitio.wsgi:application
Configuración de Servicio Systemd
# Crear archivo de servicio systemd
sudo bash -c 'cat > /etc/systemd/system/miaplicacion.service <<EOF
[Unit]
Description=Mi Aplicación Python
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/var/www/miaplicacion
Environment="PATH=/var/www/miaplicacion/venv/bin"
EnvironmentFile=/var/www/miaplicacion/.env
ExecStart=/var/www/miaplicacion/venv/bin/gunicorn \
--workers 4 \
--bind 0.0.0.0:8000 \
--timeout 120 \
--access-logfile /var/log/miaplicacion/access.log \
--error-logfile /var/log/miaplicacion/error.log \
wsgi:app
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF'
# Crear directorio de logs
sudo mkdir -p /var/log/miaplicacion
sudo chown www-data:www-data /var/log/miaplicacion
# Habilitar e iniciar servicio
sudo systemctl daemon-reload
sudo systemctl enable miaplicacion
sudo systemctl start miaplicacion
sudo systemctl status miaplicacion
Configuración de Nginx
server {
listen 80;
server_name ejemplo.com www.ejemplo.com;
access_log /var/log/nginx/miaplicacion-access.log;
error_log /var/log/nginx/miaplicacion-error.log;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
# Archivos estáticos
location /static/ {
alias /var/www/miaplicacion/static/;
expires 30d;
add_header Cache-Control "public, immutable";
}
# Archivos multimedia
location /media/ {
alias /var/www/miaplicacion/media/;
expires 7d;
}
}
Monitoreo
Estado del Entorno Virtual
# Verificar si estás en entorno virtual
echo $VIRTUAL_ENV
# Mostrar paquetes instalados
pip list
# Mostrar paquetes desactualizados
pip list --outdated
# Verificar versiones de paquetes
pip show nombre-paquete
# Verificar integridad de paquetes
pip check
Monitoreo de Aplicación
# Monitorear logs de aplicación
tail -f /var/log/miaplicacion/error.log
# Verificar estado del servicio systemd
sudo systemctl status miaplicacion
# Ver logs del servicio
sudo journalctl -u miaplicacion -f
# Verificar proceso
ps aux | grep gunicorn
# Monitorear recursos
htop
Monitoreo de Rendimiento de Python
# Instalar herramientas de monitoreo
pip install py-spy memory_profiler
# Perfilar uso de memoria
python -m memory_profiler script.py
# Perfilado de CPU con py-spy
py-spy top --pid $(pgrep -f gunicorn)
# Generar gráfico de llama
py-spy record -o profile.svg --pid $(pgrep -f gunicorn)
Solución de Problemas
Problemas de Entorno Virtual
Problema: venv no se activa
# Recrear entorno virtual
rm -rf venv
python3 -m venv venv
source venv/bin/activate
# Verificar permisos del script de activación
chmod +x venv/bin/activate
Problema: Versión incorrecta de Python en venv
# Crear con Python específico
python3.11 -m venv venv
# O usar pyenv
pyenv local 3.11.7
python -m venv venv
Problemas de Instalación de Paquetes
Problema: pip install falla
# Actualizar pip
pip install --upgrade pip setuptools wheel
# Instalar con salida detallada
pip install nombre-paquete -v
# Limpiar caché de pip
pip cache purge
# Instalar desde código fuente
pip install --no-binary :all: nombre-paquete
Problema: Permiso denegado
# Siempre usar entorno virtual
source venv/bin/activate
# Nunca usar sudo con pip en venv
# Si estás fuera de venv, usar flag --user
pip install --user nombre-paquete
Errores de Aplicación
Problema: ModuleNotFoundError
# Asegurar que el entorno virtual está activado
source venv/bin/activate
# Verificar que el paquete está instalado
pip list | grep nombre-paquete
# Reinstalar paquete
pip install --force-reinstall nombre-paquete
# Verificar PYTHONPATH
echo $PYTHONPATH
Problema: Conflictos de dependencias
# Verificar dependencias
pip check
# Mostrar árbol de dependencias
pip install pipdeptree
pipdeptree
# Crear entorno limpio
deactivate
rm -rf venv
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
Mejores Prácticas de Seguridad
Instalación Segura de Paquetes
# Siempre verificar requirements.txt antes de instalar
cat requirements.txt
# Usar modo de verificación de hash
pip install -r requirements.txt --require-hashes
# Generar hashes
pip hash nombre-paquete
# Auditar dependencias
pip install safety
safety check
# O usar pip-audit
pip install pip-audit
pip-audit
Variables de Entorno
# Nunca codificar secretos
# Usar python-dotenv
pip install python-dotenv
# Crear archivo .env
cat > .env <<EOF
SECRET_KEY=tu-clave-secreta
DATABASE_URL=postgresql://localhost/nombredb
API_KEY=tu-clave-api
EOF
# Agregar a .gitignore
echo ".env" >> .gitignore
# En código Python
from dotenv import load_dotenv
import os
load_dotenv()
secreto = os.getenv('SECRET_KEY')
Asegurar Entorno Virtual
# Establecer permisos apropiados
chmod 750 venv
chmod 640 venv/pyvenv.cfg
# Remover permisos de lectura mundial
find venv -type d -exec chmod 750 {} \;
find venv -type f -exec chmod 640 {} \;
# Hacer scripts ejecutables
chmod 750 venv/bin/*
Optimización de Rendimiento
Requisitos Optimizados
# Separar dependencias de producción y desarrollo
cat > requirements.txt <<EOF
# Solo dependencias de producción
Flask==3.0.0
gunicorn==21.2.0
psycopg2-binary==2.9.9
EOF
cat > requirements-dev.txt <<EOF
# Dependencias de desarrollo
-r requirements.txt
pytest==7.4.3
black==23.12.0
flake8==6.1.0
mypy==1.7.1
EOF
# Instalar según corresponda
pip install -r requirements.txt # Producción
pip install -r requirements-dev.txt # Desarrollo
Optimización de Python
# Usar __slots__ para optimización de memoria
class MiClase:
__slots__ = ['attr1', 'attr2']
def __init__(self, attr1, attr2):
self.attr1 = attr1
self.attr2 = attr2
# Usar generadores para conjuntos de datos grandes
def leer_archivo_grande(ruta_archivo):
with open(ruta_archivo) as f:
for linea in f:
yield linea.strip()
# Usar comprensiones de lista
resultado = [x * 2 for x in range(1000)]
# Cachear operaciones costosas
from functools import lru_cache
@lru_cache(maxsize=128)
def funcion_costosa(n):
# Cómputo costoso
return resultado
Optimización de Gunicorn
# Workers óptimos = (2 x núcleos de CPU) + 1
gunicorn --workers 5 \
--worker-class sync \
--worker-connections 1000 \
--timeout 30 \
--keep-alive 5 \
--bind 0.0.0.0:8000 \
wsgi:app
# Para aplicaciones asíncronas
gunicorn --workers 5 \
--worker-class uvicorn.workers.UvicornWorker \
--bind 0.0.0.0:8000 \
main:app
Conclusión
Has configurado exitosamente Python con entornos virtuales para desarrollo y producción. Este enfoque aislado y reproducible garantiza una gestión limpia de dependencias y un despliegue profesional de aplicaciones Python.
Puntos Clave
- Los entornos virtuales aíslan las dependencias del proyecto
- Usar requirements.txt para entornos reproducibles
- Separar dependencias de producción y desarrollo
- Nunca instalar paquetes con sudo dentro de venv
- Usar variables de entorno para configuración sensible
- gunicorn + systemd proporciona despliegue listo para producción
Mejores Prácticas
- Siempre usar entornos virtuales
- Mantener requirements.txt actualizado
- Usar versiones específicas de paquetes en producción
- Implementar auditorías de seguridad regularmente
- Monitorear rendimiento de aplicación
- Usar gestores de procesos (systemd, supervisor)
- Mantener Python y paquetes actualizados
Próximos Pasos
- Configurar pruebas automatizadas (pytest)
- Implementar pipelines de CI/CD
- Configurar monitoreo y alertas
- Configurar respaldos automáticos
- Implementar agregación de logs
- Crear procedimientos de recuperación ante desastres
¡Los entornos virtuales de Python son fundamentales para el desarrollo profesional en Python. Domínalos para aplicaciones limpias, mantenibles y listas para producción!
¡Feliz codificación!


