Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesThis lesson builds a small Python Flask app and packages it as a Docker image—the groundwork for a Kubernetes deployment, not a deployment to a cluster. You’ll create the app, fix errors in the original example, build and run the image locally, and see what still needs to happen before Kubernetes can run it.
What this tutorial builds—and what it doesn’t
The example app returns a greeting assembled from environment variables. Docker packages the app and its dependencies into an image, which you can run as a container. The tutorial stops there: it does not create Kubernetes manifests, a Deployment, or a Service, and it does not deploy the image to a cluster. The original Day 7 tutorial is best understood as containerization groundwork in a Kubernetes learning series.
As an Amazon Associate I earn from qualifying purchases.
Create the Flask application
Make a project directory and add these files. The greeting variable is spelled GREETING consistently; the source example’s GEETING typo would prevent the intended variable from being read.
app.py
requirements.txt
Dockerfile
In app.py, define a route that reads the configuration from the container’s environment:
#1 Best Overall
import os
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello():
greeting = os.getenv("GREETING", "Hello")
environment = os.getenv("APP_ENV", "local")
return f"{greeting} from {environment}!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5001, debug=True)
Binding to 0.0.0.0 makes the server reachable through the container’s network interface. The debug server is convenient for learning and local experiments, but it is not a production server configuration.
Use valid Python package requirement specifiers in requirements.txt. The double equals sign pins a version:
Flask==3.0.3
Write a Dockerfile
A Dockerfile gives Docker instructions for assembling an image. This example uses Alpine as its base image, but Alpine is not automatically the best choice for every Python application: compatibility with native dependencies and packaging needs matters as well as image size.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchFROM python:3.12-alpine
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
EXPOSE 5001
CMD ["python", "app.py"]
RUN executes while Docker builds the image; its result is captured in an image layer. Here, it installs the packages listed in requirements.txt. CMD supplies the default command when a container starts. In this example it uses exec form: a JSON array that invokes Python directly and does not implicitly run a shell. Shell-form commands do invoke a shell, which changes shell features such as variable expansion and can affect process and signal handling.
EXPOSE documents the container port the app expects to use; it does not publish that port on the host. Publishing is configured when starting the container.
Choosing a base image
Choose a base image that suits the application rather than choosing only by size. A smaller image can reduce what needs to be downloaded, while compatibility with dependencies is essential. Tags can move over time, so the same tag may not always identify identical image contents. Pinning an image digest improves repeatability, but means updates must be made deliberately. See Docker’s build best practices and its Dockerfile reference for image and instruction details.
Build and run the image locally
-
From the project directory, build the image and give it a local tag:
PerformanceWindows Errors? Fix Them Before They SpreadDriversOutdated Drivers Are Slowing You DownPerformancePC Slower Than It Used to Be?Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.docker build -t flask-greeting . -
Start a container and map host port 5001 to container port 5001. Set the greeting at runtime:
docker run --rm -p 5001:5001 -e GREETING="Hi" -e APP_ENV="development" flask-greeting -
Open
http://localhost:5001/in a browser. The response should reflect the environment values supplied todocker run.
The -p 5001:5001 option maps the host port to the container port. This is separate from the image’s EXPOSE instruction. If the host port is already in use, choose another host-side port, such as -p 8080:5001, and visit http://localhost:8080/.
What must change for Kubernetes
A local Docker container is not a Kubernetes workload. To continue the lesson, the cluster needs an image it can retrieve, and a Kubernetes resource must declare how to run it. A Deployment manages Pods for an application workload and reconciles the running state toward the declared desired state. See the Kubernetes Deployments documentation.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Quick Recap
- Make the image available. A cluster must be able to retrieve the image. A locally built image may not be visible to a remote cluster, so use an image location and workflow that the chosen cluster can access.
- Declare the workload. A follow-up manifest can define a Deployment whose container uses that image. Then apply it and check the rollout and Pod status using the appropriate cluster context.
- Configure environment values in the Pod. Kubernetes accepts individual variables through
envand groups throughenvFromin the Pod specification. These Pod settings override environment variables baked into the image. Ordinary configuration can be stored in a ConfigMap; credentials belong in a Secret. See Kubernetes’ environment-variable documentation. - Provide network access separately. Docker’s
-poption does not configure Kubernetes networking. If clients need to reach the app, create a Kubernetes Service or use another access method appropriate to the cluster.
Common copy-and-run mistakes
- Misspelling
GREETING: the app and the runtime option must use the same variable name. - Using single equals in requirements: use a valid specifier such as
Flask==3.0.3, notFlask=3.0.3. - Typing an inconsistent Dockerfile name: use
Dockerfileconsistently, or pass the exact custom filename with Docker’s-foption. The original misspellingalphine.Dockerfiledoes not match the Alpine image name. - Expecting
EXPOSEto open a host port: publish the port when running the container with-p. - Treating the debug server as production-ready: this is an instructional local example, not a production deployment recipe.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




