What is a Container?
A container is a lightweight, standalone, executable package that includes everything needed to run a piece of software: code, runtime, system libraries, system tools, and settings. Containers are isolated from each other and from the host operating system, but they share the host OS kernel — which makes them far more efficient than virtual machines.
The analogy that stuck: a shipping container standardized physical cargo transport — any container fits any ship, truck, or crane, regardless of what is inside. Software containers do the same for application deployment — any container runs on any container runtime, regardless of what application is packaged inside.
How Containers Work
Containers rely on two Linux kernel features:
Namespaces provide isolation. Each container gets its own view of the system:
- PID namespace: the container sees only its own processes
- Network namespace: the container has its own network stack and IP address
- Mount namespace: the container has its own filesystem view
- UTS namespace: the container has its own hostname
cgroups (control groups) enforce resource limits: how much CPU, memory, and I/O a container can consume.
Together, namespaces and cgroups create an isolated process environment — the container believes it is the only thing running on the machine, but it is actually sharing the kernel with dozens or hundreds of other containers.
OCI: The Open Container Standard
Docker popularized containers, but the Open Container Initiative (OCI) standardized them. OCI defines:
- Image specification — The format for container images (layers, manifests, config)
- Runtime specification — The interface for running containers (
runcis the reference implementation) - Distribution specification — The API for pushing and pulling images from registries
Because of OCI, a container image built with Docker can be run by containerd, podman, or any other OCI-compliant runtime — and can be stored in any OCI-compliant registry (Docker Hub, GitHub Container Registry, Amazon ECR).
This portability is fundamental: your container image is a universal artifact.
Anatomy of a Container Image
A container image is built from layers. Each instruction in a Dockerfile creates a new layer:
FROM node:20-alpine # Layer 1: base OS + Node.js runtime
WORKDIR /app # Layer 2: set working directory
COPY package*.json ./ # Layer 3: copy dependency manifests
RUN npm ci --omit=dev # Layer 4: install dependencies (cached if package.json unchanged)
COPY . . # Layer 5: copy application source
EXPOSE 3000
CMD ["node", "src/index.js"]Layers are cached and shared between images. If two images use the same node:20-alpine base, that layer is stored once on disk and shared — dramatically reducing storage and pull times.
Containers vs Virtual Machines
Both containers and VMs provide isolation, but at different levels:
| Containers | Virtual Machines | |
|---|---|---|
| Isolation | OS process-level | Full hardware virtualization |
| Kernel | Shared with host | Dedicated per VM |
| Size | Megabytes | Gigabytes |
| Startup | Milliseconds | Minutes |
| Overhead | Minimal | Significant CPU/memory overhead |
| Security boundary | Process isolation | Hardware-level isolation |
| Portability | Highest | Lower (image format varies) |
VMs are not obsolete — they provide a stronger security boundary and are necessary for running different operating systems. But for packaging and deploying applications, containers are lighter and faster.
Running Containers in the Cloud
Containers can run in several ways in the cloud:
- Managed container platforms (PaaS) — You deploy a container image; the platform handles everything else. No Kubernetes knowledge needed.
- Kubernetes clusters — You manage Pods, Deployments, Services, and Ingresses. Maximum control, maximum complexity.
- Serverless containers — Containers that scale to zero when not in use (AWS Fargate, Google Cloud Run).
- Edge containers — Containers running at distributed edge nodes close to users.
Deploying Containers on PandaStack
PandaStack accepts any OCI-compliant Docker container image and handles the full lifecycle: pulling the image, provisioning compute, configuring networking, SSL, health checks, and rolling updates.
- 1Build and push your image:
`bash
docker build -t ghcr.io/your-org/my-app:latest .
docker push ghcr.io/your-org/my-app:latest
`
- 1Install the PandaStack CLI:
`bash
npm install -g @pandastack/cli
panda login
`
- 1Deploy the container:
`bash
panda deploy --app my-app --image ghcr.io/your-org/my-app:latest
`
- 1Or connect your GitHub repo for automatic builds and deploys on every push — PandaStack builds the image from your Dockerfile automatically.
You can pair container deployments with PandaStack's managed databases (PostgreSQL, MySQL, Redis, MongoDB), cronjobs, and edge functions — all within the same platform.
Container Security Best Practices
- 1Use minimal base images —
alpinevariants are smaller and have a smaller attack surface - 2Run as non-root — Add
USER node(or equivalent) to your Dockerfile; avoid running processes as root inside the container - 3Scan images for vulnerabilities — Tools like Trivy or Snyk scan image layers for known CVEs
- 4Pin base image versions —
FROM node:20.11.0-alpineis safer thanFROM node:latest - 5Never bake secrets into images — Pass secrets as environment variables at runtime, not
COPYcommands in Dockerfile - 6Keep layers small — Fewer layers with less content means smaller images and faster deploys
Conclusion
Containers solved one of software deployment's most persistent problems: environment inconsistency. By packaging an application and all its dependencies into a portable, reproducible unit, containers make "it works on my machine" a property of the artifact, not the environment.
The OCI standard ensures that container images are universal: build once, run anywhere. Whether you are running locally, in CI, or deploying to a cloud platform like PandaStack, the same image works everywhere.
To deploy your first container to PandaStack, start at [dashboard.pandastack.io](https://dashboard.pandastack.io) — a free tier is available and paid plans start at $12/mo.