If you work anywhere remotely IT-adjacent, it's extremely unlikely you won't have at least some familiarity with Docker, or have heard somebody discussing “dockerizing” an application, but what does this mean, and why would it be a good thing?
Michael Nicholson
Cloud Solution Engineer
Dockerizing an application means to create a Docker container for your application. This container will then encapsulate the application's code, dependencies, and runtime environment, making it easy to deploy, scale, and run on any platform that supports Docker.
Dockerizing an application provides several benefits.
Consistent environments: Docker containers encapsulate the application's code, dependencies, and runtime environment, ensuring that it runs consistently across different stages of development (development, testing, staging, and production) and on different platforms. This reduces the chances of encountering issues related to discrepancies between environments, effectively eliminating any "it works on my machine" problems.
Faster onboarding: New team members can quickly set up their development environments by simply running the containerised application, without having to manually configure dependencies or system settings. This speeds up the onboarding process and allows developers to become productive sooner.
Easier dependency management: Docker allows you to bundle your application's dependencies within the container, isolating them from the host system. This helps to avoid conflicts with other applications or system packages and makes it easy to manage and update dependencies.
Many common dependencies (e.g. databases and programming languages) already have prebuilt docker images that you can use directly, and thus avoid having to install them on every laptop.
Simplified deployment: Docker containers can be easily deployed to various cloud platforms and hosting providers – such as Divio – that support container orchestration. This simplifies the containerized deployment process, reduces the risk of errors, and can save time for overburdened teams.
Scalability: Containerized applications can be easily scaled horizontally by adding or removing instances as needed. This can help small teams manage changes in load or demand without having to spend significant time on manual scaling or re-architecting the application.
Better resource utilisation: Docker containers share the host system's kernel and can run multiple containers with minimal overhead compared to running multiple virtual machines. This improves resource utilisation and can reduce infrastructure costs, which is beneficial for small teams with limited budgets.
Enhanced collaboration: By using a container registry, development teams can share and distribute their Docker images, making it easier for other team members or external collaborators to access and run the application.
In short, dockerizing your application will help your team focus on application development, rather than having to spend time resolving environment-related issues.
Of course not. From a CTO perspective, dockerizing your company's application(s) comes with its own set of pros and cons, some of which overlap with your development team, and some of which are unique to your position, so let's take a quick look at both the advantages and the potential drawbacks for you.
Streamlined development process: Docker helps maintain consistent environments across various stages of development, reducing the time spent on fixing environment-related issues, and thus allowing teams to focus on building features and improving the application.
Simplified deployment and scaling: Docker containers can be easily deployed to multiple cloud providers and on-premises environments that support container orchestration. This flexibility simplifies deployment and scaling processes, improving the overall agility of the organisation.
Cost efficiency: Docker containers share the host system's kernel and resources, resulting in a lower overhead compared to traditional virtual machines. This improved resource utilisation can lead to cost savings in infrastructure and reduced total cost of ownership (TCO).
Enhanced collaboration: Docker makes it easier to share and distribute applications as container images through container registries, fostering better collaboration among development teams and external partners.
Easier talent acquisition: Docker has become a widely-adopted technology, and familiarity with containerisation is now a common skill among developers. Implementing Docker within the organisation can make it more attractive to potential talent and simplify the hiring process.
Learning curve and complexity: Adopting Docker may require team members to learn new concepts and tools, which can be time-consuming initially. Additionally, containerisation adds another layer of complexity to the overall technology stack, potentially increasing maintenance efforts.
Security concerns: While containers can provide some level of isolation, they do not offer the same level of security as virtual machines since they share the host system's kernel. This requires careful attention to security best practices when deploying and managing containerised applications.
Legacy systems and compatibility: Dockerizing an application may not always be easy, feasible or beneficial for legacy systems that are deeply integrated with their host environment or rely on specific hardware or software configurations.
Risk of Vendor lock-in: Relying on specific container orchestration platforms, such as Kubernetes or Amazon ECS, can introduce a degree of vendor lock-in, making it challenging to switch providers or platforms in the future.
Performance considerations: Although Docker containers generally have lower overhead than virtual machines, specific use cases or workloads may not perform optimally in a containerised environment, and performance tuning might be required.
Great! Welcome to the world of Docker! Each application is of course unique, and may come with specific challenges or requirements of its own, but in general, following the following steps should get you a long way:
Install Docker: Download and install Docker on your development machine. Ensure that it's running correctly by executing docker --version
and docker info
commands.
Create an empty Dockerfile: A Dockerfile is a script that contains instructions to build a Docker image for your application. In the root directory of your application, create a file named Dockerfile
. The content of this file will vary depending on your application's requirements and the base image you choose.
Define the base image: The base image is the foundation of your container. Choose an appropriate base image that matches your application's runtime environment, such as the official Python or Node.js images.
Copy your application code and dependencies: In the Dockerfile, use the COPY
command to copy your application's source code and configuration files into the container. Also, use the appropriate package manager to install the dependencies defined in your application's manifest file, such as package.json
for Node.js or requirements.txt
for Python.
Expose required ports: If your application listens on a specific port, use the EXPOSE
command in the Dockerfile to specify that port, allowing the container to accept incoming connections.
Set the entrypoint or command: Define the command that will be executed when the container starts using the ENTRYPOINT
or CMD
instruction. This command starts your application's server or main process.
Build the Docker image: In the terminal, navigate to your application's root directory and run docker build -t your-image-name
. to build the Docker image, replacing "your-image-name" with a suitable name for your application's image.
Run the container: After building the image, you can run a container from it using the docker run
command. For example, docker run -d -p host-port:container-port your-image-name
, replacing host-port
with the desired port on your host machine, container-port
with the port exposed in the Dockerfile, and your-image-name
with the name of your application's image.
Test your containerized application: Access your application in a web browser or API client using the host's IP address or hostname and the host-port you specified when running the container to ensure it's working correctly.
Publish the Docker image (Optional): You can push the Docker image to a container registry like Docker Hub or Google Container Registry, making it available for others to download and use.
To put the previous steps into perspective, here is a simple Dockerfile
for a Django application running on port 8000 (note this is only using the built in Django runserver
, which isn't suitable for production use, so please don't just copy/paste this into production-ready code).
# Use the official Python base image
FROM python:3.10
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Create and set the working directory
RUN mkdir /app
WORKDIR /app
# Install project dependencies
COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt
# Copy the application code into the container
COPY . /app/
# Expose the port your Django app runs on
EXPOSE 8000
# Start the Django development server
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
The Divio platform is built to support dockerized applications. In fact, dockerizing your application is a pre-requisite for deployment on the Divio platform. To help you get up and running with your application on Divio please check out our documentation.