DEV Community

Aisalkyn Aidarova
Aisalkyn Aidarova

Posted on

Beginner Lab: Build a Simple API, Dockerize It, and Push It to GitHub

Lab goal

Students will create a small Python API, test it in the browser, package it into a Docker image, run it as a container, and push the project to GitHub.

At the end, the workflow will look like this:

Write API code
     ↓
Test locally
     ↓
Create Dockerfile
     ↓
Build Docker image
     ↓
Run Docker container
     ↓
Test API in browser
     ↓
Push code to GitHub
Enter fullscreen mode Exit fullscreen mode

This is a realistic beginner DevOps workflow because DevOps engineers regularly work with application code, Git repositories, Docker images, ports, logs, and deployments.


Part 1: What we are building

Our API will have three endpoints:

GET /
GET /health
GET /courses
Enter fullscreen mode Exit fullscreen mode

Expected results:

http://localhost:5001/
Enter fullscreen mode Exit fullscreen mode
{
  "message": "Welcome to JumpToTech API"
}
Enter fullscreen mode Exit fullscreen mode
http://localhost:5001/health
Enter fullscreen mode Exit fullscreen mode
{
  "status": "healthy"
}
Enter fullscreen mode Exit fullscreen mode
http://localhost:5001/courses
Enter fullscreen mode Exit fullscreen mode
{
  "courses": [
    "Linux",
    "Git",
    "Docker",
    "AWS"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Part 2: Check the required software

Open Terminal.

Run:

docker --version
Enter fullscreen mode Exit fullscreen mode

Run:

git --version
Enter fullscreen mode Exit fullscreen mode

Run:

python3 --version
Enter fullscreen mode Exit fullscreen mode

Expected output will look similar to:

Docker version ...
git version ...
Python 3...
Enter fullscreen mode Exit fullscreen mode

Why do we check this?

Before starting a project, a DevOps engineer verifies that the required tools are installed.

This prevents us from writing the entire project and discovering later that Docker, Git, or Python is missing.


Part 3: Create the project folder

Run:

mkdir github-docker-api-lab
Enter fullscreen mode Exit fullscreen mode

Move into it:

cd github-docker-api-lab
Enter fullscreen mode Exit fullscreen mode

Check your location:

pwd
Enter fullscreen mode Exit fullscreen mode

Expected:

/Users/your-name/github-docker-api-lab
Enter fullscreen mode Exit fullscreen mode

Why?

Every application should have its own project folder.

All files related to this API will stay together:

github-docker-api-lab/
├── app.py
├── requirements.txt
├── Dockerfile
├── .dockerignore
├── .gitignore
└── README.md
Enter fullscreen mode Exit fullscreen mode

Part 4: Create the Python API with Vim

Create and open the application file:

vim app.py
Enter fullscreen mode Exit fullscreen mode

Vim opens in command mode.

Press:

i
Enter fullscreen mode Exit fullscreen mode

The letter i puts Vim into Insert mode, which allows you to type.

Paste this code:

from flask import Flask, jsonify

app = Flask(__name__)


@app.route("/")
def home():
    return jsonify({
        "message": "Welcome to JumpToTech API"
    })


@app.route("/health")
def health():
    return jsonify({
        "status": "healthy"
    })


@app.route("/courses")
def courses():
    return jsonify({
        "courses": [
            "Linux",
            "Git",
            "Docker",
            "AWS"
        ]
    })


if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
Enter fullscreen mode Exit fullscreen mode

Now press:

Esc
Enter fullscreen mode Exit fullscreen mode

Save and exit:

:wq
Enter fullscreen mode Exit fullscreen mode

Press Enter.

Basic Vim commands

Command Meaning
vim app.py Open or create the file
i Start typing
Esc Leave Insert mode
:wq Save and exit
:q! Exit without saving
dd Delete one line
u Undo
/word Search for a word

Part 5: Understand the API code

Import Flask

from flask import Flask, jsonify
Enter fullscreen mode Exit fullscreen mode

Flask is a Python framework used to build web applications and APIs.

jsonify converts Python data into JSON.

Flask is designed to make small web applications easy to start, which is why it works well for a beginner API lab. (Flask Documentation)


Create the application

app = Flask(__name__)
Enter fullscreen mode Exit fullscreen mode

This creates our Flask application.


Create the home endpoint

@app.route("/")
def home():
Enter fullscreen mode Exit fullscreen mode

This tells Flask:

When a user sends a GET request to /, run the home function.


Return JSON

return jsonify({
    "message": "Welcome to JumpToTech API"
})
Enter fullscreen mode Exit fullscreen mode

An API usually returns structured data such as JSON instead of a full webpage.


Health endpoint

@app.route("/health")
Enter fullscreen mode Exit fullscreen mode

DevOps engineers often use a health endpoint to determine whether an application is running.

Monitoring systems, load balancers, Docker, and Kubernetes can check endpoints like:

/health
/healthz
/status
Enter fullscreen mode Exit fullscreen mode

Courses endpoint

@app.route("/courses")
Enter fullscreen mode Exit fullscreen mode

This simulates getting data from an application.

Later, the data could come from:

  • PostgreSQL
  • MySQL
  • MongoDB
  • Another API
  • AWS service

Host setting

host="0.0.0.0"
Enter fullscreen mode Exit fullscreen mode

This is extremely important for Docker.

If Flask listens only on:

127.0.0.1
Enter fullscreen mode Exit fullscreen mode

it may be reachable only from inside the container.

Using:

0.0.0.0
Enter fullscreen mode Exit fullscreen mode

allows Flask to receive requests through Docker port mapping.


Part 6: Create requirements.txt

Run:

vim requirements.txt
Enter fullscreen mode Exit fullscreen mode

Press:

i
Enter fullscreen mode Exit fullscreen mode

Add:

Flask==3.1.1
Enter fullscreen mode Exit fullscreen mode

Press:

Esc
Enter fullscreen mode Exit fullscreen mode

Then:

:wq
Enter fullscreen mode Exit fullscreen mode

Why do we need this file?

requirements.txt lists the Python packages required by the application.

Without it, another computer would not know that Flask must be installed.

In a real company:

Developer code
     +
requirements.txt
     ↓
CI/CD pipeline
     ↓
Dependencies installed automatically
Enter fullscreen mode Exit fullscreen mode

Part 7: Test the application without Docker

Install the dependency:

python3 -m pip install -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

Run the application:

python3 app.py
Enter fullscreen mode Exit fullscreen mode

Expected output:

Running on http://127.0.0.1:5000
Running on http://...:5000
Enter fullscreen mode Exit fullscreen mode

Open the browser:

http://localhost:5000
Enter fullscreen mode Exit fullscreen mode

Then test:

http://localhost:5000/health
Enter fullscreen mode Exit fullscreen mode

And:

http://localhost:5000/courses
Enter fullscreen mode Exit fullscreen mode

Why test before Docker?

We first verify that the application itself works.

This separates two possible problems:

Application problem
Enter fullscreen mode Exit fullscreen mode

from:

Docker problem
Enter fullscreen mode Exit fullscreen mode

If the application fails before Docker, then Docker is not the cause.

Stop the Flask server by returning to Terminal and pressing:

Ctrl + C
Enter fullscreen mode Exit fullscreen mode

Part 8: Create the Dockerfile with Vim

Run:

vim Dockerfile
Enter fullscreen mode Exit fullscreen mode

Important: the file must be named exactly:

Dockerfile
Enter fullscreen mode Exit fullscreen mode

Not:

Dockerfile.txt
dockerfile
DockerFile
Enter fullscreen mode Exit fullscreen mode

Press:

i
Enter fullscreen mode Exit fullscreen mode

Paste:

FROM python:3.12-slim

WORKDIR /app

COPY requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY app.py .

EXPOSE 5000

CMD ["python", "app.py"]
Enter fullscreen mode Exit fullscreen mode

Press:

Esc
Enter fullscreen mode Exit fullscreen mode

Save:

:wq
Enter fullscreen mode Exit fullscreen mode

A Dockerfile is a text file containing the instructions Docker uses to create a container image. (Docker Documentation)


Part 9: Understand every Dockerfile instruction

FROM

FROM python:3.12-slim
Enter fullscreen mode Exit fullscreen mode

This is our base image.

It already contains:

  • Linux filesystem
  • Python
  • pip
  • required runtime tools

The slim image is smaller than the full Python image. Docker recommends choosing minimal base images where practical because they reduce download size and unnecessary components. (Docker Documentation)


WORKDIR

WORKDIR /app
Enter fullscreen mode Exit fullscreen mode

This creates or selects /app inside the image.

The commands that follow run from this directory.

Think of it like:

cd /app
Enter fullscreen mode Exit fullscreen mode

inside the image.


COPY requirements.txt

COPY requirements.txt .
Enter fullscreen mode Exit fullscreen mode

This copies the local file into /app inside the image.

The period means:

current working directory
Enter fullscreen mode Exit fullscreen mode

Because WORKDIR is /app, the file becomes:

/app/requirements.txt
Enter fullscreen mode Exit fullscreen mode

RUN

RUN pip install --no-cache-dir -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

This command runs while the image is being built.

It installs Flask into the image.

RUN is a build-time instruction.


COPY app.py

COPY app.py .
Enter fullscreen mode Exit fullscreen mode

This copies the Python API into the image.

The image now contains:

/app/app.py
/app/requirements.txt
Enter fullscreen mode Exit fullscreen mode

EXPOSE

EXPOSE 5000
Enter fullscreen mode Exit fullscreen mode

This documents that the application listens on port 5000 inside the container.

It does not automatically make the application accessible from the Mac.

We still need -p when we run the container.


CMD

CMD ["python", "app.py"]
Enter fullscreen mode Exit fullscreen mode

This starts the API when the container starts.

Difference:

RUN = executed while building the image
CMD = executed when starting the container
Enter fullscreen mode Exit fullscreen mode

Part 10: Create .dockerignore

Run:

vim .dockerignore
Enter fullscreen mode Exit fullscreen mode

Press i and add:

.git
.gitignore
README.md
__pycache__
*.pyc
venv
.env
Enter fullscreen mode Exit fullscreen mode

Press Esc, then:

:wq
Enter fullscreen mode Exit fullscreen mode

Why?

When we run:

docker build .
Enter fullscreen mode Exit fullscreen mode

Docker sends the current directory as the build context.

We do not want unnecessary files included.

For example:

  • Git history
  • temporary Python files
  • local virtual environment
  • secret .env files

This keeps builds cleaner and often faster.


Part 11: Create .gitignore

Run:

vim .gitignore
Enter fullscreen mode Exit fullscreen mode

Press i and add:

__pycache__/
*.pyc
venv/
.env
.DS_Store
Enter fullscreen mode Exit fullscreen mode

Press Esc, then:

:wq
Enter fullscreen mode Exit fullscreen mode

Why?

.gitignore tells Git which local files should not be committed.

We normally do not push:

  • operating-system files
  • Python cache
  • local environments
  • secrets
  • passwords
  • API keys

Part 12: Verify all files

Run:

ls -la
Enter fullscreen mode Exit fullscreen mode

You should see:

.
..
.dockerignore
.gitignore
Dockerfile
app.py
requirements.txt
Enter fullscreen mode Exit fullscreen mode

Check the contents:

cat app.py
Enter fullscreen mode Exit fullscreen mode
cat requirements.txt
Enter fullscreen mode Exit fullscreen mode
cat Dockerfile
Enter fullscreen mode Exit fullscreen mode

Why?

Your students previously had an empty Dockerfile. This check catches that problem before the build.


Part 13: Build the Docker image

Run:

docker build -t beginner-api:v1 .
Enter fullscreen mode Exit fullscreen mode

Explanation:

docker build
Enter fullscreen mode Exit fullscreen mode

Build an image.

-t
Enter fullscreen mode Exit fullscreen mode

Add a name and tag.

beginner-api
Enter fullscreen mode Exit fullscreen mode

Image name.

v1
Enter fullscreen mode Exit fullscreen mode

Image version.

.
Enter fullscreen mode Exit fullscreen mode

Use the current directory as the Docker build context.

Docker processes Dockerfile instructions in order, beginning from a base image defined by FROM. (Docker Documentation)


Part 14: Check the image

Run:

docker images
Enter fullscreen mode Exit fullscreen mode

Expected:

REPOSITORY      TAG
beginner-api    v1
Enter fullscreen mode Exit fullscreen mode

Important difference

Dockerfile = instructions
Image      = packaged application
Container  = running instance of the image
Enter fullscreen mode Exit fullscreen mode

A container is a runnable instance of an image. (Docker Documentation)


Part 15: Run the container

Use host port 5001 to avoid conflicts with macOS services or another Flask process:

docker run -d \
  -p 5001:5000 \
  --name beginner-api-container \
  beginner-api:v1
Enter fullscreen mode Exit fullscreen mode

Explanation

docker run
Enter fullscreen mode Exit fullscreen mode

Create and start a container.

-d
Enter fullscreen mode Exit fullscreen mode

Run in detached mode, in the background.

-p 5001:5000
Enter fullscreen mode Exit fullscreen mode

Map ports:

Mac port 5001 → container port 5000
Enter fullscreen mode Exit fullscreen mode
--name beginner-api-container
Enter fullscreen mode Exit fullscreen mode

Give the container a readable name.

beginner-api:v1
Enter fullscreen mode Exit fullscreen mode

Use this image.


Part 16: Check the container

Run:

docker ps
Enter fullscreen mode Exit fullscreen mode

Expected:

beginner-api-container
Up ...
0.0.0.0:5001->5000/tcp
Enter fullscreen mode Exit fullscreen mode

Test in the browser:

http://localhost:5001
Enter fullscreen mode Exit fullscreen mode
http://localhost:5001/health
Enter fullscreen mode Exit fullscreen mode
http://localhost:5001/courses
Enter fullscreen mode Exit fullscreen mode

Part 17: Test with curl

Run:

curl http://localhost:5001
Enter fullscreen mode Exit fullscreen mode

Run:

curl http://localhost:5001/health
Enter fullscreen mode Exit fullscreen mode

Run:

curl http://localhost:5001/courses
Enter fullscreen mode Exit fullscreen mode

Why use curl?

A browser is useful, but DevOps engineers frequently test APIs from the terminal.

curl is helpful when:

  • working on a remote Linux server
  • troubleshooting containers
  • testing CI/CD
  • checking health endpoints
  • testing APIs without a graphical browser

Part 18: Check logs

Run:

docker logs beginner-api-container
Enter fullscreen mode Exit fullscreen mode

Refresh the browser, then run it again:

docker logs beginner-api-container
Enter fullscreen mode Exit fullscreen mode

You should see requests such as:

GET / HTTP/1.1
GET /health HTTP/1.1
GET /courses HTTP/1.1
Enter fullscreen mode Exit fullscreen mode

To follow logs live:

docker logs -f beginner-api-container
Enter fullscreen mode Exit fullscreen mode

Press:

Ctrl + C
Enter fullscreen mode Exit fullscreen mode

to stop following the logs.

Why?

Logs are often the first place DevOps engineers investigate when an application fails.


Part 19: Enter the container

Run:

docker exec -it beginner-api-container sh
Enter fullscreen mode Exit fullscreen mode

Inside the container, run:

pwd
Enter fullscreen mode Exit fullscreen mode

Expected:

/app
Enter fullscreen mode Exit fullscreen mode

Run:

ls -la
Enter fullscreen mode Exit fullscreen mode

Run:

cat app.py
Enter fullscreen mode Exit fullscreen mode

Check Python:

python --version
Enter fullscreen mode Exit fullscreen mode

Check installed packages:

pip list
Enter fullscreen mode Exit fullscreen mode

Exit:

exit
Enter fullscreen mode Exit fullscreen mode

Why?

This helps students see that the application and dependencies really exist inside the container.

In production, DevOps engineers may enter a container temporarily to investigate files, environment variables, or network configuration. Permanent changes should be made in code or the Dockerfile, not manually inside the running container.


Part 20: Create a README with Vim

Run:

vim README.md
Enter fullscreen mode Exit fullscreen mode

Press i and add:

# Beginner GitHub Docker API Lab

This project demonstrates a simple Python Flask API running inside Docker.

## API endpoints

- `GET /`
- `GET /health`
- `GET /courses`

## Build the image

```bash
docker build -t beginner-api:v1 .
Enter fullscreen mode Exit fullscreen mode

Run the container

docker run -d -p 5001:5000 --name beginner-api-container beginner-api:v1
Enter fullscreen mode Exit fullscreen mode

Test

curl http://localhost:5001
curl http://localhost:5001/health
curl http://localhost:5001/courses
Enter fullscreen mode Exit fullscreen mode

Stop and remove

docker stop beginner-api-container
docker rm beginner-api-container
Enter fullscreen mode Exit fullscreen mode

Press `Esc`, then:

```text
:wq
Enter fullscreen mode Exit fullscreen mode

Why?

A README explains:

  • what the project does
  • how to build it
  • how to run it
  • how to test it

A new team member should be able to use the project without asking the original developer for every command.


Part 21: Initialize Git

Run:

git init
Enter fullscreen mode Exit fullscreen mode

Check:

git status
Enter fullscreen mode Exit fullscreen mode

You should see untracked files.

Why?

git init turns the folder into a local Git repository.

Git will now track the history of the project.


Part 22: Add the files

Run:

git add .
Enter fullscreen mode Exit fullscreen mode

Check:

git status
Enter fullscreen mode Exit fullscreen mode

The files should appear under:

Changes to be committed
Enter fullscreen mode Exit fullscreen mode

Why?

git add places files into the staging area.

The staging area lets us choose which changes should be part of the next commit.


Part 23: Commit

Run:

git commit -m "Create beginner Flask API with Docker"
Enter fullscreen mode Exit fullscreen mode

Check history:

git log --oneline
Enter fullscreen mode Exit fullscreen mode

Expected:

abc1234 Create beginner Flask API with Docker
Enter fullscreen mode Exit fullscreen mode

Why?

A commit is a saved checkpoint.

Good commit messages explain what changed.

Bad:

update
stuff
changes
Enter fullscreen mode Exit fullscreen mode

Better:

Create beginner Flask API with Docker
Add health-check endpoint
Update Docker port configuration
Enter fullscreen mode Exit fullscreen mode

Part 24: Create a GitHub repository

Go to GitHub and sign in.

Then:

  1. In the upper-right corner, click the plus icon.
  2. Click New repository.
  3. In Repository name, enter:
beginner-github-docker-api
Enter fullscreen mode Exit fullscreen mode
  1. Add a description:
Beginner Flask API containerized with Docker
Enter fullscreen mode Exit fullscreen mode
  1. Choose Public or Private.
  2. Do not select Add a README file, because you already created one locally.
  3. Do not add .gitignore, because you already created it.
  4. Do not choose a license for this lab.
  5. Click Create repository.

GitHub’s current documented workflow is to use the upper-right menu, select New repository, enter the repository details, and create it. (GitHub Docs)


Part 25: Connect the local project to GitHub

After creating the empty repository, GitHub displays commands.

Copy the repository URL.

It should look similar to:

https://github.com/YOUR-USERNAME/beginner-github-docker-api.git
Enter fullscreen mode Exit fullscreen mode

Return to Terminal.

Rename the main branch:

git branch -M main
Enter fullscreen mode Exit fullscreen mode

Add GitHub as the remote:

git remote add origin https://github.com/YOUR-USERNAME/beginner-github-docker-api.git
Enter fullscreen mode Exit fullscreen mode

Verify:

git remote -v
Enter fullscreen mode Exit fullscreen mode

Expected:

origin  https://github.com/YOUR-USERNAME/beginner-github-docker-api.git (fetch)
origin  https://github.com/YOUR-USERNAME/beginner-github-docker-api.git (push)
Enter fullscreen mode Exit fullscreen mode

GitHub documents git remote add as the command for connecting a local repository to a remote repository. (GitHub Docs)


Part 26: Push to GitHub

Run:

git push -u origin main
Enter fullscreen mode Exit fullscreen mode

Git may open a browser and ask you to authenticate.

After the push finishes:

  1. Return to the GitHub repository page.
  2. Refresh the page.
  3. You should see:
app.py
requirements.txt
Dockerfile
.dockerignore
.gitignore
README.md
Enter fullscreen mode Exit fullscreen mode

GitHub also documents using Git commands in the terminal to add locally hosted code to GitHub. (GitHub Docs)


Part 27: Make version 2

Open the API:

vim app.py
Enter fullscreen mode Exit fullscreen mode

Move to the bottom of the endpoint section.

Press:

i
Enter fullscreen mode Exit fullscreen mode

Add this route before the final if block:

@app.route("/students")
def students():
    return jsonify({
        "students": [
            "Samara",
            "Kasiet",
            "Jipara"
        ]
    })
Enter fullscreen mode Exit fullscreen mode

Press Esc, then:

:wq
Enter fullscreen mode Exit fullscreen mode

Check the change:

git diff
Enter fullscreen mode Exit fullscreen mode

Part 28: Rebuild the image

The currently running container will not automatically receive the code change.

Build version 2:

docker build -t beginner-api:v2 .
Enter fullscreen mode Exit fullscreen mode

Remove the old container:

docker rm -f beginner-api-container
Enter fullscreen mode Exit fullscreen mode

Run version 2:

docker run -d \
  -p 5001:5000 \
  --name beginner-api-container \
  beginner-api:v2
Enter fullscreen mode Exit fullscreen mode

Test:

curl http://localhost:5001/students
Enter fullscreen mode Exit fullscreen mode

Expected:

{
  "students": [
    "Samara",
    "Kasiet",
    "Jipara"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Why rebuild?

The image is an immutable package.

Changing app.py on your laptop does not change an image that was already built.

The correct workflow is:

Change code
    ↓
Build new image
    ↓
Create new container
Enter fullscreen mode Exit fullscreen mode

This repeatability is one of the major reasons teams use Docker.


Part 29: Push version 2 to GitHub

Run:

git status
Enter fullscreen mode Exit fullscreen mode

Stage:

git add app.py
Enter fullscreen mode Exit fullscreen mode

Commit:

git commit -m "Add students API endpoint"
Enter fullscreen mode Exit fullscreen mode

Push:

git push
Enter fullscreen mode Exit fullscreen mode

Go to GitHub and refresh.

Click:

app.py
Enter fullscreen mode Exit fullscreen mode

You should see the /students endpoint.

Click Commits to see both commits.


Final architecture

Developer
   |
   | edits with Vim
   v
Python Flask API
   |
   | git add / commit / push
   v
GitHub Repository
   |
   | docker build
   v
Docker Image
   |
   | docker run
   v
Docker Container
   |
   | port 5001 → 5000
   v
Browser or curl
Enter fullscreen mode Exit fullscreen mode

What each technology did

API

The API accepted HTTP requests and returned JSON.

Client request → API → JSON response
Enter fullscreen mode Exit fullscreen mode

Docker

Docker packaged:

  • Python
  • Flask
  • source code
  • dependency information
  • startup command

Git

Git tracked changes locally through commits.

GitHub

GitHub stored the repository remotely so the code could be shared, reviewed, and later used by a CI/CD pipeline.

Vim

Vim allowed students to create and edit files directly from the terminal, which is especially useful on remote Linux servers.


Troubleshooting

Error: Dockerfile cannot be empty

Check:

cat Dockerfile
Enter fullscreen mode Exit fullscreen mode

If nothing appears:

vim Dockerfile
Enter fullscreen mode Exit fullscreen mode

Add the Dockerfile content and save with:

Esc
:wq
Enter fullscreen mode Exit fullscreen mode

Error: port already allocated

Use another host port:

docker run -d -p 5002:5000 --name beginner-api-container beginner-api:v1
Enter fullscreen mode Exit fullscreen mode

Then open:

http://localhost:5002
Enter fullscreen mode Exit fullscreen mode

Error: container name already in use

Run:

docker ps -a
Enter fullscreen mode Exit fullscreen mode

Remove the old container:

docker rm -f beginner-api-container
Enter fullscreen mode Exit fullscreen mode

Run again.


Error: unable to find image locally

Check:

docker images
Enter fullscreen mode Exit fullscreen mode

If the image does not exist, build it:

docker build -t beginner-api:v1 .
Enter fullscreen mode Exit fullscreen mode

Container starts but browser does not work

Check:

docker ps
Enter fullscreen mode Exit fullscreen mode

Then:

docker logs beginner-api-container
Enter fullscreen mode Exit fullscreen mode

Make sure the Python code contains:

app.run(host="0.0.0.0", port=5000)
Enter fullscreen mode Exit fullscreen mode

Also make sure the port mapping is:

-p 5001:5000
Enter fullscreen mode Exit fullscreen mode

Git says remote origin already exists

Check:

git remote -v
Enter fullscreen mode Exit fullscreen mode

Change it:

git remote set-url origin https://github.com/YOUR-USERNAME/beginner-github-docker-api.git
Enter fullscreen mode Exit fullscreen mode

Student challenge

Ask students to add one new endpoint:

GET /devops-tools
Enter fullscreen mode Exit fullscreen mode

It should return:

{
  "tools": [
    "Git",
    "Docker",
    "Terraform",
    "Ansible",
    "Kubernetes"
  ]
}
Enter fullscreen mode Exit fullscreen mode

Then they must:

1. Test the Python application
2. Build beginner-api:v3
3. Replace the container
4. Test with curl
5. Commit the change
6. Push it to GitHub
Enter fullscreen mode Exit fullscreen mode

This lab teaches the complete beginner DevOps cycle:

Code → Test → Package → Run → Troubleshoot → Version → Push
Enter fullscreen mode Exit fullscreen mode

Top comments (0)