Claudio Cicali
Welcome to the official website of Claudio Cicali. This site serves as a central hub for information and updates.
Learn moreFollow along for the latest updates and announcements. Visit the homepage for more information.
Understanding Docker Through the Reality of Containerised Work
Containerisation is often presented through tidy diagrams: an application sits inside a container, the container runs on a host, and the same package behaves consistently from a developer’s laptop to a production server. Docker makes that model practical, but understanding it requires more than memorising commands. It means examining how software is assembled, isolated, delivered, monitored and retired.
For Australian learners, the subject has a direct connection to everyday technology work. A team in Sydney may build on Apple silicon, test against a service hosted in an Australian cloud region, and deploy to a platform governed by business, privacy and security requirements. Docker is useful in that environment because it makes the moving parts visible, provided its limits are understood clearly.
Containers solve a packaging problem
A software application rarely consists of one file. It may depend on a particular Python version, system libraries, environment variables, database drivers, certificates and background services. When those dependencies are installed differently on two computers, the familiar “works on my machine” problem appears.
A container packages an application with much of the user-space environment it needs. The package is created from an image, and a running instance of that image is a container. The image is immutable in principle: when a change is required, a new image is built. This gives teams a traceable artefact that can be tested and promoted between environments.
Docker does not create a complete virtual computer for every application. Containers share the host operating system’s kernel, while processes are separated through operating-system features such as namespaces and control groups. Virtual machines generally provide a stronger hardware-level boundary and carry a full guest operating system, so they remain useful where isolation, legacy support or a different kernel is required.
Images, layers and Dockerfiles
A Dockerfile records the recipe for building an image. Instructions commonly select a base image, copy application files, install dependencies, expose a network port and define the command that starts the process. The file is executable documentation: a colleague can inspect how the environment was assembled rather than relying on an undocumented workstation.
Docker images are formed from layers. If a Dockerfile changes only near its final steps, earlier layers may be reused from the local build cache. This speeds up development and reduces transfers to a registry. The benefit depends on sensible ordering: stable operating-system packages and dependency manifests are usually placed before frequently changing source code.
Base-image selection deserves careful attention. A small Alpine image may reduce download size, while a Debian- or Ubuntu-based image can offer broader compatibility and easier troubleshooting. “Smallest” is not automatically “best”; a team also needs security updates, reliable package support and a predictable debugging process. Image tags such as latest can move unexpectedly, so production systems often pin a version or digest.
The practical Docker workflow
A typical workflow begins with docker build, which turns a Dockerfile and build context into an image. docker run creates a container from that image, while docker ps, docker logs and docker exec help inspect a running instance. These commands are simple enough for a learner to use on a laptop in Melbourne or Adelaide, yet they represent the same basic lifecycle found in larger systems.
Port mapping connects a host port to a port inside the container. Environment variables provide configuration without baking passwords or site-specific settings into the image. A .dockerignore file prevents unnecessary material, such as local caches, test output and secret files, from entering the build context.
Local development usually involves several services: an application, a database, perhaps a queue and an observability tool. Docker Compose describes those services in a YAML file so they can be started together. Compose is valuable for repeatable development, although it should not be mistaken for a complete production orchestration platform.
Storage changes the mental model
Containers are designed to be replaceable. Data written only to a container’s writable layer can disappear when that container is removed, which is exactly what makes rebuilding and redeploying manageable. Databases, uploaded files and generated reports therefore need deliberate storage outside the disposable container layer.
Docker volumes provide managed storage, while bind mounts connect a container to a directory on the host. Each choice affects portability, permissions, backups and performance. A volume may suit a database in local development; a bind mount may be convenient when editing source code. In a production environment, storage often belongs to a cloud service or network system rather than the container host.
The same principle applies to ordinary household organisation: deciding where an object belongs before storing it prevents later confusion, much like the practical ideas in creative cutting-board storage. For containerised applications, the equivalent question is whether information belongs in an image, a temporary filesystem, a named volume or an external data service.
Networking and multi-service applications
Each container has a network identity within a Docker network. Services on the same user-defined network can usually reach one another by service name, avoiding hard-coded IP addresses. An application might connect to a database at db:5432, while users reach the application through a published host port or a reverse proxy.
This arrangement makes the boundary between internal and external traffic easier to describe. A database does not need to be exposed directly to the public internet merely because the application needs to access it. Firewalls, network policies and authenticated service connections still matter; Docker’s default networking behaviour is not a replacement for security architecture.
For a business operating in Australia, network location can influence latency and compliance discussions. A service hosted in an AWS, Microsoft Azure or Google Cloud region near Sydney may provide a different experience from one hosted overseas. The correct choice depends on customers, contracts, resilience requirements and data-handling obligations, not on containerisation alone.
Security and operational responsibility
A container is not automatically a security boundary. Running processes as root, using unverified images, leaving unnecessary packages installed and exposing administrative ports can create avoidable risk. Teams should scan images, use trusted registries, patch base images and apply the least privilege needed by each process.
Secrets require separate handling. Passwords and API keys should come from a secrets manager or protected deployment configuration, rather than being committed to a Dockerfile or source repository. Logs should avoid leaking credentials or personal information. These practices matter to Australian organisations dealing with customer records under the Privacy Act and, in some industries, sector-specific regulatory expectations.
Docker Desktop is convenient for individual development, but commercial licensing may affect larger organisations. A small consultancy in Brisbane may use it differently from a national enterprise with central procurement, identity controls and managed developer workstations. Operational responsibility also includes backups, incident response, patch schedules and knowing who owns each image after it enters a registry.
From local containers to production
A container running on a laptop is not the same thing as a reliable production service. Production requires health checks, resource limits, restart behaviour, centralised logs, metrics, vulnerability management and a deployment process that can be reversed. These concerns become more important when an application serves customers across multiple Australian time zones and must remain available during maintenance.
Docker can run directly on a host, through a managed container service or under an orchestrator such as Kubernetes. Orchestration adds scheduling, service discovery, scaling and rollout controls, but it also introduces substantial complexity. A small application may be better served by a managed platform with a simple deployment interface than by an elaborate cluster maintained by a team without specialist expertise.
The learning path is easier when documentation is treated as part of the system. A developer can keep Dockerfiles, Compose files, runbooks and architecture notes beside the application, while a learner can use downloadable technical resources from Claudio Cicali to study concepts away from the terminal. The durable skill is the ability to explain why a service is packaged, where its data lives and how it will be operated.
What containerisation cannot replace
Docker does not fix poorly designed software, unclear ownership or inadequate testing. A container can faithfully package an application that has insecure dependencies, inefficient queries or fragile configuration. Reproducible packaging makes those faults easier to move between environments, not less serious.
It also does not remove the need to understand operating systems, networking, storage and application architecture. When a container fails, useful diagnosis may involve exit codes, process signals, DNS, file permissions, CPU limits or a missing shared library. The command line is only the visible surface of a deeper model.
A sound approach is therefore incremental: containerise a small service, inspect its image, test its configuration, add persistent storage deliberately and document its network connections. Then assess whether production needs a basic managed service or a larger orchestration system. The essential lesson is that Docker provides a repeatable boundary around software, while reliability still depends on the decisions made around that boundary.
Containerisation is best remembered as a method for making application environments consistent and replaceable. Images describe the package, containers execute it, volumes preserve selected data, networks connect services and operational practices keep the whole arrangement safe. Docker is the tool; clear reasoning about software, people and infrastructure is what makes the tool dependable.