Skip to content

Building a Web Server Docker File

We’ve learned how to use existing images. Now let’s build our own custom image using a Dockerfile. We’ll create a simple web server image based on Ubuntu with Apache installed.

Step 1: Create a file named Dockerfile (case-sensitive, no extension) in a new, empty directory. Add the following content using a text editor:

# Use an official Ubuntu base image (specify a version for reproducibility)
FROM ubuntu:22.04
# Set labels (optional, good practice)
LABEL maintainer="Your Name <your.email@example.com>"
LABEL description="Simple Apache web server based on Ubuntu"
# Update package lists, install Apache, and clean up in one layer
# Using noninteractive mode to avoid prompts during build
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y apache2 apache2-utils && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
# Expose port 80 (standard HTTP port Apache listens on)
EXPOSE 80
# Command to run when the container starts
# Runs Apache in the foreground, which is necessary for Docker
CMD ["apache2ctl", "-D", "FOREGROUND"]

Key points about this Dockerfile:

  • FROM ubuntu:22.04: Specifies the base image. Using a specific tag like 22.04 is better than latest for consistent builds.
  • LABEL: Provides metadata about the image (replaces the deprecated MAINTAINER).
  • RUN: Executes commands during the image build process. We chain commands with && \ to minimize image layers and clean up apt cache (apt-get clean, rm -rf ...) to reduce image size.
  • DEBIAN_FRONTEND=noninteractive: Prevents interactive prompts during package installation.
  • EXPOSE 80: Documents that the container listens on port 80. It doesn’t actually publish the port; that’s done with docker run -p.
  • CMD: Specifies the default command to run when a container starts from this image. apache2ctl -D FOREGROUND keeps the container running by running Apache in the foreground.

Step 2: Open your terminal, navigate to the directory containing the Dockerfile, and run the docker build command:

# Build the image and tag it as 'my-apache-server:1.0'
docker build -t my-apache-server:1.0 .
  • -t my-apache-server:1.0: Tags the image with a name (my-apache-server) and a version tag (1.0). This makes it easy to reference.
  • .: Specifies the build context (the current directory), where Docker looks for the Dockerfile and any files needed by COPY or ADD instructions (not used here).

Docker will execute the instructions in the Dockerfile step-by-step, downloading the base image if necessary, running commands, and creating layers. You’ll see output for each step. Upon successful completion, you’ll have a new image named my-apache-server:1.0.

You can verify the image exists using:

docker images

Step 3: Now, run a container from your newly built image:

# Run the container in detached mode (-d) and map host port 8080 to container port 80 (-p)
docker run -d -p 8080:80 --name my-running-webserver my-apache-server:1.0
  • -d: Runs the container in detached mode (in the background).
  • -p 8080:80: Maps port 8080 on your host machine to port 80 inside the container (where Apache is listening).
  • --name my-running-webserver: Assigns a name to the container for easier management.
  • my-apache-server:1.0: The image to run.

To test it, open a web browser and navigate to http://localhost:8080 (or http://<your-docker-host-ip>:8080 if Docker isn’t running locally). You should see the default Apache Ubuntu page, confirming your custom web server container is running!