What Is a Docker Image?
A Docker image is a read-only, layered package that holds an application and everything it needs to run. This guide explains what is inside one, how it is built, named, stored, and shared, and how to keep it small and safe.
Imagine you want to open a bakery branch in a new city. You could send the head baker with a notebook and hope the new kitchen has the right oven, flour, and tools. Or you could ship a complete, sealed kit: the recipe, the exact ingredients, the measuring tools, and the oven settings, all packed in one box. Wherever the box is opened, the bread tastes the same. A Docker image is that sealed kit for software. It is the thing you build once and then run anywhere.
1The Problem Images Solve
To appreciate the image, first feel the pain it removes.
Software never travels alone
A program depends on many hidden things: a certain version of a programming language, helper libraries, system tools, and settings. On the developer’s laptop all of these happen to be just right. On a test server or a customer’s machine, one of them may be missing or slightly different, and the program breaks. This is the famous complaint: “but it works on my machine!”
Older solutions were clumsy. Long setup documents were easy to misread. Full virtual machines were reliable but heavy, slow to start, and huge to copy around. Teams needed a package that was light, complete, and identical everywhere.
Think of a flat-pack furniture box that arrives with every screw, panel, and instruction already inside. You never have to hunt for a missing part. A Docker image arrives with every library, tool, and setting your program needs.
2So, What Exactly Is a Docker Image?
A clear definition, without the jargon.
A Docker image is a read-only template that contains an application along with the files, libraries, tools, and settings it needs in order to run. It also carries instructions about how to start the program, such as which command to run first. When you want to run the application, you use the image to create a container, which is the live, running version.
Images follow an open standard created by the Open Container Initiative, often shortened to OCI. Because of this standard, an image built with Docker can be run by many other tools, including the container runtime used inside Kubernetes. The image is not locked to one company’s tool.
Three key words to remember
Template
An image is a pattern, not a running program. You cannot “run” changes into an image; you create containers from it.
Read-only
After an image is built, its contents are frozen. To change something, you build a new image.
Layered
An image is made of thin stacked layers, each recording one set of changes to the files.
An image usually does not contain a full operating system with its own kernel. It contains only the files and tools an application needs on top of the host’s kernel, which is why images are much smaller than virtual machine disks.
3Image Versus Container
The most common confusion for beginners, cleared up once and for all.
An image is the frozen template. A container is a running instance created from that template. If the image is the recipe card with all ingredients measured, the container is the dish being cooked and served right now. You can cook the same recipe ten times, and each dish is separate from the others.
An image is like a song file stored on your phone. A container is the song playing. The same file can be played on many phones at the same time, and pressing stop on one phone never damages the file.
| Feature | Image | Container |
|---|---|---|
| What it is | A read-only template | A running instance of an image |
| Can it change? | No, it is frozen once built | Yes, it has a thin writable layer on top |
| How many from one? | One image | Many containers can start from one image |
| Where it lives | On disk and in registries | In memory as a process, plus a writable layer on disk |
| When you delete it | Containers already running are not affected on their own, but new ones cannot be created from it | Its writable layer and its data are lost, but the image stays |
When someone says “my image crashed”, they nearly always mean a container crashed. An image cannot crash, because it is not running. It is just stored files.
4The Anatomy of an Image
Open the box and see what is really inside.
Under the hood, an image is not one giant file. It is a small collection of well-organized parts. Understanding these parts explains almost every behavior you will see later.
Layers
Compressed bundles of files. Each one records what was added, changed, or removed compared to the layer below it.
Configuration
A small description file listing the start command, environment values, working folder, the user to run as, and the order of layers.
Manifest
A table of contents that lists the configuration and each layer, with a fingerprint for every item so nothing can be swapped secretly.
Image Index
An optional top-level list that points to different versions of the same image for different computer types, such as Intel and ARM machines.
flowchart TD
IDX["Image Index - optional list per computer type"] --> MAN["Manifest - table of contents"]
MAN --> CFG["Configuration - start command, settings, layer order"]
MAN --> L1["Layer 1 - base files"]
MAN --> L2["Layer 2 - runtime and libraries"]
MAN --> L3["Layer 3 - your application"]
Think of a book. The layers are the chapters, the configuration is the note on how to read it, the manifest is the table of contents that lists every chapter, and the image index is a library shelf that points to translations for different readers.
Fingerprints everywhere
Each layer and each configuration file is identified by a fingerprint, called a digest, which is calculated from its exact contents using a secure hashing method. If even one character changes, the fingerprint changes completely. This makes images content-addressable: the name of a piece is derived from what the piece contains. It is the reason Docker can trust that a downloaded layer is exactly the one that was published.
5How Layers Really Work
The clever trick that makes images small and fast.
Stacking, not copying
Each layer contains only the differences from the layer below it. Imagine a stack of transparent sheets where each sheet has a few things drawn on it. Looking down through the pile, you see one combined picture. Docker uses a union file system, commonly a driver called overlay2 on modern Linux, to present all the layers as one ordinary folder tree.
graph TD
A["Layer 1: minimal operating system files"] --> B["Layer 2: language runtime"]
B --> C["Layer 3: application libraries"]
C --> D["Layer 4: your application files"]
D --> E["Writable layer: added only when a container starts"]
Layers are like the transparent sheets that old teachers used on overhead projectors. Put several sheets on top of each other and you see a single combined picture, but each sheet can be swapped or reused independently.
Copy-on-write
The layers of an image are read-only. When a running container wants to change a file that lives in a lower layer, Docker first copies that file up into the container’s own thin writable layer, and the change is made there. The original layer stays untouched. This technique is called copy-on-write. It means a hundred containers can share the same underlying layers, while each keeps its own small set of changes.
Deleted files still take space
Because layers only add on top, deleting a file in a later layer does not make the earlier layer smaller. The file is merely hidden by a marker in the new layer, while its bytes are still stored below. This surprises many beginners, and it is one reason that the order and combination of build steps matters for size and for security.
If a password or a big installer is added in one step and removed in a later step, it is still inside the earlier layer. Anyone who receives the image can extract it. Never add secrets to any layer, even temporarily.
Sharing saves real money
If fifty images on one server all start from the same base, that base is stored once on disk and downloaded once over the network. Multiply that saving across hundreds of servers, and the benefit becomes very large.
6The Dockerfile: The Recipe for an Image
How you tell Docker what to put inside.
A Dockerfile is a plain text file that lists, step by step, how to build an image. Docker reads it from top to bottom, and each step that changes files adds a new layer. Because it is just text, it can be stored next to your source files, reviewed by teammates, and improved over time. It also acts as living documentation of exactly how your environment is put together.
The most important instructions
FROM
Chooses the starting image, called the base. Every Dockerfile begins here.
WORKDIR
Sets the working folder inside the image for the steps that follow.
COPY
Brings files from your computer into the image.
RUN
Runs a command while building, such as installing a package. It creates a new layer.
ENV
Sets an environment value that will be available inside the image and containers.
EXPOSE
Documents which network port the application listens on. It is a note, and does not open the port by itself.
USER
Chooses which user the application runs as, ideally a normal one rather than the administrator.
CMD and ENTRYPOINT
Define what starts when a container is created. ENTRYPOINT sets the main program, and CMD supplies default arguments or a default command.
Steps like RUN happen once, when the image is being built, and their results are frozen into layers. The start command runs every time a container is created. Keeping these two moments separate in your mind avoids many mistakes.
A Dockerfile is like a cooking recipe with numbered steps. “Start with this dough, add these ingredients, bake for this long, and serve with this sauce.” Anyone who follows the recipe gets the same dish.
7How an Image Is Built
From text file to finished package, step by step.
Gather the build context
You point Docker at a folder. The files in it, minus anything listed in an ignore file, are sent to the builder as the material it may copy from.
Pull the base image
The builder downloads the starting image if it is not already stored locally.
Execute each instruction
Every instruction that changes files is run in a temporary environment, and the resulting file changes are saved as a new layer.
Write the configuration and manifest
Docker records the start command, settings, and the list of layers with their fingerprints.
Tag the result
The finished image receives a name and a tag so you can refer to it easily.
sequenceDiagram
participant Dev as Developer
participant CLI as Docker Client
participant BLD as Builder
participant REG as Registry
Dev->>CLI: request a build
CLI->>BLD: send Dockerfile and build context
BLD->>REG: pull base image if missing
REG-->>BLD: base layers
BLD->>BLD: run each step, save each layer
BLD-->>CLI: finished image with name and tag
CLI-->>Dev: image ready
Build caching
Docker remembers the result of every step. If a step and everything before it have not changed, Docker reuses the saved layer instead of doing the work again. Once a step changes, that step and every step after it must be redone. So the order of steps matters a great deal: put things that rarely change, like installing the tools and libraries, near the top, and put things that change often, like your own source files, near the bottom.
Copy the list of dependencies first and install them, then copy the rest of your source files. That way, changing a single line of your own code does not force Docker to reinstall every dependency.
The ignore file
A file named .dockerignore lets you list things that should never be sent to the builder, such as version-control folders, temporary files, local notes, and secret keys. It makes builds faster, images smaller, and prevents accidental leaks.
8Choosing a Base Image
The first decision in every Dockerfile shapes size, speed, and safety.
The base image is the starting point that everything else is stacked on. A bigger base gives you more built-in tools and comfort. A smaller base gives you fewer files, faster downloads, and fewer places for security weaknesses to hide.
| Base Type | What It Is | Good For | Watch Out For |
|---|---|---|---|
| Full distribution image | A general operating-system userland with many tools | Learning, debugging, apps that need many system tools | Larger size and more software to keep patched |
| Slim variant | A trimmed version with unneeded files removed | A balanced default for many applications | Some tools you expect may be missing |
| Alpine-based | A very small Linux distribution | Tiny images | It uses a different C library, which can cause surprises with some software |
| Distroless | Only the runtime and application, with no shell or package manager | Production, where fewer tools mean a smaller attack surface | Harder to debug because there is no shell to log into |
| Scratch | An completely empty starting point | Single self-contained programs | You must include everything the program needs |
Choosing a base image is like choosing a suitcase. A giant trunk holds everything but is heavy to carry. A small backpack is light and quick, but you must pack carefully. The right choice depends on the trip.
Whatever base you choose becomes part of your application. Prefer official images and verified publishers, and keep them updated, because weaknesses found in a base become weaknesses in your image.
9Names, Tags, Digests, and Repositories
How you point at exactly the image you mean.
Reading an image name
A full image reference usually has up to three parts: the registry address, the repository path, and the tag or digest. For example, it might say where the library lives, then the owner and project name, then the version label. If you leave out the registry, Docker assumes Docker Hub, and if you leave out the tag, Docker assumes a tag called “latest”.
Registry
The server where images are stored, such as Docker Hub or a private company registry.
Repository
A named collection of related image versions, usually one project, like a shelf in the library.
Tag
A human-friendly label for one version inside the repository, often a version number.
Digest
A fingerprint of the exact image contents. It can never point to anything else.
Tag or digest?
Advantages of Tags
- Easy to read and remember
- Convenient for receiving fixes automatically when a publisher updates a version
- Good for development and quick experiments
- One image can have several tags at once, such as a full version and a short version
Disadvantages / Trade-offs
- A tag can be moved to a different build, so the same tag may not mean the same image tomorrow
- “latest” gives no guarantee of being newest or safest
- Hard to audit exactly what ran in production last month
A digest reference is the safest choice for production because it never changes. Many teams use a friendly tag while developing and switch to the digest, or a very specific version tag, for releases.
10Registries: Sharing and Storing Images
An image that stays on one laptop is not very useful.
A registry is a server that stores images and hands them out on request. Uploading an image is called pushing, and downloading is called pulling. Docker Hub is the best-known public registry, and it hosts many official images for popular software. Cloud providers and other services also offer registries, and companies often run private ones to keep their own images internal.
flowchart LR
DEV["Developer machine"] -->|"push"| REG["Registry"]
REG -->|"pull"| CI["Build and test server"]
REG -->|"pull"| PROD["Production server"]
REG -->|"pull"| COL["Teammate laptop"]
Public registries
Open to everyone. They are perfect for widely used software and for sharing open-source projects. Look for official and verified publisher badges before trusting an image.
Private registries
Restricted to your organization. They store proprietary applications and can be integrated with your access controls, scanning, and deployment tools.
Smart pulling
When you pull an image, Docker first fetches the manifest, then downloads only the layers that are missing locally. If you already have most of the layers, the pull is fast. Each downloaded layer is checked against its fingerprint to make sure it arrived intact and unmodified.
Public registries may limit how often anonymous users can pull. Teams with many build machines often sign in or run a local mirror or private registry, so their builds do not stall.
11Multi-Architecture Images
One name that works on different kinds of computers.
Computers do not all speak the same machine language. Many servers and laptops use Intel-style processors, while many newer laptops and cloud machines use ARM processors. A program built for one will not run directly on the other. An image is therefore built for a specific platform.
To avoid confusion, publishers create a multi-architecture image. It has one name, but behind it the image index points to a separate image for each platform. When you pull, Docker checks your computer type and picks the matching one automatically. You type the same name everywhere and get the right build.
Think of a book sold in one store under a single title, but printed in several languages. The clerk hands each customer the copy in the language they read, without the customer asking for a special edition.
If you build an image on an ARM laptop and deploy it to an Intel server without building for that platform, it may fail to start or run slowly through emulation. Check the platform when things behave oddly.
12Making Images Small: Multi-Stage Builds
Ship the finished dish, not the whole kitchen.
Building an application often needs heavy tools: compilers, test runners, and package managers. Running it needs none of those. If you leave the heavy tools inside the final image, it becomes large, slow to pull, and full of unnecessary software that could contain weaknesses.
A multi-stage build solves this. You write a Dockerfile with more than one FROM. The first stage has all the build tools and produces the finished application. The final stage starts from a small base and copies only the finished result from the first stage. Everything else is left behind and does not appear in the final image.
flowchart LR
S1["Stage 1: build tools + source code"] -->|"produces finished application"| OUT["Built application files"]
OUT -->|"only these are copied"| S2["Stage 2: small runtime base"]
S2 --> FIN["Final small image"]
A restaurant kitchen is messy, full of knives, pans, and scraps. The customer only receives the finished plate. Multi-stage builds serve the plate and keep the messy kitchen out of the dining room.
Advantages
- Much smaller final images
- Fewer installed tools, so a smaller attack surface
- Faster downloads and starts
- One Dockerfile handles both building and packaging
Disadvantages / Trade-offs
- Slightly more complex Dockerfile to read
- Debugging the final image can be harder, since tools are missing
- You must remember to copy every file the program needs at run time
Other ways to shrink an image
Pick a smaller base
A slim or distroless base can save hundreds of megabytes.
Install only what you need
Skip optional packages and remove package caches in the same step that creates them.
Use an ignore file
Keep logs, test data, and version-control folders out of the build.
Combine related steps carefully
Temporary files must be removed in the same layer where they were created, or they will stay in the earlier layer.
13The Life of an Image: Data Flow from Build to Run
Follow one image on its whole journey.
stateDiagram-v2
[*] --> Written: Dockerfile written
Written --> Built: build
Built --> Tagged: name and tag applied
Tagged --> Scanned: security scan
Scanned --> Pushed: upload to registry
Pushed --> Pulled: downloaded by a server
Pulled --> InUse: containers started from it
InUse --> Replaced: newer version released
Replaced --> Removed: old image cleaned up
Removed --> [*]
Written and built
A Dockerfile becomes a finished, frozen image.
Tested and scanned
Automated tests run against containers made from the image, and security scanners check its contents.
Pushed and pulled
The image is stored in a registry and downloaded wherever it is needed.
Run as containers
Each start creates a new container with its own thin writable layer, while the image stays unchanged.
Replaced and retired
A new version is built, containers are switched over, and old images are removed to free space.
A good practice is to build the image once, then move that exact same image through testing and into production. Rebuilding at each stage risks producing subtly different results.
14Image Security
An image is software you did not fully write, so it deserves careful checking.
Every image contains many packages, and any of them can have a known weakness. Because images are shared and reused widely, one weak base image can spread a problem to thousands of applications. Good security starts before the image is built and continues after it is deployed.
Start from trusted, minimal bases
Prefer official or verified publishers, and keep the contents small. Fewer packages mean fewer possible weaknesses to patch.
Scan images regularly
Scanners compare the packages inside an image against lists of known weaknesses. Run them during builds and again later, because new weaknesses are discovered all the time.
Never bake in secrets
Passwords, tokens, and keys must not be stored in any layer. Supply them when a container starts, using proper secret handling.
Run as a normal user
Use the USER instruction so that the application does not run with administrator rights inside the container. If someone breaks in, the damage is limited.
Know what is inside
A software bill of materials lists all the components in an image, like the ingredients label on food. It helps you quickly find affected images when a new weakness is announced.
Sign and verify
Digital signatures prove who published an image and that it was not changed on the way. Teams can require that only signed images run in production.
Rebuild regularly
An image is frozen, so it does not receive fixes on its own. Rebuild it from updated bases on a schedule to pick up security patches.
The same read-only nature that makes images reliable also means an old image keeps its old weaknesses forever. A perfectly safe image last year can be risky today.
15Inspecting and Monitoring Images
Because you cannot manage what you cannot see.
Listing
Docker can list every image stored on a machine, with its name, tag, ID, age, and size.
Inspecting
A detailed report shows the configuration, start command, environment values, and layer fingerprints of a single image.
History
A step-by-step view lists each layer, the instruction that created it, and how much space it uses. It is the best way to find which step made an image large.
Scanning reports
Security tools summarize known weaknesses in the image’s packages, ranked by severity.
What to track over time
Teams often keep an eye on a few simple measures: the size of each image, the time it takes to build, the number of known serious weaknesses, the age of the base image, and how many images in use are old or unused. Watching these numbers as trends helps you notice when an image is quietly growing or aging.
Disk space and cleanup
Old images accumulate quickly, especially on build servers where every change makes a new image. Docker can remove images that are not used by any container, and it can report how much disk space images consume. Clean up on a schedule, and always review what will be removed before agreeing.
Managing images is like managing a fridge. If you never check it, old and forgotten items pile up, and some go bad. A regular look at what is inside, and what is past its date, keeps everything fresh and the shelf space free.
16Advantages and Trade-offs of Images
An honest look at the strengths and limits of the image model.
Advantages
- Consistency: the same image behaves the same on a laptop, a test server, and in production
- Portability: any machine with a compatible runtime can run it
- Efficiency: shared layers save disk space and network traffic
- Speed: build caching and small sizes make builds and pulls fast
- Repeatability: the Dockerfile documents exactly how the image was made
- Easy rollback: keep the previous image, and start it again if a release goes wrong
Disadvantages / Trade-offs
- Images are frozen and do not update themselves, so they need regular rebuilding
- Careless builds create huge, slow images
- Hidden data left in old layers can create security risks
- Images are built for a specific platform, so cross-platform use needs planning
- Trusting third-party images requires checking their source and contents
17Design Patterns and Anti-patterns
Habits worth copying and habits worth avoiding.
Helpful patterns
One image, one purpose
Each image packages a single application or role, which keeps it small and easy to update.
Multi-stage builds
Build with heavy tools, ship with a slim runtime.
Shared organization base image
A company maintains its own approved, hardened base and every team builds on it, so fixes are applied in one place.
Immutable releases
Never change a deployed image. Build a new version, give it a new tag, and deploy that.
Harmful anti-patterns
Problem
Fixing a running container by hand and saving it as a new image.
Why It’s Harmful
The change is undocumented and impossible to repeat. Nobody can explain how the image was made, and hidden changes pile up over time.
Correct Approach
Put the change into the Dockerfile, rebuild the image, and replace the container.
Problem
Depending on the “latest” tag for a base or for deployment.
Why It’s Harmful
The image can change silently between builds or restarts, causing surprise failures that are hard to trace.
Correct Approach
Use specific version tags, or better, digests, and update them deliberately.
Problem
Packing many unrelated programs, a database, and a shell full of debugging tools into one giant image.
Why It’s Harmful
The image is huge and slow, hard to secure, and cannot be updated or scaled piece by piece.
Correct Approach
Split the system into several focused images and connect them as separate containers.
Problem
Copying the whole project folder into the image, including secret files and version-control data.
Why It’s Harmful
Secrets leak to anyone who gets the image, and the image grows with files it never needs.
Correct Approach
Use an ignore file and copy only the files the application needs.
18Best Practices and Common Mistakes
A short checklist that will save you a lot of trouble.
Choose a small, trusted base
Smaller and official bases download faster, start faster, and contain fewer weaknesses.
Order steps for caching
Put rarely changing steps first and frequently changing ones last.
Pin versions
Use specific tags or digests for bases and packages so builds are repeatable.
Use multi-stage builds
Leave compilers and test tools behind in the final image.
Run as a non-administrator user
Limit what the application can do if it is ever compromised.
Add helpful labels
Labels can record the owner, source repository, and version, so anyone can trace an image back to where it came from.
Scan, rebuild, and clean regularly
Automate weakness scanning, refresh images from updated bases, and remove old unused images.
Mistakes beginners often make
Removing a file in a later step does not shrink the image or erase the file from earlier layers. Remove temporary files in the same step that creates them.
The EXPOSE instruction is only documentation. Visitors cannot reach the application until a port is actually published when the container starts.
Sending an enormous folder to the builder makes every build slow. Keep the context small and use an ignore file.
An image is a template, not a place to keep changing data. Store data in volumes or external services and let containers stay disposable.
19Docker Images in the Real World
Where you will meet images in everyday engineering.
Continuous integration and delivery
Build servers create an image for each code change, run tests inside containers from it, and then send the very same image toward production.
Consistent developer environments
Teams publish an image with the right tools and versions, and every developer starts from it, so a new hire is productive on the first day.
Microservices
Each small service has its own image, so teams can release, update, and scale them independently. Companies such as Netflix and Spotify have publicly described container-based service architectures.
Trying software safely
Instead of installing a database or a tool on your computer, pull its official image, start a container, experiment, and delete it afterwards.
Cloud and cluster platforms
Cloud container services and Kubernetes all run images pulled from registries. The image you built on your laptop is the same kind of package that large platforms run at scale.
Repeatable data and machine learning work
Data scientists freeze their exact tool versions in an image, so an experiment can be repeated identically months later by someone else.
| Situation | Without Images | With Images |
|---|---|---|
| Onboarding a developer | Long setup document and manual installs | Pull one image and start working |
| Deploying a release | Update servers by hand, risk of differences between them | Run the new image on every server |
| Reproducing a bug | Guess what differs between machines | Run the exact same image locally |
| Rolling back | Complicated manual reversal | Start the previous image again |
20Frequently Asked Questions
Quick answers to what beginners ask most.
No. An image is a read-only template, and a container is a running instance created from it. One image can produce many containers.
Not in place. Images are read-only. To change anything, you build a new image, which usually reuses many layers from the old one.
Layers let Docker share common pieces between images, cache build steps, and download only what is missing. This saves time, bandwidth, and disk space.
On your machine, Docker keeps them in its own storage area managed by the engine. Shared copies live in registries such as Docker Hub or a private company registry.
They contain the files and tools of an operating system environment, such as a minimal Linux userland, but not a kernel. Containers borrow the kernel of the host.
A tag is a friendly label that can be moved to point at a different build. A digest is a fingerprint of the exact contents, so it always refers to the same image.
Common reasons are a large base image, leftover build tools, package caches, and unneeded files copied in. Inspect the history of the image to see which step added the most, then use a smaller base, an ignore file, and multi-stage builds.
Official images and verified publishers are generally a good start, but you should still scan them, pin versions, and keep them updated. Be cautious with unknown publishers.
A Linux image runs on any system that provides a Linux kernel. Docker Desktop on Mac and Windows quietly runs a small Linux environment for this reason. The processor type must also match, or a multi-architecture image must be used.
Docker generally refuses to remove an image that is still used by a container unless you force it. Removing a container, on the other hand, never deletes the image it came from.
Start with the difference between an image and a container, then learn what a Dockerfile does and how layers and caching work. After that, look at tags, registries, and multi-stage builds.
21Summary and Key Takeaways
A Docker image is a read-only, layered package that holds an application together with its libraries, tools, and settings, plus instructions for how to start it. It is described by a Dockerfile, built into stacked layers that Docker can cache and share, identified by fingerprints, named with tags, and stored in registries so that any machine can pull it. Containers are created from images, and while containers come and go, the image stays unchanged and trustworthy. Keep images small, pinned, scanned, and free of secrets, and they will give you consistent behavior everywhere your software runs.
Key Takeaways
- An image is a read-only template — it holds the application and everything it needs, and containers are the running instances created from it.
- Layers make images efficient — they are shared, cached, and downloaded only when missing, but deleted files still occupy earlier layers.
- The Dockerfile is the recipe — it documents exactly how an image is made, and the order of its steps controls build speed through caching.
- Names are not fingerprints — tags are friendly but movable, while digests always point to the exact same contents, so use them where repeatability matters.
- Small is better — choose lean bases, use an ignore file, and use multi-stage builds to leave build tools behind.
- Security is ongoing — use trusted bases, never bake in secrets, run as a normal user, scan, sign, and rebuild regularly, because frozen images age.
- Build once, promote everywhere — push the same tested image through every stage, and keep the previous version handy for easy rollback.