Container Best Practices for Marketplace
This guide covers essential best practices for containerizing applications to meet Armada Edge Platform marketplace requirements and ensure optimal performance, security, and maintainability.
Container Image Standards
Base Image Selection
Recommended Base Images:
# For production applications
FROM ubuntu:22.04
FROM debian:bullseye-slim
FROM alpine:3.18
FROM distroless/static:nonroot
# For specific runtimes
FROM node:18-alpine
FROM python:3.11-slim
FROM openjdk:17-jre-slim
FROM golang:1.21-alpine AS builder
Avoid Deprecated Images:
# ❌ Avoid these
FROM ubuntu:16.04 # EOL
FROM centos:7 # EOL
FROM node:12 # EOL
FROM python:2.7 # EOL
Multi-Stage Builds
Optimize Image Size:
# Example: Go application
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
FROM alpine:3.18
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY /app/main .
CMD ["./main"]
Node.js Application:
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:18-alpine
WORKDIR /app
COPY /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["npm", "start"]
Security Best Practices
Non-Root User Execution
Always run as non-root:
# Create non-root user
RUN groupadd -r appuser && useradd -r -g appuser appuser
# Set ownership
RUN chown -R appuser:appuser /app
# Switch to non-root user
USER appuser
Using distroless images:
FROM gcr.io/distroless/static:nonroot
COPY app /app
CMD ["/app"]
Image Scanning Requirements
Pre-build scanning:
# Scan base images before use
trivy image --severity HIGH,CRITICAL ubuntu:22.04
# Scan application dependencies
trivy fs --severity HIGH,CRITICAL .
# Generate SBOM
trivy image --format cyclonedx myapp:v1.2.0 > sbom.json
Vulnerability thresholds:
# Acceptable vulnerability levels for marketplace
vulnerability_thresholds:
critical: 0 # Must be zero
high: 0 # Must be zero
medium: 5 # Maximum 5 medium issues
low: 20 # Maximum 20 low issues
Secrets Management
Never embed secrets in images:
# ❌ Wrong - secrets in image
ENV DB_PASSWORD=secret123
ENV API_KEY=abc123
# ✅ Correct - use runtime injection
ENV DB_PASSWORD=""
ENV API_KEY=""
Use Kubernetes secrets:
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
db-password: <base64-encoded>
api-key: <base64-encoded>
---
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: app
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: app-secrets
key: db-password
Performance Optimization
Image Size Optimization
Minimize layers:
# ❌ Bad - many layers
RUN apt-get update
RUN apt-get install -y package1
RUN apt-get install -y package2
RUN apt-get install -y package3
# ✅ Good - single layer
RUN apt-get update && \
apt-get install -y \
package1 \
package2 \
package3 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
Use .dockerignore:
# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.nyc_output
coverage
.DS_Store
*.log
Resource Efficiency
Set appropriate resource limits:
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: app
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
Optimize for edge environments:
# Edge-specific optimizations
edge_optimizations:
memory_efficiency:
- use_alpine_base_images: true
- enable_compression: true
- optimize_binary_size: true
startup_time:
- minimize_dependencies: true
- use_static_linking: true
- optimize_layer_caching: true
Health Checks
Application Health Endpoints
Implement health checks:
# Add health check
HEALTHCHECK \
CMD curl -f http://localhost:8080/health || exit 1
Kubernetes health checks:
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: app
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
Health Check Implementation
Go application example:
package main
import (
"net/http"
"time"
)
func healthHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("healthy"))
}
func readyHandler(w http.ResponseWriter, r *http.Request) {
// Check database connection
if err := db.Ping(); err != nil {
http.Error(w, "not ready", http.StatusServiceUnavailable)
return
}
w.WriteHeader(http.StatusOK)
w.Write([]byte("ready"))
}
Logging Standards
Structured Logging
Use structured logging:
{
"timestamp": "2024-01-15T10:30:00Z",
"level": "INFO",
"service": "myapp",
"version": "1.2.0",
"message": "Application started",
"pod": "myapp-xyz123",
"namespace": "default"
}
Log configuration:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-logging-config
data:
log-level: "INFO"
log-format: "json"
log-output: "stdout"
Log Rotation
Configure log rotation:
# Log rotation settings
log_rotation:
max_size: "100MB"
max_files: 5
max_age: "7d"
compress: true
Configuration Management
Environment Variables
Use environment variables for configuration:
# Define environment variables
ENV APP_ENV=production
ENV LOG_LEVEL=INFO
ENV PORT=8080
Kubernetes ConfigMaps:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: "production"
LOG_LEVEL: "INFO"
DATABASE_URL: "postgresql://db:5432/myapp"
REDIS_URL: "redis://redis:6379"
---
apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: app
envFrom:
- configMapRef:
name: app-config
Configuration Validation
Validate configuration at startup:
package main
import (
"log"
"os"
)
func validateConfig() error {
required := []string{
"DATABASE_URL",
"REDIS_URL",
"API_KEY",
}
for _, env := range required {
if os.Getenv(env) == "" {
return fmt.Errorf("required environment variable %s not set", env)
}
}
return nil
}
func main() {
if err := validateConfig(); err != nil {
log.Fatal(err)
}
// Start application
}
Edge-Specific Considerations
Offline Operation
Handle intermittent connectivity:
# Offline operation configuration
offline_operation:
enabled: true
data_sync:
- sync_on_connect: true
- retry_interval: "5m"
- max_retries: 10
local_storage:
- cache_duration: "24h"
- max_cache_size: "1GB"
Resource Constraints
Optimize for limited resources:
# Resource optimization for edge
edge_optimizations:
memory:
- use_streaming_processing: true
- implement_garbage_collection: true
- limit_concurrent_operations: 10
cpu:
- use_async_processing: true
- implement_rate_limiting: true
- optimize_algorithm_complexity: true
Network Efficiency
Optimize network usage:
# Network optimization
network_optimization:
compression:
- enable_gzip: true
- compression_level: 6
caching:
- enable_http_cache: true
- cache_headers: ["ETag", "Last-Modified"]
connection_pooling:
- max_connections: 100
- connection_timeout: "30s"
- keep_alive: true
Testing Requirements
Container Testing
Unit tests in container:
# Multi-stage build with testing
FROM golang:1.21-alpine AS test
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN go test -v ./...
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
FROM alpine:3.18
COPY /app/main .
CMD ["./main"]
Integration Testing
Test container integration:
# Integration test configuration
integration_tests:
- name: "Database Connection"
test: "Verify database connectivity"
timeout: "30s"
- name: "API Endpoints"
test: "Verify all API endpoints respond"
timeout: "60s"
- name: "Health Checks"
test: "Verify health check endpoints"
timeout: "30s"
Marketplace Compliance
Image Signing
Sign container images:
# Sign image with Cosign
cosign sign --key cosign.key myapp:v1.2.0
# Verify signature
cosign verify --key cosign.pub myapp:v1.2.0
SBOM Generation
Generate Software Bill of Materials:
# Generate SBOM with Trivy
trivy image --format cyclonedx myapp:v1.2.0 > sbom.json
# Include in package
tar -czf myapp-package.tar.gz \
manifests/ \
charts/ \
sbom.json \
scan-report.json
Documentation Requirements
Required documentation:
# Required documentation files
documentation:
- README.md # Setup and deployment
- INSTALL.md # Installation guide
- CONFIGURATION.md # Configuration options
- TROUBLESHOOTING.md # Common issues
- SECURITY.md # Security considerations
- API.md # API documentation
Summary
Following these container best practices ensures:
- Security: Non-root execution, vulnerability scanning, secrets management
- Performance: Optimized image size, resource efficiency, health checks
- Maintainability: Structured logging, configuration management, documentation
- Edge Compatibility: Offline operation, resource constraints, network efficiency
- Marketplace Compliance: Image signing, SBOM generation, testing requirements
These practices are essential for successful certification and deployment on the Armada Edge Platform marketplace.