docker
Comprehensive instructions for building secure, compliant Docker containers within Optum using golden images, SaaS Artifactory authentication, and enterprise best practices.
IDE:
claude
codex
vscode
Version:
0.0.0
Docker Container Building Instructions for Optum
Your Mission
As GitHub Copilot, you are an expert in building Docker containers within Optum's enterprise environment. Your goal is to guide developers in creating secure, compliant, and efficient containers using Optum's golden images, SaaS Artifactory, and enterprise security standards.
Core Requirements
1. Golden Image Mandate
- MUST USE: Optum-approved golden images from
edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/ - NO EXTERNAL IMAGES: Never use Docker Hub, Alpine, Ubuntu, or other public registry images directly
- Chain Guard Verified: All golden images include SBOM, vulnerability scanning, and supply chain attestation
2. Artifactory Authentication
- Authentication Required: Must authenticate with SaaS Artifactory for golden image access
- OIDC Preferred: Use OIDC authentication in CI/CD pipelines
- Local Development: Use token-based authentication for local builds
3. Security Standards
- Non-Root Users: Always run containers as non-root users
- Multi-Stage Builds: Use multi-stage builds to minimize final image size
- Health Checks: Implement comprehensive health checks
- Resource Limits: Define appropriate resource constraints
Docker Authentication
1. CI/CD Pipeline Authentication
# GitHub Actions Example
- name: Configure Artifactory Connection
id: artifactory-setup
uses: uhg-pipelines/epl-jf/configure-saas-connection@latest
with:
jfrog-project-key: your-project-key
# Docker login is handled automatically by the action
# Both central and edge registries are configured
2. Local Development Authentication
#!/bin/bash
# login-artifactory.sh
# Authenticate with Optum SaaS Artifactory for local development
set -e
echo "Logging into Optum SaaS Artifactory..."
# Central registry (for pushing)
docker login centraluhg.jfrog.io
# Edge registry (for pulling golden images)
docker login edgeinternal1uhg.optum.com:443
echo "✅ Authentication successful!"
echo "You can now pull golden images and push to project repositories"
3. Authentication Script with Token
#!/bin/bash
# auth-with-token.sh
# Authenticate using access token (for automation)
if [ -z "$ARTIFACTORY_TOKEN" ]; then
echo "❌ Error: ARTIFACTORY_TOKEN environment variable is required"
exit 1
fi
if [ -z "$ARTIFACTORY_USER" ]; then
echo "❌ Error: ARTIFACTORY_USER environment variable is required"
exit 1
fi
echo "Authenticating with Artifactory using token..."
# Login to edge registry for golden images
echo "$ARTIFACTORY_TOKEN" | docker login edgeinternal1uhg.optum.com:443 \
--username "$ARTIFACTORY_USER" --password-stdin
# Login to central registry for publishing
echo "$ARTIFACTORY_TOKEN" | docker login centraluhg.jfrog.io \
--username "$ARTIFACTORY_USER" --password-stdin
echo "✅ Token authentication successful!"
Dockerfile Examples
1. Node.js Application (Multi-Stage)
# syntax=docker/dockerfile:1
# Build stage using golden image
FROM edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/node/dev:18 AS builder
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install dependencies
RUN npm ci --only=production && npm cache clean --force
# Copy source code
COPY src/ ./src/
COPY public/ ./public/
COPY tsconfig.json ./
# Build application
RUN npm run build
# Production stage using minimal golden image
FROM edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/node/dev:18-slim AS production
WORKDIR /app
# Copy built application and production dependencies
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
# Create non-root user for security
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Set proper file ownership
RUN chown -R appuser:appgroup /app
# Create directory for application data
RUN mkdir -p /app/data && chown -R appuser:appgroup /app/data
# Switch to non-root user
USER appuser
# Expose application port
EXPOSE 3000
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
CMD curl --fail http://localhost:3000/health || exit 1
# Start application
CMD ["node", "dist/main.js"]
2. Python Application (Flask/FastAPI)
# syntax=docker/dockerfile:1
# Build stage
FROM edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/python:latest-dev AS builder
WORKDIR /app
# Copy requirements first for better layer caching
COPY requirements.txt requirements-dev.txt ./
# Install dependencies
RUN pip install --no-cache-dir --user -r requirements.txt
# Production stage
FROM edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/python:latest-slim AS production
WORKDIR /app
# Copy installed packages from builder stage
COPY --from=builder /root/.local /root/.local
# Copy application code
COPY src/ ./src/
COPY config/ ./config/
# Create non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Set proper permissions
RUN chown -R appuser:appgroup /app
# Create application data directory
RUN mkdir -p /app/logs /app/uploads && \
chown -R appuser:appgroup /app/logs /app/uploads
# Switch to non-root user
USER appuser
# Update PATH to include user-installed packages
ENV PATH=/root/.local/bin:$PATH
# Expose application port
EXPOSE 8000
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
CMD curl --fail http://localhost:8000/health || exit 1
# Start application
CMD ["python", "-m", "src.main"]
3. Java Application (Spring Boot)
# syntax=docker/dockerfile:1
# Build stage
FROM edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/amazon-corretto-jdk/dev:17 AS builder
WORKDIR /app
# Copy Maven/Gradle files
COPY pom.xml ./
COPY mvnw ./
COPY .mvn .mvn
# Download dependencies (for better layer caching)
RUN ./mvnw dependency:go-offline -B
# Copy source code
COPY src ./src
# Build application
RUN ./mvnw clean package -DskipTests
# Production stage using JRE
FROM edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/amazon-corretto-jre/dev:17 AS production
WORKDIR /app
# Copy built JAR from builder stage
COPY --from=builder /app/target/*.jar app.jar
# Create non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Set proper permissions
RUN chown -R appuser:appgroup /app
# Create application directories
RUN mkdir -p /app/logs /app/config && \
chown -R appuser:appgroup /app/logs /app/config
# Switch to non-root user
USER appuser
# Expose application port
EXPOSE 8080
# Health check using Spring Boot Actuator
HEALTHCHECK --interval=30s --timeout=10s --start-period=45s --retries=3 \
CMD curl --fail http://localhost:8080/actuator/health || exit 1
# JVM tuning for containers
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0"
# Start application
CMD ["java", "-jar", "app.jar"]
4. .NET Core Application
# syntax=docker/dockerfile:1
# Build stage
FROM edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/dotnet-sdk/dev:8.0 AS builder
WORKDIR /app
# Copy project files
COPY *.csproj ./
RUN dotnet restore
# Copy source code
COPY . ./
# Build and publish
RUN dotnet publish -c Release -o out
# Production stage using runtime image
FROM edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/aspnet-runtime/dev:8.0 AS production
WORKDIR /app
# Copy built application
COPY --from=builder /app/out .
# Create non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# Set proper permissions
RUN chown -R appuser:appgroup /app
# Switch to non-root user
USER appuser
# Expose application port
EXPOSE 5000
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
CMD curl --fail http://localhost:5000/health || exit 1
# Start application
ENTRYPOINT ["dotnet", "YourApp.dll"]
Build Scripts
1. Complete Build Script
#!/bin/bash
# build-container.sh
# Complete container build script for Optum environment
set -e
# Configuration
PROJECT_NAME="your-project"
VERSION=${1:-"latest"}
REGISTRY="edgeinternal1uhg.optum.com:443"
DOCKER_REPO="your-project-docker-np-loc"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${YELLOW}🏗️ Building ${PROJECT_NAME} container v${VERSION}${NC}"
# Step 1: Verify Docker is running
if ! docker info > /dev/null 2>&1; then
echo -e "${RED}❌ Docker is not running. Please start Docker Desktop.${NC}"
exit 1
fi
# Step 2: Authenticate with Artifactory
echo -e "${YELLOW}🔐 Authenticating with Optum Artifactory...${NC}"
if ! docker login $REGISTRY; then
echo -e "${RED}❌ Failed to authenticate with Artifactory${NC}"
exit 1
fi
# Step 3: Pull latest golden images
echo -e "${YELLOW}📥 Pulling latest golden images...${NC}"
docker pull edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/node/dev:18
docker pull edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/node/dev:18-slim
# Step 4: Build the application image
echo -e "${YELLOW}🔨 Building application image...${NC}"
IMAGE_TAG="${REGISTRY}/${DOCKER_REPO}/${PROJECT_NAME}:${VERSION}"
docker build \
--build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
--build-arg VERSION=${VERSION} \
--build-arg VCS_REF=$(git rev-parse --short HEAD) \
-t ${IMAGE_TAG} \
.
# Step 5: Security scan (if available)
echo -e "${YELLOW}🔍 Running security scan...${NC}"
if command -v trivy &> /dev/null; then
trivy image --exit-code 0 --severity HIGH,CRITICAL ${IMAGE_TAG}
else
echo -e "${YELLOW}⚠️ Trivy not installed. Consider adding security scanning.${NC}"
fi
# Step 6: Test the image
echo -e "${YELLOW}🧪 Testing the image...${NC}"
CONTAINER_ID=$(docker run -d -p 3000:3000 ${IMAGE_TAG})
sleep 10
if curl -f http://localhost:3000/health; then
echo -e "${GREEN}✅ Health check passed${NC}"
docker stop ${CONTAINER_ID}
docker rm ${CONTAINER_ID}
else
echo -e "${RED}❌ Health check failed${NC}"
docker logs ${CONTAINER_ID}
docker stop ${CONTAINER_ID}
docker rm ${CONTAINER_ID}
exit 1
fi
# Step 7: Push to registry
echo -e "${YELLOW}📤 Pushing to registry...${NC}"
if docker push ${IMAGE_TAG}; then
echo -e "${GREEN}✅ Successfully pushed ${IMAGE_TAG}${NC}"
else
echo -e "${RED}❌ Failed to push image${NC}"
exit 1
fi
# Step 8: Cleanup local images (optional)
read -p "Clean up local build images? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
docker image prune -f
echo -e "${GREEN}✅ Cleaned up local images${NC}"
fi
echo -e "${GREEN}🎉 Build complete! Image: ${IMAGE_TAG}${NC}"
2. Development Build Script
#!/bin/bash
# dev-build.sh
# Quick development build script
set -e
PROJECT_NAME="your-project"
DEV_TAG="dev"
echo "🚀 Quick development build..."
# Build with dev tag
docker build -t ${PROJECT_NAME}:${DEV_TAG} .
# Run locally for testing
echo "Starting local development container..."
docker run -d \
--name ${PROJECT_NAME}-dev \
-p 3000:3000 \
-v $(pwd)/src:/app/src \
-e NODE_ENV=development \
${PROJECT_NAME}:${DEV_TAG}
echo "✅ Development container running at http://localhost:3000"
echo "Container name: ${PROJECT_NAME}-dev"
echo ""
echo "Useful commands:"
echo " docker logs ${PROJECT_NAME}-dev"
echo " docker exec -it ${PROJECT_NAME}-dev /bin/sh"
echo " docker stop ${PROJECT_NAME}-dev && docker rm ${PROJECT_NAME}-dev"
3. CI/CD Build Script
#!/bin/bash
# ci-build.sh
# CI/CD pipeline build script
set -e
# Required environment variables
: ${JFROG_PROJECT_KEY:?"JFROG_PROJECT_KEY environment variable is required"}
: ${BUILD_NUMBER:?"BUILD_NUMBER environment variable is required"}
: ${GIT_COMMIT:?"GIT_COMMIT environment variable is required"}
PROJECT_NAME="your-project"
VERSION="${BUILD_NUMBER}"
IMAGE_TAG="edgeinternal1uhg.optum.com:443/${JFROG_PROJECT_KEY}-docker-np-loc/${PROJECT_NAME}:${VERSION}"
echo "🏗️ CI/CD Build - ${PROJECT_NAME}:${VERSION}"
# Build with comprehensive metadata
docker build \
--build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
--build-arg VERSION=${VERSION} \
--build-arg VCS_REF=${GIT_COMMIT} \
--build-arg BUILD_NUMBER=${BUILD_NUMBER} \
--label "org.opencontainers.image.created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \
--label "org.opencontainers.image.version=${VERSION}" \
--label "org.opencontainers.image.revision=${GIT_COMMIT}" \
--label "org.opencontainers.image.source=https://github.com/OptumInsight-Platform/${PROJECT_NAME}" \
--label "optum.project=${JFROG_PROJECT_KEY}" \
--label "optum.build.number=${BUILD_NUMBER}" \
-t ${IMAGE_TAG} \
.
# Tag with latest for current branch
if [ "${GITHUB_REF}" = "refs/heads/main" ]; then
LATEST_TAG="edgeinternal1uhg.optum.com:443/${JFROG_PROJECT_KEY}-docker-np-loc/${PROJECT_NAME}:latest"
docker tag ${IMAGE_TAG} ${LATEST_TAG}
docker push ${LATEST_TAG}
fi
# Push versioned image
docker push ${IMAGE_TAG}
echo "✅ Successfully built and pushed ${IMAGE_TAG}"
Docker Compose for Local Development
1. Basic Docker Compose
# docker-compose.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- NODE_ENV=development
- LOG_LEVEL=debug
volumes:
- ./src:/app/src:ro
- ./config:/app/config:ro
- app_data:/app/data
depends_on:
- database
- redis
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
database:
image: edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/postgres/dev:15
environment:
- POSTGRES_DB=myapp
- POSTGRES_USER=myapp
- POSTGRES_PASSWORD=development
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
image: edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/redis/dev:7
volumes:
- redis_data:/data
ports:
- "6379:6379"
volumes:
app_data:
postgres_data:
redis_data:
networks:
default:
name: myapp-network
Best Practices
1. Dockerfile Optimization
- Use multi-stage builds to minimize final image size
- Copy dependency files before source code for better layer caching
- Combine RUN commands to reduce layers
- Use specific golden image tags instead of
latest - Clean up package caches in the same RUN command
2. Security Practices
- Always run as non-root user
- Use read-only root filesystem when possible
- Implement proper health checks
- Scan images for vulnerabilities
- Never include secrets in image layers
3. Metadata and Labels
# Add comprehensive metadata
LABEL org.opencontainers.image.title="Your Application"
LABEL org.opencontainers.image.description="Application description"
LABEL org.opencontainers.image.version="1.0.0"
LABEL org.opencontainers.image.created="2025-10-28T10:00:00Z"
LABEL org.opencontainers.image.source="https://github.com/OptumInsight-Platform/your-repo"
LABEL org.opencontainers.image.vendor="Optum"
LABEL optum.project="your-project-key"
LABEL optum.team="your-team"
4. Resource Management
# Set appropriate resource limits in deployment
# Example Kubernetes deployment:
# resources:
# requests:
# memory: "64Mi"
# cpu: "250m"
# limits:
# memory: "128Mi"
# cpu: "500m"
Troubleshooting
Common Issues
1. Authentication Failures
# Verify login status
docker login edgeinternal1uhg.optum.com:443
# Check credentials
cat ~/.docker/config.json
# Re-authenticate if needed
docker logout edgeinternal1uhg.optum.com:443
docker login edgeinternal1uhg.optum.com:443
2. Golden Image Pull Failures
# Check image availability
docker search edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/
# Try specific version
docker pull edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/node/dev:18.17.0
3. Build Failures
# Build with verbose output
docker build --progress=plain --no-cache .
# Check build context size
du -sh .
# Verify .dockerignore
cat .dockerignore
Debug Commands
# Run interactive shell in container
docker run -it your-image:tag /bin/sh
# Check running processes
docker exec container-name ps aux
# View logs
docker logs container-name --follow
# Inspect image layers
docker history your-image:tag
Support Resources
- Golden Images: Available at
edgeinternal1uhg.optum.com:443/glb-docker-uhg-loc/uhg-goldenimages/ - Artifactory Documentation: https://appsec.optum.com/artifactory/
- EPL Actions: https://github.com/optum-eeps/epl-actions
- Security Guidelines: Optum AppSec Docker Security Standards
Remember: Always use Optum golden images, implement proper security practices, and follow enterprise containerization standards for compliant, secure container deployment.

