Skip to content

Best practices

Recommended patterns and practices for using Playpen effectively.

Application development

Use base images

Always use Playpen base images as your foundation:

# Good
FROM playpen/python-base:latest

# Avoid
FROM python:3.11

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:

# FastAPI
@app.get("/health")
def health():
    return {"status": "healthy"}

CI/CD pipelines

Declarative pipelines

Use declarative pipeline syntax:

// Good
pipeline {
    agent any
    stages {
        stage('Build') {
            steps {
                sh 'make build'
            }
        }
    }
}

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:

# Alembic for SQLAlchemy
alembic upgrade head

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:

# Good
password = os.getenv("DB_PASSWORD")

# Avoid
password = "hardcoded-password"

Least privilege

Use service accounts with minimal permissions:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-app
  namespace: playpen-apps

Resource management

Resource limits

Set appropriate resource limits:

resources:
  requests:
    cpu: "100m"
    memory: "128Mi"
  limits:
    cpu: "500m"
    memory: "512Mi"

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