Best practices¶
Recommended patterns and practices for using Playpen effectively.
Application development¶
Use base images¶
Always use Playpen base images as your foundation:
Layer caching¶
Optimize Docker builds with layer caching:
# Good - dependencies first
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# Avoid - copy everything first
COPY . .
RUN pip install --no-cache-dir -r requirements.txt
Environment variables¶
Use environment variables for configuration:
# Good
import os
db_host = os.getenv("POSTGRES_HOST", "postgres.playpen-platform.svc.cluster.local")
# Avoid
db_host = "postgres.playpen-platform.svc.cluster.local" # Hard-coded
Health checks¶
Always include health check endpoints:
CI/CD pipelines¶
Declarative pipelines¶
Use declarative pipeline syntax:
Parallel execution¶
Run independent stages in parallel:
stage('Test') {
parallel {
stage('Unit Tests') {
steps {
sh 'pytest tests/unit'
}
}
stage('Integration Tests') {
steps {
sh 'pytest tests/integration'
}
}
}
}
Credential management¶
Store credentials in Jenkins credential store:
withCredentials([usernamePassword(
credentialsId: 'nexus-credentials',
usernameVariable: 'NEXUS_USER',
passwordVariable: 'NEXUS_PASS'
)]) {
sh 'docker login -u $NEXUS_USER -p $NEXUS_PASS nexus:5000'
}
Container images¶
Image tagging¶
Use meaningful tags:
# Good
docker tag my-app:latest nexus:5000/my-app:1.0.0
docker tag my-app:latest nexus:5000/my-app:v1.0.0-${BUILD_NUMBER}
# Avoid
docker tag my-app:latest nexus:5000/my-app:latest
Multi-stage builds¶
Use multi-stage builds for smaller images:
# Build stage
FROM playpen/python-base:latest AS builder
WORKDIR /build
COPY requirements.txt .
RUN pip install --user -r requirements.txt
# Runtime stage
FROM playpen/python-base:latest
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]
Data management¶
Database migrations¶
Use migration tools:
Connection pooling¶
Use connection pooling:
from sqlalchemy import create_engine
from sqlalchemy.pool import QueuePool
engine = create_engine(
"postgresql://user:pass@host/db",
poolclass=QueuePool,
pool_size=10,
max_overflow=20
)
Backup strategy¶
Regular backups:
kubectl exec -n playpen-platform postgres-0 -- \
pg_dump -U playpen playpen | gzip > backup-$(date +%Y%m%d).sql.gz
Security¶
Secrets management¶
Never hard-code secrets:
Least privilege¶
Use service accounts with minimal permissions:
Resource management¶
Resource limits¶
Set appropriate resource limits:
Health probes¶
Configure health probes:
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8000
initialDelaySeconds: 5
periodSeconds: 5
Monitoring and logging¶
Structured logging¶
Use structured logging:
import logging
logger = logging.getLogger(__name__)
logger.info("User login", extra={
"user_id": user_id,
"ip_address": ip_address,
"timestamp": datetime.now().isoformat()
})
Log levels¶
Use appropriate log levels:
logger.debug("Detailed debugging information")
logger.info("General informational message")
logger.warning("Warning message")
logger.error("Error occurred", exc_info=True)
Next steps¶
- Review troubleshooting guide for common issues
- Explore platform guides