Containerize Your First Web App
Package a Python Flask app into a Docker container and run it live.
Introduction
30 Second Summary
Every time you install an app on a new computer, you deal with missing files, wrong versions, and broken settings. Docker solves this by packaging everything an app needs into a single portable box called a container.
In this project, you will build a simple web app using Python and Flask, then package it into a Docker container that runs the same way on any machine. This is the exact workflow that DevOps teams use every day to ship software.
What You'll Build
A "DevOps Status Board" web app that displays your name, the current date, and a status message, served entirely from inside a Docker container.
By the end of this project, you'll have:
- A Python Flask web app that renders a live status page in the browser.
- A Dockerfile you wrote yourself that packages the app into a portable Docker image.
- Hands-on experience with essential Docker commands like docker build, docker run, and docker logs that DevOps engineers use daily.
- Secret Mission: add a health check endpoint and use Docker's HEALTHCHECK instruction to monitor your container automatically.
Are there any prerequisites?
All you need is a free GitHub account. Everything in this project runs inside GitHub Codespaces, so you do not need to install Docker or Python on your own computer.
Open Your Codespace and Meet the Terminal
Before you can containerize anything, you need a development environment with Docker installed. Setting that up on a personal laptop can be time-consuming and error-prone.
GitHub Codespaces gives you a full Linux environment in your browser with Docker and Python pre-installed. In this step, you'll create a Codespace and verify that all your tools are ready to go.
In this step, get ready to:
- Create a GitHub repository and open a Codespace.
- Verify Docker and Python are pre-installed.
- Practice basic terminal commands.
Create a new GitHub repository and open a Codespace
You need a GitHub repository to store your project files. A Codespace connected to that repository gives you a cloud editor with everything pre-installed.
- Open your browser and go to github.com.
- In the upper-right corner of any page, click the + icon.
- Select New repository from the dropdown menu.
- Type docker-first-app in the Repository name field.
- Make sure Public is selected for repository visibility.
- Toggle Add a README file to On.
- Click Create repository.
Your new repository page loads with a single README.md file.
- Click the green Code button near the top of the repository page.
- Click the Codespaces tab in the dropdown that appears.
- Click Create codespace on main.
What just happened?
A new browser tab opens with a VS Code editor. This is your Codespace. GitHub allocated a cloud virtual machine, cloned your repository into it, and connected you to it automatically.
The editor has a file explorer on the left and a terminal panel at the bottom. You will use both throughout this project.
Don't see the terminal?
If the terminal panel is not visible at the bottom of your Codespace, press Ctrl+` (backtick key, usually above Tab) to toggle it open.
Help me open the terminal in my Codespace.
Verify Docker and Python are installed
Your Codespace comes with Docker and Python pre-installed. Let's confirm they are both available before building anything.
- Check your Docker version by running this command in the terminal:
docker --version
You should see output like Docker version 24.0.x. The exact patch number may differ.
- Check your Python version by running:
python3 --version
You should see output like Python 3.10.x. This confirms Python is ready.
Why check versions first?
Running version checks is a common first step in any DevOps workflow. It confirms that the tools you need are installed and accessible on your system before you start depending on them.
✔️ I see version numbers for both
Both tools are ready. You are all set to continue.
ⓧ I see 'command not found'
This usually means the Codespace did not finish setting up. Try waiting 30 seconds and running the commands again. If the issue persists, close the Codespace tab and reopen it from your repository page by clicking Code then Codespaces.
Help me troubleshoot missing Docker or Python in my Codespace.
Practice a few terminal commands
You will use the terminal for every Docker command in this project. Let's practice a few basic commands so you know how to navigate.
- See your current working directory by running:
pwd
You should see /workspaces/docker-first-app. This is your project folder inside the Codespace.
- List the files in your current folder by running:
ls
You should see README.md listed. This is the file GitHub created when you initialized the repository.
- Create a test folder by running:
mkdir test-folder
- Confirm the folder was created by running:
ls
You should see test-folder alongside README.md in the output.
- Remove the test folder by running:
rmdir test-folder
- Confirm it was removed by running:
ls
You should see only README.md again. The test folder is gone.
What do these commands do?
- pwd stands for "print working directory." It shows which folder you are currently in.
- ls lists all files and folders in your current directory.
- mkdir creates a new folder.
- rmdir removes an empty folder.
Your environment is ready and you know how to use the terminal. Next up, you'll create the Python web app that you will later containerize with Docker.
Create Your Python Web App
Your Codespace is set up and you've confirmed that Docker and Python are ready to go. Now it's time to build the app you're going to containerize.
Before Docker can package anything, it needs an actual application to work with. You'll use Flask, a lightweight Python web framework, to create a simple DevOps Status Board that displays your name and a live status message.
In this step, get ready to:
- Create a Flask web app that displays a status board page.
- List the app's dependencies in a requirements.txt file.
- Test the app locally to confirm it works before containerizing it.
Create your Flask application
- Create a new file called app.py by running this command in your terminal:
touch app.py
- Click on app.py in the Explorer sidebar on the left to open it in the editor.
- Copy the following code into app.py:
from flask import Flask
import datetime
# Create the Flask application
app = Flask(__name__)
# Define the home page route
@app.route("/")
def home():
# Get today's date in a readable format
current_date = datetime.datetime.now().strftime("%B %d, %Y")
# Return an HTML page with the status board
return f"""
<html>
<head><title>DevOps Status Board</title></head>
<body style="font-family: Arial, sans-serif; text-align: center; padding: 50px; background-color: #1a1a2e; color: #e0e0e0;">
<h1 style="color: #00d4ff;">DevOps Status Board</h1>
<p style="font-size: 24px;">Engineer: Your Name Here</p>
<p style="font-size: 20px;">Date: {current_date}</p>
<p style="font-size: 28px; color: #00ff88;">Status: All Systems Operational</p>
<p style="font-size: 16px; color: #888;">Running inside a Docker container</p>
</body>
</html>
"""
# Run the app when this file is executed directly
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
What does this code do?
- Flask(__name__) creates your web application instance.
- @app.route("/") tells Flask what to display when someone visits the home page.
- The home() function returns a styled HTML page showing your name, today's date, and a status message.
- app.run(host="0.0.0.0", port=5000) starts the web server. Using 0.0.0.0 makes the app accessible from outside its environment, which is essential when running inside a container later.
- Save app.py by pressing Cmd+S (macOS) or Ctrl+S (Windows).
You won't see the app running yet. You'll test it after creating the requirements file in the next substep.
See red underlines or errors in the editor?
If you see a warning about Flask not being found, that's expected. You haven't installed Flask yet. The editor is just flagging the missing package.
If you see a syntax error, double-check that the triple quotes (""") at the start and end of the HTML string match exactly. The f before the opening triple quotes is also required.
Why is my app.py showing errors in the editor?
✔️ Awesome, I've got everything!
Great. Double-check you've saved app.py before moving on.
ⓧ I'd like to double check the full code
Here's the complete app.py file. Compare it with yours and make sure every line matches.
from flask import Flask
import datetime
app = Flask(__name__)
@app.route("/")
def home():
current_date = datetime.datetime.now().strftime("%B %d, %Y")
return f"""
<html>
<head><title>DevOps Status Board</title></head>
<body style="font-family: Arial, sans-serif; text-align: center; padding: 50px; background-color: #1a1a2e; color: #e0e0e0;">
<h1 style="color: #00d4ff;">DevOps Status Board</h1>
<p style="font-size: 24px;">Engineer: Your Name Here</p>
<p style="font-size: 20px;">Date: {current_date}</p>
<p style="font-size: 28px; color: #00ff88;">Status: All Systems Operational</p>
<p style="font-size: 16px; color: #888;">Running inside a Docker container</p>
</body>
</html>
"""
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
Create the requirements file
Real Python projects track their dependencies in a file called requirements.txt. This tells anyone (and any tool, including Docker) exactly which packages the app needs to run.
- Create a new file called requirements.txt by running this command:
touch requirements.txt
- Click on requirements.txt in the Explorer sidebar to open it.
- Add the following line to requirements.txt:
Flask==3.1.3
Why pin the version number?
Flask==3.1.3 pins Flask to an exact version. Without the version pin, Python would install whatever the latest version is at the time.
Pinning versions is a best practice because it makes your project reproducible. Anyone who installs from this file gets the exact same version you tested with.
- Save requirements.txt.
- Confirm both files exist by running:
ls
You should see app.py and requirements.txt in the output.
Don't see both files?
Make sure you ran the touch commands from the /workspaces/docker-first-app directory. Run pwd to check your current location.
Why are my files missing from the directory listing?
Test the app without Docker first
Before bringing Docker into the picture, you should confirm the app works on its own. This way, if something breaks later during containerization, you'll know the problem is with Docker and not your code.
- Install Flask by running this command:
pip install -r requirements.txt
You should see output ending with Successfully installed followed by Flask and its dependencies.
Seeing a pip error?
If you see a permissions error, try running pip install --user -r requirements.txt instead. If you see No such file or directory, make sure you're in the /workspaces/docker-first-app folder where requirements.txt lives.
Why is pip install failing in my Codespace?
- Start your app by running:
python3 app.py
You should see output like Running on http://0.0.0.0:5000 in the terminal.
How does Codespaces show your app?
When Flask prints a localhost URL, Codespaces automatically detects the port and shows a popup offering to open it in your browser. You do not type localhost:5000 in your local browser.
Instead, Codespaces forwards the port to a special URL that looks like https://CODESPACENAME-5000.app.github.dev. You can also find this URL in the Ports tab at the bottom of your Codespace.
- Click Open in Browser in the popup that appears.
You should see your DevOps Status Board in a new browser tab. It displays a dark page with a blue title, your name, today's date, and a green All Systems Operational status message.
- Go back to your Codespace tab.
- Press Ctrl+C in the terminal to stop the app.
Don't see the popup or your app?
If the popup disappeared, click the Ports tab at the bottom of your Codespace. Find port 5000 in the list and click the globe icon to open it in your browser.
If you see an error like ModuleNotFoundError: No module named 'flask', make sure you ran pip install -r requirements.txt successfully before starting the app.
My Flask app won't start or the browser shows an error. Help me debug.
Your app works locally. Next up, you'll write a Dockerfile that packages this app into a portable Docker image.
Write Your First Dockerfile
Your Flask app is tested and working. You ran it locally and confirmed it shows your DevOps Status Board in the browser.
Now it's time to package this app so it can run the same way on any machine. You'll do this by writing a Dockerfile, a recipe that tells Docker exactly how to build your app into a portable image.
In this step, get ready to:
- Write a Dockerfile that packages your Flask app.
- Create a .dockerignore file to keep your image clean.
- Understand the purpose of each Dockerfile instruction.
Create the Dockerfile
A Dockerfile is a text file with a specific set of instructions. Docker reads it top to bottom, executing each instruction to build your app's image layer by layer.
- Create a new file called Dockerfile by running this command in your terminal (use a capital D and no file extension):
touch Dockerfile
- Confirm the file was created by running:
ls
You should see Dockerfile listed alongside app.py and requirements.txt.
- Click on Dockerfile in the file explorer on the left side to open it in the editor.
- Copy the following code into your Dockerfile:
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
What does this code do?
- FROM python:3.10-slim starts from a lightweight Python image with Python 3.10 pre-installed.
- WORKDIR /app creates a folder called /app inside the container and makes it the active directory for all following instructions.
- requirements.txt is copied and installed in a separate step before the rest of the code. This lets Docker reuse the cached dependency layer when only your app code changes.
- COPY . . copies all remaining project files into the container.
- CMD ["python", "app.py"] tells Docker what command to run when a container starts from this image.
- Save Dockerfile by pressing Cmd+S (macOS) or Ctrl+S (Windows).
You won't see a visual change yet. In the next step, you'll build this Dockerfile into a real Docker image.
Don't see Dockerfile in the file explorer?
- Make sure you used a capital D. Docker looks for a file named exactly Dockerfile, not dockerfile or Dockerfile.txt.
- Check that you're in the right folder by running pwd. It should show /workspaces/docker-first-app.
- Help me troubleshoot my Dockerfile not appearing in the Codespaces file explorer.
✔️ Awesome, I've got everything!
You're all set. Make sure you've saved Dockerfile before moving on.
ⓧ I'd like to double check the full code
Here's the complete Dockerfile. Compare it with yours line by line.
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]
Create a .dockerignore file
Just like .gitignore keeps unwanted files out of your Git repository, .dockerignore keeps unwanted files out of your Docker image. This makes your image smaller and prevents unnecessary files from being copied in.
- Create the .dockerignore file by running this command:
touch .dockerignore
- Click on .dockerignore in the file explorer to open it.
- Copy the following entries into the file:
__pycache__/
*.pyc
.git/
.gitignore
What does this file do?
- __pycache__/ and *.pyc exclude Python's compiled bytecode files. These are auto-generated and not needed inside the container.
- .git/ and .gitignore exclude version control files. Your container only needs the app code, not its Git history.
- Save .dockerignore by pressing Cmd+S (macOS) or Ctrl+S (Windows).
- Confirm both new files exist by running:
ls -a
You should see .dockerignore, Dockerfile, app.py, and requirements.txt in the output.
Don't see .dockerignore in the list?
Files starting with a dot are hidden by default. The -a flag in ls -a shows hidden files. If you ran ls without the flag, you won't see it.
Help me find my .dockerignore file in GitHub Codespaces.
Understand each Dockerfile instruction
Your Dockerfile has seven instructions. Docker reads them top to bottom, and each instruction creates a new layer in your image.
What does each instruction do?
- FROM picks the starting image for your container. Think of it as choosing a base operating system with Python already installed.
- WORKDIR creates and switches to a folder inside the container. All following commands run from this folder.
- COPY moves files from your project into the container. The first argument is the source file, and the second is the destination inside the container.
- RUN executes a command during the build process. The result becomes a new layer in your image.
- EXPOSE documents which port your app listens on. It does not actually publish the port to the outside world.
- CMD defines the command that runs when a container starts from this image. There can only be one CMD per Dockerfile.
Why copy requirements.txt separately?
Docker caches each layer it builds. If a layer's input hasn't changed, Docker skips rebuilding it and reuses the cached version.
By copying requirements.txt and installing dependencies in a separate layer from your app code, Docker only reinstalls dependencies when requirements.txt changes. When you edit app.py, Docker reuses the cached dependency layer and only rebuilds the layers after it. This makes rebuilds much faster.
Your Dockerfile is ready to go. Next up, you'll build this recipe into a real Docker image and run your app inside a container.
Build and Run Your Docker Container
You now have all the ingredients: a Flask web app, a requirements.txt file listing your dependencies, and a Dockerfile that tells Docker how to package everything together.
Right now, your Dockerfile is just a recipe sitting on disk. In this step, you will execute that recipe to build a Docker image, run a live container from it, and peek inside to see your app running.
In this step, get ready to:
- Build a Docker image from your Dockerfile.
- Run your app inside a Docker container with port mapping.
- Inspect and debug a running container.
Build the Docker image
A Docker image is a snapshot of everything your app needs to run. Building an image reads the instructions in your Dockerfile and executes them step by step, producing a portable package you can run on any machine.
- Build your Docker image by running this command in the terminal:
docker build -t my-first-app .
What does this command do?
- docker build tells Docker to read your Dockerfile and create an image from it.
- -t my-first-app gives your image a name (called a "tag") so you can refer to it easily later.
- . (the dot at the end) tells Docker to look in your current folder for the Dockerfile and any files it needs to copy.
- Watch the terminal output as Docker executes each instruction from your Dockerfile layer by layer.
- The first build may take a minute or two as Docker downloads the python:3.10-slim base image.
You should see numbered steps like Step 1/7 : FROM python:3.10-slim, ending with Successfully tagged my-first-app:latest.
Seeing an error during the build?
- Make sure you are in the /workspaces/docker-first-app folder. Run pwd to check your current location.
- Check that your file is named exactly Dockerfile with a capital D and no file extension.
- Don't forget the . at the end of the command. It tells Docker where to find your files.
Help me debug my Docker build error.
Run your app in a container
Your image is built, but it is not doing anything yet. An image is a blueprint. To actually start your app, you need to create a running container from that image.
- Start your app inside a Docker container by running this command:
docker run -d -p 5000:5000 --name my-app my-first-app
What do these flags mean?
- -d runs the container in "detached" mode, meaning it runs in the background so you can keep using the terminal.
- -p 5000:5000 maps port 5000 inside the container to port 5000 outside of it. Without this, the app runs but nothing outside the container can reach it.
- --name my-app gives your container a friendly name so you can reference it easily instead of using a long container ID.
- my-first-app at the end is the name of the image you just built.
- Codespaces detects the port and shows a notification in the bottom-right corner of the screen.
- Click Open in Browser on the notification to see your app.
You should see the DevOps Status Board page with your name, today's date, and the status message. This page is being served entirely from inside your Docker container.
Missed the notification?
Click the Ports tab at the bottom of VS Code (next to the Terminal tab). Find port 5000 in the list and click the globe icon to open it in your browser.
Container won't start?
- If you see name is already in use, a container named my-app already exists. Run docker rm -f my-app to remove it, then try the docker run command again.
- If you see port is already allocated, something else is using port 5000. Make sure you stopped the Flask app from the previous step by pressing Ctrl+C in the terminal where it was running.
Help me fix my docker run error.
Inspect your running container
Your app is running inside a container, but how do you check on it? Docker gives you several commands for inspecting and debugging containers. These are the same tools DevOps engineers use to troubleshoot production issues.
- See all running containers by running this command:
docker ps
You should see a table with your my-app container listed. The table shows its container ID, the image it was built from, its status, and the port mapping.
- View your app's log output by running:
docker logs my-app
You should see Flask's startup message, including Running on http://0.0.0.0:5000. This is the same output you saw when you ran the app directly in a previous step.
What do these commands tell you?
docker ps is your dashboard for running containers. It shows you what is running, how long it has been up, and which ports are mapped.
docker logs shows everything your app has printed to the terminal inside the container. This is your first stop when something goes wrong in a containerized app.
You can also go inside a running container and look around, just like opening a terminal on a remote server.
- Open an interactive shell inside your container by running:
docker exec -it my-app /bin/bash
Your terminal prompt changes to something like root@abc123:/app#. You are now inside the container, not in Codespaces.
- Run ls to see the files inside the container. You should see app.py, requirements.txt, and the other files that Docker copied in.
- Type exit and press Enter to leave the container shell and return to your Codespaces terminal.
Why is docker exec useful?
docker exec lets you open a live terminal session inside a running container. This is how DevOps engineers debug issues in production. You can check files, inspect environment variables, and test network connections without stopping the app.
Seeing 'No such container'?
- Run docker ps to check if your container is still running. If it is not listed, run docker start my-app to bring it back up.
- If docker start also fails, the container may have been removed. Run the docker run command from the previous substep again to create a fresh container.
Help me fix my Docker container issue.
Your app is running inside a Docker container, and you have explored its insides. Next up, you will learn to manage the full container lifecycle by stopping, restarting, rebuilding, and cleaning up containers.
Manage Your Container Lifecycle
Your container is up and running, and you've explored its internals with docker exec. Now it's time to learn how to manage containers over time.
In real DevOps work, you don't just run a container once and call it done. You constantly stop, update, and redeploy containers as your code changes. This step walks you through that essential workflow.
In this step, get ready to:
- Stop and restart a running Docker container.
- Edit your app and rebuild the Docker image.
- Practice the standard stop, remove, rebuild, run development cycle.
Stop and restart your container
Containers are not permanent. You can stop them, restart them, and remove them whenever you need to.
- Stop your running container by running this command:
docker stop my-app
- Confirm the container stopped by running:
docker ps
You should see an empty table with no containers listed.
- Now check all containers, including stopped ones, by running:
docker ps -a
You should see my-app listed with a status of Exited.
What is the difference between docker ps and docker ps -a?
docker ps shows only running containers. docker ps -a shows all containers, including stopped ones.
Docker keeps stopped containers on disk until you explicitly remove them. This is useful when you need to restart a container or inspect its logs after a crash.
- Bring the container back by running:
docker start my-app
- Refresh your browser tab. You should see the DevOps Status Board page loading again.
App not loading after restart?
- Make sure you ran docker start my-app, not docker run. docker start restarts an existing stopped container, while docker run creates a brand new one.
- Check the Ports tab at the bottom of your Codespaces window. Port 5000 should be listed and forwarded.
- My Docker container restarted but the app isn't loading in the browser
Make a change and rebuild your image
When you change your application code, the running container does not automatically update. You need to rebuild the image and start a fresh container from it.
- In app.py, find this line inside the HTML template:
<p style="font-size: 28px; color: #00ff88;">Status: All Systems Operational</p>
- Change All Systems Operational to any status message you like. For example:
<p style="font-size: 28px; color: #00ff88;">Status: Deploying New Features</p>
- Save app.py.
- Rebuild your Docker image with the updated code by running:
docker build -t my-first-app .
Watch the build output closely. You should see some steps marked as CACHED.
What is layer caching?
Docker remembers each layer from your previous build. If a layer's inputs haven't changed, Docker skips rebuilding it entirely.
You only changed app.py, not requirements.txt. So Docker reuses the cached pip install layer and only re-runs from COPY . . onward. This is why the Dockerfile copies requirements.txt separately before copying the rest of the code. The bigger the install step, the more time caching saves.
All steps rebuilding from scratch?
- If no steps show CACHED, you may have edited requirements.txt or the Dockerfile by accident. Check that both files are unchanged from the previous step.
- My Docker build is not using cached layers even though I only changed app.py
Clean up and run the updated container
Your old container is still running the previous version of your app. To see your change, you need to replace it with a new container built from the updated image.
- Stop the running container by running:
docker stop my-app
- Remove the stopped container by running:
docker rm my-app
Why stop AND remove?
docker stop shuts down the container but keeps it on disk. docker rm deletes it completely. You need to remove the old container before running a new one with the same name.
- Start a fresh container from your updated image by running:
docker run -d -p 5000:5000 --name my-app my-first-app
- Open your browser tab and refresh the page.
- You should see your new status message displayed on the DevOps Status Board.
Still seeing the old message?
- Make sure you saved app.py before running docker build. Unsaved changes are not included in the image.
- Confirm you removed the old container with docker rm my-app before running the new one. If a container with that name already exists, Docker refuses to create another.
- Try a hard refresh in your browser with Cmd+Shift+R (macOS) or Ctrl+Shift+R (Windows) to clear the cached page.
- I rebuilt my Docker image and ran a new container but the browser still shows the old status message
- See all Docker images on your machine by running:
docker images
You should see my-first-app listed along with the python:3.10-slim base image from your Dockerfile.
The Docker development workflow
You just practiced the standard cycle that DevOps teams use every day: edit code, rebuild the image, stop and remove the old container, then run a new one.
As your projects grow, tools like Docker Compose automate parts of this cycle. For now, knowing these commands by heart gives you a solid foundation.
Secret mission
Add a Health Check to Your Container
Your container is running. But how do you know if the app inside is actually healthy? In production, DevOps teams add health checks to containers so orchestrators can automatically detect and restart broken services.
Before you go
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs inside GitHub Codespaces, which has a free tier of 120 core hours per month. Leaving your Codespace running consumes those hours even when you are not using it.
Cost warning
GitHub Codespaces gives you 120 free core hours per month. A running Codespace uses hours continuously, even if you close the browser tab.
If you are done with this project, stop or delete your Codespace to avoid using up your free hours on something you are not actively working on.
Resources you used:
- GitHub repository docker-first-app.
- GitHub Codespace (cloud development environment).
- Docker image my-first-app.
- Docker container my-app.
- Project files: app.py, requirements.txt, Dockerfile, .dockerignore.
Keep everything running
No action needed. Choose this if you are still actively building or plan to continue working on this project right away.
- Your Codespace stays running and your Docker container keeps serving the app.
- Remember that a running Codespace consumes your free core hours. Come back to stop it when you are done for the day.
Pause - I'll come back to this later
Stop your Codespace to free up core hours while keeping all your files intact. You can restart it anytime and pick up where you left off.
- In your Codespace terminal, stop the Docker container by running docker stop my-app.
- Go to github.com/codespaces in your browser.
- Find your Codespace in the list, click the three-dot menu on the right, and select Stop codespace.
- Your files and Docker images are preserved. When you restart the Codespace, you can rebuild or rerun your container.
Delete - I don't want to use this again
Remove all project resources completely. This frees up storage and ensures nothing is left running.
- Go to github.com/codespaces in your browser.
- Find your Codespace in the list, click the three-dot menu on the right, and select Delete.
- To also delete the GitHub repository, go to your repository page, click Settings, scroll to the bottom, and click Delete this repository.
- Deleting the Codespace removes all files, Docker images, and containers inside it. Deleting the repository removes the code from GitHub entirely.
Mission accomplished
That's a Wrap!
You just containerized your first web application using Docker. That is a real DevOps skill that teams use every day to ship software.
You've learned how to:
- Built a Python Flask web app and wrote a Dockerfile to package it into a portable Docker image.
- Used essential Docker CLI commands like docker build, docker run, docker ps, docker logs, and docker exec to build, run, and debug containers.
- Managed the full container lifecycle including stopping, restarting, rebuilding with layer caching, and cleaning up old containers.
- Secret Mission: Added a /health endpoint and a HEALTHCHECK instruction to automatically monitor container health.
Ready to quiz yourself?