How-to: Container Tasks#
Step-by-step guides for common container tasks at SKAO.
Write an efficient Dockerfile#
Minimise layers and image size:
# Use build arguments for flexibility
ARG base_image="python:3.9.5"
FROM $base_image
# Install packages and clean up in one layer
RUN apt-get update && \
apt-get install -y \
apache2-bin \
binutils \
cmake && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Copy requirements first (changes less often)
COPY pyproject.toml poetry.lock ./
ENV POETRY_NO_INTERACTION=1
ENV POETRY_VIRTUALENVS_IN_PROJECT=1
ENV POETRY_VIRTUALENVS_CREATE=1
RUN poetry install --no-root
# Copy application code last (changes most often)
COPY ./app /app
Key practices:
Order layers from least to most frequently changing
Combine
RUNcommands to reduce layersAlways clean package caches after
apt-get installSort multi-line arguments alphabetically for readability
Use multi-stage builds#
Multi-stage builds separate build tools from runtime to reduce final image size:
FROM artefact.skao.int/ska-build-python:0.1.1 as build
WORKDIR /src
COPY pyproject.toml poetry.lock* ./
ENV POETRY_NO_INTERACTION=1
ENV POETRY_VIRTUALENVS_IN_PROJECT=1
ENV POETRY_VIRTUALENVS_CREATE=1
# Install dependencies only (not the code)
RUN poetry install --no-root
FROM artefact.skao.int/ska-python:0.1.2
WORKDIR /src
# Add virtualenv to PATH
ENV VIRTUAL_ENV=/src/.venv
ENV PATH="$VIRTUAL_ENV/bin:$PATH"
# Copy only the built virtualenv
COPY --from=build ${VIRTUAL_ENV} ${VIRTUAL_ENV}
COPY ./src/my_project ./my_project
ENV PYTHONPATH=${PYTHONPATH}:/src/
This keeps build tools (compilers, dev packages) out of your production image.
Name and tag images correctly#
Image naming convention:
ska-tango-examples/powersupply:1.13.2
└── repository ──────┘└─ app ─┘└ tag ┘
Tagging strategy:
During development: Tag with short commit hash
git rev-parse --verify --short=8 HEAD # Result: bbedf059
For production releases: Tag with semantic version
ska-tango-examples/powersupply:1.13.2 # Full version ska-tango-examples/powersupply:1.13 # Minor version ska-tango-examples/powersupply:1 # Major version ska-tango-examples/powersupply:latest # Current release
For debug images: Append
-devska-tango-examples/powersupply-dev:1.13.2
Warning
Always use fully qualified semantic versions for production deployments.
Never deploy using :latest — it changes unexpectedly.
Configure ENTRYPOINT and CMD#
Use ENTRYPOINT for the application and CMD for default arguments:
ENTRYPOINT ["/bin/cat"]
CMD ["/etc/hosts"]
Always use the exec format (["thing"]) to ensure proper signal propagation:
# Correct — signals propagate to the application
ENTRYPOINT ["/usr/bin/myapp"]
# Incorrect — signals go to the shell, not the app
ENTRYPOINT /usr/bin/myapp
Run containers with resource limits#
Set memory and CPU constraints to prevent runaway containers:
docker run --rm --name postgresdb \
--memory="1g" \
--cpu-shares="1024" \
--cpuset-cpus="1,3" \
-d postgres
This limits the container to 1GB memory and pins it to CPUs 1 and 3.
Mount volumes securely#
Use read-only mounts when you don’t need write access:
docker run -v /etc/passwd:/etc/passwd:ro \
-v /config:/app/config:ro \
myimage:1.0.0
Pass configuration via environment variables#
Set defaults in your Dockerfile:
ENV APP_PORT=8080
ENV LOG_LEVEL=INFO
Override at runtime:
docker run -e APP_PORT=9090 -e LOG_LEVEL=DEBUG myimage:1.0.0
Warning
Never pass secrets (passwords, API keys) via command line arguments. Use environment variables or mounted secret files instead.
Sign and push images to the registry#
Push to the SKAO Central Artefact Repository:
docker push artefact.skao.int/ska-tango-images/myimage:1.0.0
Verify image signatures:
docker trust inspect --pretty \
artefact.skao.int/ska-tango-images/ska-python-runtime:1.2.3
Create a Helm chart for Kubernetes#
Create the chart structure:
charts/myapp/
Chart.yaml # Chart metadata and dependencies
values.yaml # Default configuration values
templates/ # Kubernetes manifest templates
templates/NOTES.txt # Usage notes shown after install
templates/tests/ # Test templates for 'helm test'
Chart.yaml requirements:
name: my-app
version: 1.0.0
description: Very important app
home: https://www.skao.int/
sources:
- https://gitlab.com/ska-telescope/my-app
maintainers:
- name: myaccount
email: myaccount@skatelescope.org
Validate your chart:
helm lint ./charts/my-app/
Test locally with Minikube:
helm install --dry-run --debug ./charts/my-app/