Utility Containers in Docker: A Powerful Tool for Local Development Without Polluting Your Machine

In our previous blogs, we explored how to build real-world multi-container applications using Docker and simplify container orchestration using Docker Compose. In this post, we’ll delve into utility containers, an often-overlooked but extremely powerful use of Docker that can dramatically streamline your development workflow. Why Utility Containers? Imagine you're starting a fresh Node.js project. Typically, you’d run: npm init But to run that, you'd need Node.js installed on your host machine. What if you're working on a lightweight Linux server, a CI/CD pipeline, or a constrained environment where you don’t want to install Node.js globally? This is where utility containers come in. They allow you to run one-off or repetitive tasks using Docker containers without installing dependencies on your local machine. Step 1: Create a Utility Container Let’s create a Dockerfile that uses Node.js as its base: Practice Resource Dockerfile FROM node:14-alpine WORKDIR /app We're using the official lightweight Node.js image. The WORKDIR directive sets the default working directory inside the container to /app. We don’t add a CMD because we want this container to be flexible – capable of running any npm command like npm init, npm install, or npm test. Now build the Docker image: docker build -t node-util . Step 2: Run the Utility Container Let’s say you have a project directory at /Users/mayank/projects/util-node. Navigate to it and run: docker run -it -v $(pwd):/app node-util npm init -it: Runs the container interactively -v $(pwd):/app: Mounts your current directory to the container’s /app directory node-util: The image you built npm init: The command to execute inside the container After the command finishes, you’ll notice a package.json file generated in your local folder. Step 3: Simplify with ENTRYPOINT Let’s make it even easier. Add an ENTRYPOINT instruction to the Dockerfile so you don’t have to type npm every time: Updated Dockerfile FROM node:14-alpine WORKDIR /app ENTRYPOINT ["npm"] Now you can run commands like this: docker run -it -v $(pwd):/app node-util init or docker run -it -v $(pwd):/app node-util install express Docker will automatically prepend npm to your command. This is extremely helpful in reducing errors and typing effort. Step 4: Use Docker Compose for Even More Simplicity Running the long docker run command repeatedly can be tiring. Let’s use Docker Compose to define the setup once. docker-compose.yaml version: '3.8' services: npm: build: ./ stdin_open: true tty: true volumes: - ./:/app Now you can run: docker-compose run npm init or docker-compose run npm install express Docker Compose takes care of mounting the volume and setting up the working directory, so you don’t have to repeat those parameters every time. Bonus: Using Utility Containers for Other Tools You’re not limited to Node.js. You can create utility containers for: Python: FROM python:3.10 Go: FROM golang:1.20 Terraform: FROM hashicorp/terraform:latest Just change the base image and entrypoint accordingly. Summary Utility containers are a powerful and clean way to run development tasks without polluting your host machine. When combined with Docker Compose, they offer a repeatable, team-friendly development experience. They are ideal for bootstrapping projects, running tests, building apps, or using tools that aren’t worth installing globally. Instead of installing language runtimes or package managers on every machine, create utility containers once and use them everywhere.

May 4, 2025 - 19:26
 0
Utility Containers in Docker: A Powerful Tool for Local Development Without Polluting Your Machine

In our previous blogs, we explored how to build real-world multi-container applications using Docker and simplify container orchestration using Docker Compose. In this post, we’ll delve into utility containers, an often-overlooked but extremely powerful use of Docker that can dramatically streamline your development workflow.

Why Utility Containers?

Imagine you're starting a fresh Node.js project. Typically, you’d run:

npm init

But to run that, you'd need Node.js installed on your host machine. What if you're working on a lightweight Linux server, a CI/CD pipeline, or a constrained environment where you don’t want to install Node.js globally?

This is where utility containers come in. They allow you to run one-off or repetitive tasks using Docker containers without installing dependencies on your local machine.

Step 1: Create a Utility Container

Let’s create a Dockerfile that uses Node.js as its base:

Practice Resource

Dockerfile

FROM node:14-alpine
WORKDIR /app

We're using the official lightweight Node.js image. The WORKDIR directive sets the default working directory inside the container to /app.

We don’t add a CMD because we want this container to be flexible – capable of running any npm command like npm init, npm install, or npm test.

Now build the Docker image:

docker build -t node-util .

Step 2: Run the Utility Container

Let’s say you have a project directory at /Users/mayank/projects/util-node. Navigate to it and run:

docker run -it -v $(pwd):/app node-util npm init
  • -it: Runs the container interactively
  • -v $(pwd):/app: Mounts your current directory to the container’s /app directory
  • node-util: The image you built
  • npm init: The command to execute inside the container

After the command finishes, you’ll notice a package.json file generated in your local folder.

Step 3: Simplify with ENTRYPOINT

Let’s make it even easier. Add an ENTRYPOINT instruction to the Dockerfile so you don’t have to type npm every time:

Updated Dockerfile

FROM node:14-alpine
WORKDIR /app
ENTRYPOINT ["npm"]

Now you can run commands like this:

docker run -it -v $(pwd):/app node-util init

or

docker run -it -v $(pwd):/app node-util install express

Docker will automatically prepend npm to your command. This is extremely helpful in reducing errors and typing effort.

Step 4: Use Docker Compose for Even More Simplicity

Running the long docker run command repeatedly can be tiring. Let’s use Docker Compose to define the setup once.

docker-compose.yaml

version: '3.8'
services:
  npm:
    build: ./
    stdin_open: true
    tty: true
    volumes:
      - ./:/app

Now you can run:

docker-compose run npm init

or

docker-compose run npm install express

Docker Compose takes care of mounting the volume and setting up the working directory, so you don’t have to repeat those parameters every time.

Bonus: Using Utility Containers for Other Tools

You’re not limited to Node.js. You can create utility containers for:

  • Python: FROM python:3.10
  • Go: FROM golang:1.20
  • Terraform: FROM hashicorp/terraform:latest

Just change the base image and entrypoint accordingly.

Summary

Utility containers are a powerful and clean way to run development tasks without polluting your host machine. When combined with Docker Compose, they offer a repeatable, team-friendly development experience. They are ideal for bootstrapping projects, running tests, building apps, or using tools that aren’t worth installing globally.

Instead of installing language runtimes or package managers on every machine, create utility containers once and use them everywhere.