Docker Flags - Exercices
These exercises use five fundamental Dockerfile instructions: ARG
, ADD
, COPY
, EXPOSE
, ONBUILD
, and VOLUME
. Cumulatively, they will be used to build a Dockerfile step-by-step. The final Dockerfile will deploy a simple Python application.
Sample python server
python
import osfrom http.server import BaseHTTPRequestHandler, HTTPServerclass Handler(BaseHTTPRequestHandler):def do_GET(self):try:with open('/data/sampledata.txt', 'r') as file:content = file.read()self.send_response(200)self.send_header('Content-type', 'text/plain')self.end_headers()self.wfile.write(bytes(content, "utf8"))except Exception as e:self.send_response(500)self.send_header('Content-type', 'text/plain')self.end_headers()self.wfile.write(bytes(str(e), "utf8"))if __name__ == '__main__':port = int(os.getenv("PORT", 8080))HTTPServer(('', port), Handler).serve_forever()
Please complete the following exercises:
Exercise 1 - ARG and ADD Commands
In Exercise 1, youâll use the ARG
command to specify the Python version during the build process. Then, with the ADD
command, youâll download a specific file from a URL into your Docker image.
- Create a new file and name it Dockerfile.
- Add the line
ARG version
to start your Dockerfile. This line sets up a build-time variable which will allow you to specify the version of Python for your Docker image. - On a new line, add
FROM python:$version
. This line pulls the Python docker image of the version you specified, creating the possibility to customize the base image version at build time. - Then, add the line
ADD https://bnei.dev/assets/docker/flag/data.txt /data/sampledata.txt
. This command will download a text file from a URL and add it to the /data directory in your Docker image.
Now, you can use the --build-arg
flag when building the Docker image to specify the Python version. For example, use the command docker build --build-arg version=3.9 -t my-python-app .
to build your Docker image using Python 3.9 as the base image. This Docker image also contains sampledata.txt
file in the /data
directory, obtained from a URL.
Exercise 2 - COPY Command
In exercise 2, you will use the COPY
command to copy an application and its configurations from your local system into the Docker image.
- Create a new directory named
app
in the same location as your Dockerfile. - Put a simple python application
main.py
into theapp
directory. - Back in the Dockerfile, add the command
WORKDIR /src
to set the working directory for any subsequent commands. - Add the command
COPY ./app /src
. This command will copy the localapp
directory from your host to the/src
directory in your Docker image.
In these steps, you have added your local application code to the Docker image which will be executed whenever a Docker container is spun out from the image.
Exercise 3 - EXPOSE Command
For the third step, youâll use the EXPOSE
command to inform Docker that the container should listen on a specified network port at runtime.
- Append the instruction
EXPOSE 8080
to your Dockerfile. It tells Docker that your container will be listening on port 8080.
Exercise 4 - VOLUME Command
The VOLUME
command is used to allow your Docker container access to a directory in the host machine. In this exercise, you will create a directory for the appâs data to persist across different containers.
- Add
VOLUME /app-data
to your Dockerfile. This command designates /app-data as a directory on the host machine.
Exercise 5 - ONBUILD Command
Finally, using the ONBUILD
command, weâll set an instruction to trigger when another Docker image uses the current image as a base.
- Add the instruction
ONBUILD RUN echo 'New Container created from this Base image'
to the Dockerfile. Now, whenever a Docker image uses your image as a base, it will print this message as output during its build process.
Exercice 6 - CMD
Add a command with the CMD flag to start the app.
Conclusion
Through these exercises, you have built up a Dockerfile step by-step for a simple Python application, practicing essential commands like ARG
, ADD
, COPY
, EXPOSE
, VOLUME
, and ONBUILD
. The resulting Dockerfile can successfully build a Docker image for a Python application by using flexible, passable arguments and including crucial elements that a deployed Python application might need.
Solution
Exercise 1 - ARG and ADD Commands Solution
The solution to these commands in a Dockerfile would be as follows:
ARG version FROM python:$version ADD https://bnei.dev/assets/docker/flag/data.txt /data/sampledata.txt
With these lines:
- You can specify Python version using the
--build-arg version=3.9
flag while building the Docker image. - âsampledata.txtâ is added to â/dataâ directory from a URL.
Exercise 2 - COPY Command Solution
For the COPY command, the solution is:
WORKDIR /src COPY ./app /src
These lines set â/srcâ as the working directory and copies all files from your local âappâ directory into â/srcâ.
Exercise 3 - EXPOSE Command Solution
For the EXPOSE command, the solution is:
EXPOSE 8080
This line tells Docker that the container should listen on network port 8080 at runtime.
Exercise 4 - VOLUME Command Solution
For the VOLUME command, the solution is:
VOLUME /app-data
This line updates Dockerfile to create â/app-dataâ as a directory on the host machine.
Exercise 5 - ONBUILD Command Solution
For the ONBUILD command, the solution is:
ONBUILD RUN echo 'New Container created from this Base image'
This line updates Dockerfile to print a message whenever a new Docker image is built from your image as a base.
Exercise 6 - CMD
For the CMD command, the solution is:
CMD [ "python", "app.py" ]
Final Dockerfile
Pulling all these instructions together, our final Dockerfile looks like this:
ARG version FROM python:$version ADD https://bnei.dev/assets/docker/flag/data.txt /data/sampledata.txt WORKDIR /src COPY ./app /src EXPOSE 8080 VOLUME /app-data ONBUILD RUN echo 'New Container created from this Base image' CMD [ "python", "app.py" ]
In conclusion, with these solutions you have a modular Dockerfile which will build a Docker container for a Python application. You can specify the Python version, work directory, exposed port, and even an action based on triggers from subsequent Dockerfiles.