🎯 Objective
Create a custom Docker image using a Dockerfile that:
The final container should respond on:
http://localhost:6400🧠 Concept
A Dockerfile is a text file containing instructions Docker uses to build an image.
The flow is:
Dockerfile
↓
docker build
↓
Docker Image
↓
docker run
↓
ContainerInstead of manually changing a running container, a Dockerfile makes the setup:
🔍 Step 1: Check Running Containers
Check currently running containers:
docker psThis helps confirm the Docker environment before starting.
📂 Step 2: Go to the Docker Directory
Navigate to:
cd /opt/docker/Check the directory contents:
ls -lah📝 Step 3: Create the Dockerfile
Create the Dockerfile:
sudo touch DockerfileEdit it:
sudo vi DockerfileAdd:
FROM ubuntu:24.04
RUN apt-get update && \
apt-get install -y apache2 && \
sed -i 's/Listen 80/Listen 6400/' /etc/apache2/ports.conf && \
rm -rf /var/lib/apt/lists/*
EXPOSE 6400
CMD ["apache2ctl", "-D", "FOREGROUND"]🧩 Dockerfile Breakdown
FROM
FROM ubuntu:24.04Defines the base image.
In this case:
Base Image → Ubuntu 24.04Every instruction that follows builds on top of this image.
RUN
RUN apt-get update && \
apt-get install -y apache2 && \
sed -i 's/Listen 80/Listen 6400/' /etc/apache2/ports.conf && \
rm -rf /var/lib/apt/lists/*This performs several operations during the image build.
First:
apt-get updateupdates the package repository metadata.
Then:
apt-get install -y apache2installs Apache2.
Then:
sed -i 's/Listen 80/Listen 6400/' /etc/apache2/ports.confchanges Apache's listening port:
80
↓
6400Finally:
rm -rf /var/lib/apt/lists/*removes cached package metadata to reduce the final image size.
🌐 Step 4: Expose Port 6400
The Dockerfile contains:
EXPOSE 6400This documents that the containerized application listens on port:
6400Important:
> EXPOSE does not publish the port to the Docker host by itself.
Port publishing happens with:
-pwhen the container is started.
▶️ Step 5: Run Apache in Foreground
The Dockerfile ends with:
CMD ["apache2ctl", "-D", "FOREGROUND"]Docker containers normally keep running only while their main process is active.
Running Apache in foreground mode ensures:
Apache
↓
Main Container Process
↓
Container remains runningIf Apache ran only as a background daemon, the container could exit after the main process finished.
🔍 Step 6: Verify the Dockerfile
Check the contents:
cat /opt/docker/DockerfileExpected:
FROM ubuntu:24.04
RUN apt-get update && \
apt-get install -y apache2 && \
sed -i 's/Listen 80/Listen 6400/' /etc/apache2/ports.conf && \
rm -rf /var/lib/apt/lists/*
EXPOSE 6400
CMD ["apache2ctl", "-D", "FOREGROUND"]🏗️ Step 7: Build the Docker Image
Make sure you are inside:
cd /opt/dockerBuild the image:
sudo docker build -t custom-apache .Command Breakdown
docker buildBuilds an image from a Dockerfile.
-t custom-apacheTags the new image as:
custom-apacheThe final:
.means:
> Use the current directory as the build context.
Docker looks for:
./Dockerfileby default.
🔍 Step 8: Verify the Image
Check the available images:
sudo docker image lsYou should see:
REPOSITORY TAG IMAGE ID CREATED SIZE
custom-apache latest ... ... ...Because no explicit tag was provided, Docker uses:
latestSo the image is effectively:
custom-apache:latest🚀 Step 9: Run the Container
Create a container from the image:
sudo docker run -d \
--name apache-test \
-p 6400:6400 \
custom-apacheCommand Breakdown
-dRuns the container in detached mode.
--name apache-testNames the container:
apache-test-p 6400:6400Maps:
Host Port 6400
↓
Container Port 6400Finally:
custom-apacheis the image used to create the container.
🌐 Port Mapping
The port flow is:
Browser / curl
│
│ localhost:6400
▼
Docker Host
Port 6400
│
│ -p 6400:6400
▼
Container
Port 6400
│
▼
ApacheThis works because:
Listen 6400inside Apache matches:
-p 6400:6400in Docker.
🔍 Step 10: Verify the Container
Check running containers:
sudo docker psYou should see apache-test.
Example:
CONTAINER ID IMAGE PORTS NAMES
abc123 custom-apache 0.0.0.0:6400->6400/tcp apache-testThe important part is:
0.0.0.0:6400->6400/tcpThis confirms the host-to-container port mapping.
🧪 Step 11: Test Apache
Test the container:
curl http://localhost:6400If everything is working correctly, Apache should return its default HTML page.
The request flow is:
curl localhost:6400
↓
Host Port 6400
↓
Container Port 6400
↓
Apache
↓
HTML Response ✅🗑️ Step 12: Remove the Test Container
After verification, remove the container:
sudo docker rm -f apache-testf
Forces Docker to:
Stop container
↓
Remove containerin one command.
Without -f, you would normally do:
sudo docker stop apache-test
sudo docker rm apache-test🧠 Dockerfile vs Manual Container Changes
Using manual commands:
Run Ubuntu Container
↓
Install Apache
↓
Change Port
↓
Configure Startuprequires repeating those steps every time.
With a Dockerfile:
Dockerfile
↓
docker build
↓
Reusable Image
↓
docker runThe infrastructure becomes repeatable.
⚠️ Important Notes
⚙️ Complete Workflow
Check Docker:
docker psNavigate:
cd /opt/docker/Inspect files:
ls -lahCreate Dockerfile:
sudo touch Dockerfile
sudo vi DockerfileDockerfile:
FROM ubuntu:24.04
RUN apt-get update && \
apt-get install -y apache2 && \
sed -i 's/Listen 80/Listen 6400/' /etc/apache2/ports.conf && \
rm -rf /var/lib/apt/lists/*
EXPOSE 6400
CMD ["apache2ctl", "-D", "FOREGROUND"]Verify:
cat /opt/docker/DockerfileBuild:
cd /opt/docker
sudo docker build -t custom-apache .Run:
sudo docker run -d \
--name apache-test \
-p 6400:6400 \
custom-apacheVerify:
sudo docker psTest:
curl http://localhost:6400Clean up:
sudo docker rm -f apache-test🧪 Validation Checklist
📌 Summary
The Dockerfile is:
FROM ubuntu:24.04
RUN apt-get update && \
apt-get install -y apache2 && \
sed -i 's/Listen 80/Listen 6400/' /etc/apache2/ports.conf && \
rm -rf /var/lib/apt/lists/*
EXPOSE 6400
CMD ["apache2ctl", "-D", "FOREGROUND"]Build it:
sudo docker build -t custom-apache .Run it:
sudo docker run -d \
--name apache-test \
-p 6400:6400 \
custom-apacheTest:
curl http://localhost:6400The complete flow is:
Dockerfile
│
│ docker build
▼
custom-apache Image
│
│ docker run
▼
apache-test Container
│
│ Apache listens on 6400
▼
Container Port 6400
│
│ -p 6400:6400
▼
Host Port 6400
│
▼
curl localhost:6400 ✅The key takeaway is:
> A Dockerfile defines a repeatable image build process. In this task, Ubuntu 24.04 is used to build a custom Apache image that listens on port 6400 and runs Apache as the container's foreground process.