Glossary
Docker
Docker helps run the same application, runtime, and dependencies in local development, CI, and on a server. However, it does not replace application design, data management, or secure operations.
Short definition
An application packaged as an image and run as an isolated process.
Docker builds an image: an immutable package of layers containing files and instructions for starting a process. One or more containers can then be created from a single image. Each container has its own writable runtime layer, network configuration, and process, but it does not simulate an entire separate operating system.
A container is not a virtual machine. Multiple containers on the same host share its kernel, so their isolation boundaries and compatibility differ. The practical benefit lies mainly in repeatably building a PHP application, frontend, database, or worker without manually installing different versions on every computer.
Use cases
Where containerization solves a specific operational problem
Docker is useful when an application needs predictable dependencies and separate running components.
- a local PHP application with the same runtime, Composer, and extension versions as CI
- separate web server, PHP-FPM, worker, database, and Redis services in one development environment
- a repeatable image for tests, static analysis, and artefact builds
- isolating several projects that would otherwise conflict over a port or dependency version
- running a one-off import, queue worker, or scheduled job with the same code as the application
Practical example
A PHP e-commerce application with an internal app and public entry point
The local environment has four services: nginx accepts browser requests, the PHP application runs the code, PostgreSQL stores relational data, and Redis provides caching or coordination. Only nginx publishes a local port; the application and database address each other by internal service names over the Docker network.
CI builds the application image from the Composer lock file, runs tests and static analysis inside it, and tags the resulting image with a specific version. Production deployment therefore does not take a directory from a developer’s computer. It must still handle secrets, database migrations, monitoring, and data recovery separately.
services:
app:
build: .
expose:
- '9000'
nginx:
image: nginx:alpine
ports:
- '127.0.0.1:8080:80'
depends_on:
- app
How it works
From source code to a running process
An image describes a prepared environment. A container is a specific run of that image with environment-specific configuration.
- Dockerfile It describes the base image, dependency installation, application copying, and default command. It should be built deterministically from a lock file.
- Build and layers A build creates content-addressed layers. A good instruction order allows the dependency layer to be reused instead of downloading everything again after every code change.
- Image registry A completed image can be stored under a specific tag or digest, allowing the same artefact to be used in CI, staging, and production.
- Container The runtime starts the specified process from the image with environment variables, limits, a network, and possibly a mounted volume. When the main process exits, the container stops.
- Supporting services Compose or another orchestrator describes multiple services, their networks, volumes, and dependencies. The application then connects to a service by its internal name, not through an arbitrary localhost port.
Key parts
Images, containers, volumes, networks, and Compose are not the same
Distinguishing these concepts prevents the common misconception that deleting or restarting a container automatically protects data.
Images and layers
An image is a template composed of immutable filesystem-change layers. Each build step may create another layer, so secrets and unnecessary build artefacts do not belong in an image.
Container and process
A container usually runs one primary responsibility, such as PHP-FPM or a worker. It is not a full server into which a production fix should be installed manually.
Volume and state
Database data, uploads, and other persistent files need clearly designated persistent storage. A container’s writable layer is ephemeral and is not a backup strategy.
Networks and published ports
Services on the same Docker network communicate internally. Publishing a port creates a rule from the host to the container; by default, it may be accessible on all host network interfaces.
Docker Compose
A compose.yaml file keeps the description of a local multi-service environment in versioned code. It helps development but does not itself provide production orchestration, rollouts, or monitoring.
Benefits and limitations
Repeatability is a benefit, not automatic security.
Benefits
- the same runtime and extension versions for developers, CI, and servers
- separate services with less risk of dependency conflicts
- a versioned image build instead of manual machine configuration
- easier local startup of a database, cache, worker, and web server
What to watch for
- an image with an outdated base layer carries known security and operational problems
- secrets in a Dockerfile, image, or log remain accessible in history and registries
- a published database port may be reachable outside the intended environment
- a container without a volume, backups, and a recovery procedure does not protect important data
- too many services in a small project may make development more complicated
Scope of use
Use it where repeatable execution outweighs the cost of the operational layer.
Docker makes sense for a PHP application with several dependencies, for teams, CI, and long-term operations where rebuilding the same environment matters. For example, it can separate public nginx, the application, a worker, and the database without installing their dependencies directly on the host system.
A simple one-off script may not need a complex Compose file or its own registry workflow. Containerization should not conceal missing documentation, unclear environment variables, or an inappropriate split into microservices.
What to consider
Both build and runtime should be defined, constrained, and traceable.
A good container environment minimises manual steps while clearly showing where data, ports, and secrets reside.
- build an image from a lock file and unambiguously identify the artefact in use
- separate build dependencies from the final runtime image when this genuinely reduces its scope
- do not store passwords, tokens, or private keys in an image or Dockerfile
- publish only ports that must be available outside the internal network
- keep persistent data, backups, and recovery outside the lifecycle of a single container
- run the same image in CI and subsequent environments, but verify each environment’s configuration separately
Common questions
What Docker solves and what it does not
Is Docker a virtual machine?
No. A container is an isolated process that shares the host kernel. A virtual machine contains its own operating system and kernel, so it has different properties and overhead.
Is an image the same as a container?
No. An image is an immutable template; a container is a specific running instance with a writable runtime layer and configuration.
Is a database container enough to back up data?
No. Data should reside in designated persistent storage with backups, tested recovery, and an operational plan.
Does EXPOSE publish a port to the internet?
No. EXPOSE only declares the image’s intended port. Actual host access requires a publish rule, for example through ports or docker run -p.
How I design an application’s technical foundation
I keep development and production environments as close as practical to the application’s real runtime.
For PHP projects, I address how the application, database, cache, workers, and integration services work together so their state can be traced and changed safely.