Docker Hands-On Part 03
Tags: aws, docker, tutorial
Published: 2024-02-09 09:17:31

## 03. Handcrafting a Container Image

**Introduction**

This approach to creating a container image, emphasizes the practicality of incorporating data directly into the image rather than manually mounting it each time a container is started. This method is particularly useful for web deployment, where efficiency and customization are key. The process outlined involves starting with a pre-built HTTPD image and modifying it to suit specific needs. 

**Step-by-Step Guide to Creating a Handcrafted Container Image**

**01. Selecting a Base Image:** The journey begins with selecting HTTPD as the base image, a popular choice for serving web content.

**02. Adding Tools and Data:** To customize the container, tools are added to fetch website data from a repository, such as GitHub. This step ensures that the necessary content is directly embedded within the container.

**03. Creating the Initial Image:** After customizing the template container with the website's data, an image is created from this state, labeled Widget Factory v1.

**04. Optimizing the Image:** Inspection of the initial image reveals it to be larger than necessary due to residual installation artifacts. By removing these, a cleaner and more efficient image, Web App v2, is produced.

**05. Deployment and Testing:** Multiple containers are spawned from the optimized v2 image to test and view the final product in action.

**The Process Visualized**

The creation process visualizes the transition from a generic HTTPD latest version image to a specialized Widget Factory image. The initial modifications result in the v1 image, which is further refined to create the optimized v2 image. This final version is then used to run multiple containers, showcasing the website deployment.

Step 01: Create another container called "webtemplate" using httpd. 

```
$ docker run --name webtemplate -d httpd:latest

$ docker ps -a
CONTAINER ID   IMAGE          COMMAND              CREATED         STATUS         PORTS                                   NAMES
4dadb7c6ca70   httpd:latest   "httpd-foreground"   5 seconds ago   Up 4 seconds   80/tcp                                  webtemplate

```

Step 02: Get an internal terminal of the webtemplate container. 

```
$ docker exec -it webtemplate bash
```

Step 03: Update the container and install git. 

```
# apt update && apt install -y git
```

Step 04: Clone the repo from the GitHub. 

Repo Link: https://github.com/RandiakM/content-widget-factory-inc.git

```
# git clone https://github.com/RandiakM/content-widget-factory-inc.git /tmp/widget-factory-inc

# ls -l /tmp/widget-factory-inc
```

Step 05: Now we need to set up the htdocs folder. Remove the default apache page and copy our web pages. 

```
root@4dadb7c6ca70:/usr/local/apache2# pwd
/usr/local/apache2

# rm -rf htdocs/index.html

# cp -r /tmp/widget-factory-inc/web/* htdocs

# ls -l htdocs 
```

Step 06: Create an image from the container, we need the container ID. 

```
$ docker ps -a
CONTAINER ID   IMAGE          COMMAND              CREATED             STATUS             PORTS                                   NAMES
4dadb7c6ca70   httpd:latest   "httpd-foreground"   About an hour ago   Up About an hour   80/tcp                                  webtemplate

$ docker commit 4dadb7c6ca70 example/widgetfactory:v1

$ docker images
[ec2-user@ip-172-16-1-10 ~]$ docker images
REPOSITORY              TAG       IMAGE ID       CREATED          SIZE
example/widgetfactory   v1        1676623db0fc   11 seconds ago   277MB
httpd                   latest    59bcd61b45fd   3 weeks ago      167MB
hello-world             latest    d2c94e258dcb   9 months ago     13.3kB

```

You can see our `example/widgetfactory` size is large. All this coming from the extra build tools. We need to clean this up. 

Step 07: Go to the inside of the container, and need to remove git, web app codes, and remove the cache. 

```
$ docker exec -it webtemplate bash

# rm -rf /tmp/widget-factory-inc

# apt remove git -y && apt autoremove -y && apt clean

# exit
```

Step 08: Now we need to run `docker commit` again. 

```
$ docker commit 4dadb7c6ca70 example/widgetfactory:v2

$ docker images
REPOSITORY              TAG       IMAGE ID       CREATED         SIZE
example/widgetfactory   v2        01e2bd60f515   7 seconds ago   187MB
example/widgetfactory   v1        1676623db0fc   7 minutes ago   277MB
httpd                   latest    59bcd61b45fd   3 weeks ago     167MB

```

Step 09: Remove v1 image and run the v2. Stop the webtemplate. 

```
$ docker rmi example/widgetfactory:v1

$ docker run -d --name web1 -p 8081:80  example/widgetfactory:v2

$ docker ps -a
CONTAINER ID   IMAGE                      COMMAND              CREATED             STATUS             PORTS                                   NAMES
adaf110c7088   example/widgetfactory:v2   "httpd-foreground"   4 seconds ago       Up 3 seconds       0.0.0.0:8081->80/tcp, :::8081->80/tcp   web1
4dadb7c6ca70   httpd:latest               "httpd-foreground"   About an hour ago   Up About an hour   80/tcp                                  webtemplate
53aace921e70   httpd:latest               "httpd-foreground"   4 hours ago         Up 4 hours         0.0.0.0:8080->80/tcp, :::8080->80/tcp   httpd


$ docker stop webtemplate

```

Step 10: Now in your browser navigate to the public_ip:8081