Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 35 additions & 4 deletions Dockerfile.infer
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
WORKDIR /app
COPY requirements.txt .
COPY server.py .
#WORKDIR /app
#COPY requirements.txt .
#COPY server.py .
#FROM python:3.9-slim
#CMD ["python", "server.py"]
#RUN pip install --no-cache-dir -r requirements.txt
#EXPOSE 8080


FROM python:3.9-slim
CMD ["python", "server.py"]

# TODO: Set a working directory
WORKDIR /my-workdir

# TODO: Copy the requirements.txt file to the working directory
COPY requirements.txt /my-workdir/

# TODO: Install the Python dependencies
RUN pip install --no-cache-dir -r requirements.txt

# TODO: Copy the server script (server.py.py) to the working directory
COPY server.py /my-workdir/

#TODO: document which port(s) the container is intended to listen on at runtime
EXPOSE 8080

# TODO: Run the server script that generates the model
CMD ["python", "server.py"]


# command for image build
#docker build . --tag python-server-sd:v1.0.0 -f Dockerfile.infer

# command to run the docker image
#docker run --detach --name python_server_docker -p 4441:8080 -v .:/my-workdir python-server-sd:v1.0.0

#access the running docker locally via: http://127.0.0.1:4441/

17 changes: 15 additions & 2 deletions Dockerfile.train
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
FROM <base imagae>
FROM python:3.9-slim

# TODO: Set a working directory
WORKDIR /my-workdir

# TODO: Copy the requirements.txt file to the working directory
COPY requirements.txt /my-workdir/


# TODO: Install the Python dependencies
RUN pip install --no-cache-dir -r requirements.txt

# TODO: Copy the training script (train.py) to the working directory
COPY train.py /my-workdir/

# TODO: Run the training script that generates the model
CMD [...]
CMD ["python", "train.py"]


# command for image build
# docker build . --tag python-train-sd:v1.0.0 -f Dockerfile.train

# command to run the docker image
# docker run -v .:/my-workdir python-train-sd:v1.0.0
# output ot the docker run: Model training complete and saved as iris_model.pkl
46 changes: 23 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,40 @@ In this project, you will train, run and serve a machine learning model using Do

## Deliverables

- [ ] Clone this repository to your personal github account
- [ ] Containerize training the machine learning model
- [ ] Containerize serving of the machine learning model
- [ ] Train and run the machine learning model using Docker
- [ ] Run the Docker container serving the machine learning model
- [ ] Store the Docker images on your personal account on Docker Hub
- [ ] Provide the resulting Dockerfiles in GitHub
- [ ] Build an Apptainer image on a HPC of your choice
- [ ] Provide the logs of the slurm job in GitHub
- [ ] Document the steps in a text document in GitHub
- [X] Clone this repository to your personal github account
- [X] Containerize training the machine learning model
- [X] Containerize serving of the machine learning model
- [X] Train and run the machine learning model using Docker
- [X] Run the Docker container serving the machine learning model
- [X] Store the Docker images on your personal account on Docker Hub
- [X] Provide the resulting Dockerfiles in GitHub
- [X] Build an Apptainer image on a HPC of your choice
- [X] Provide the logs of the slurm job in GitHub
- [X] Document the steps in a text document in GitHub (Step-By-Step.md)

## Proposed steps - containerize and run training the machine learning model

Complete file named `Dockerfile.train`

- Copy requirements.txt and install dependencies
- Copy train.py to the working directory
- Set the command to run train.py
- Run the training of the model on your computer
- Document the command as comment in the Dockerfile
- Store the created Dockerfile in your cloned github repository
- [X] Copy requirements.txt and install dependencies
- [X] Copy train.py to the working directory
- [X] Set the command to run train.py
- [X] Run the training of the model on your computer
- [X] Document the command as comment in the Dockerfile
- [X] Store the created Dockerfile in your cloned github repository

## Proposed steps - containerize and serve the machine learning model

- Correct the order of the instructions in the Dockerfile.infer
- Document the steps in the Dockerfile.infer as comments
- Document the succesful `docker run` command in the Dockerfile.infer as a comment
- [X] Correct the order of the instructions in the Dockerfile.infer
- [X] Document the steps in the Dockerfile.infer as comments
- [X] Document the succesful `docker run` command in the Dockerfile.infer as a comment

## Proposed steps - store images on Dockerhub and build an Apptainer image on the HPC

- Create an account on Dockerhub
- Store the built images on your account
- Create a shell script on the HPC of your preference
- Store the shell script in your cloned github repository
- [X] Create an account on Dockerhub
- [X] Store the built images on your account
- [X] Create a shell script on the HPC of your preference
- [X] Store the shell script in your cloned github repository



49 changes: 49 additions & 0 deletions Step-By-step.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Clone this repository to your personal github account
git clone [email protected]:saradufour/project_docker_microcredential.git

# Containerize training the machine learning model

command for image build
`docker build . --tag python-train-sd:v1.0.0 -f Dockerfile.train`


# Containerize serving of the machine learning model

command for image build
`docker build . --tag python-server-sd:v1.0.0 -f Dockerfile.infer`


# Train and run the machine learning model using Docker


command to run the docker image (train)
`docker run -v .:/my-workdir python-train-sd:v1.0.0`
output ot the docker run: Model training complete and saved as iris_model.pkl


# Run the Docker container serving the machine learning model

command to run the docker image (server)
`docker run --detach --name python_server_docker -p 4441:8080 -v .:/my-workdir python-server-sd:v1.0.0`

access the running docker locally via: http://127.0.0.1:4441/


# Store the Docker images on your personal account on Docker Hub

`docker images`
`docker login`
`docker tag python-server-sd:v1.0.0 saradufour/python-server-sd:v1.0.0`
`docker push saradufour/python-server-sd:v1.0.0`
`docker tag python-train-sd:v1.0.0 saradufour/python-train-sd:v1.0.0`
`docker push saradufour/python-train-sd:v1.0.0`


# Provide the resulting Dockerfiles in GitHub
`git add *`
`git commit -m "..."`

# Apptainer
see VSC folder in github repository

`sbatch docker-project.sh`
17 changes: 17 additions & 0 deletions VSC/docker-project.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash

#SBATCH --job-name=jbuild-apptainer
#SBATCH --partition=donphan
#SBATCH --mem=8G
#SBATCH --time=00:30:00


LOG_DIR="$VSC_SCRATCH/logs"
mkdir -p $LOG_DIR

echo "build containers on VSC"

apptainer build --fakeroot python-train-sd.sif docker://saradufour/python-train-sd:v1.0.0 > $LOG_DIR/python-train-sd-OUT.log 2>&1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you could also use a SBATCH statement to create log files

apptainer build --fakeroot python-server-sd.sif docker://saradufour/python-server-sd:v1.0.0 > $LOG_DIR/python-server-sd-OUT.log 2>&1

echo "You can now run your container"
21 changes: 21 additions & 0 deletions VSC/python-server-sd-OUT.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
INFO: Starting build...
Copying blob sha256:24c9ec169934c78008ef30494c5735cce146c038004a2cf1bd5f63b674c75093
Copying blob sha256:8a628cdd7ccc83e90e5a95888fcb0ec24b991141176c515ad101f12d6433eb96
Copying blob sha256:74018f7cfa8f2965fd86b13c38f71417bc846e071a5f5bb5ae569ccb5a6e7248
Copying blob sha256:a0b0cfc480ce03c723a597904bcfbf28c71438c689e6d5097c2332835f67a40c
Copying blob sha256:97d21b95fb00ac3b08975ab6f8709f3a7e35a05d75e2f9a70fa95348279dac27
Copying blob sha256:d4802e1316679b361e2ebd439a0153a86f1a74de1f6490bce82b6985cdd27bd5
Copying blob sha256:bc05d8da204fd477b8bf4f4aeef2a6ea6694053102449fc04e709c6203026eb8
Copying blob sha256:47432841852a4fdb7690e090a9a51676251d42705f1af2e5a1eba975fbeb092b
Copying config sha256:472c6673fd87607215351b99a6779289b86b2a364d96f2a662cffbd859f146e2
Writing manifest to image destination
2025/04/24 14:41:05 info unpack layer: sha256:8a628cdd7ccc83e90e5a95888fcb0ec24b991141176c515ad101f12d6433eb96
2025/04/24 14:41:07 info unpack layer: sha256:74018f7cfa8f2965fd86b13c38f71417bc846e071a5f5bb5ae569ccb5a6e7248
2025/04/24 14:41:07 info unpack layer: sha256:a0b0cfc480ce03c723a597904bcfbf28c71438c689e6d5097c2332835f67a40c
2025/04/24 14:41:07 info unpack layer: sha256:97d21b95fb00ac3b08975ab6f8709f3a7e35a05d75e2f9a70fa95348279dac27
2025/04/24 14:41:07 info unpack layer: sha256:d4802e1316679b361e2ebd439a0153a86f1a74de1f6490bce82b6985cdd27bd5
2025/04/24 14:41:07 info unpack layer: sha256:24c9ec169934c78008ef30494c5735cce146c038004a2cf1bd5f63b674c75093
2025/04/24 14:41:07 info unpack layer: sha256:bc05d8da204fd477b8bf4f4aeef2a6ea6694053102449fc04e709c6203026eb8
2025/04/24 14:41:11 info unpack layer: sha256:47432841852a4fdb7690e090a9a51676251d42705f1af2e5a1eba975fbeb092b
INFO: Creating SIF file...
INFO: Build complete: python-server-sd.sif
21 changes: 21 additions & 0 deletions VSC/python-train-sd-OUT.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
INFO: Starting build...
Copying blob sha256:24c9ec169934c78008ef30494c5735cce146c038004a2cf1bd5f63b674c75093
Copying blob sha256:8a628cdd7ccc83e90e5a95888fcb0ec24b991141176c515ad101f12d6433eb96
Copying blob sha256:74018f7cfa8f2965fd86b13c38f71417bc846e071a5f5bb5ae569ccb5a6e7248
Copying blob sha256:a0b0cfc480ce03c723a597904bcfbf28c71438c689e6d5097c2332835f67a40c
Copying blob sha256:97d21b95fb00ac3b08975ab6f8709f3a7e35a05d75e2f9a70fa95348279dac27
Copying blob sha256:d4802e1316679b361e2ebd439a0153a86f1a74de1f6490bce82b6985cdd27bd5
Copying blob sha256:bc05d8da204fd477b8bf4f4aeef2a6ea6694053102449fc04e709c6203026eb8
Copying blob sha256:cf612e53a4c896366012dc36f6caea05fdd787b1ef4f52405a61d081f0fc05a0
Copying config sha256:0ac2dd017a895bf7cb7bda4e539f8b1cd9ad226083ac43541704cad96e34dab9
Writing manifest to image destination
2025/04/24 14:40:06 info unpack layer: sha256:8a628cdd7ccc83e90e5a95888fcb0ec24b991141176c515ad101f12d6433eb96
2025/04/24 14:40:07 info unpack layer: sha256:74018f7cfa8f2965fd86b13c38f71417bc846e071a5f5bb5ae569ccb5a6e7248
2025/04/24 14:40:07 info unpack layer: sha256:a0b0cfc480ce03c723a597904bcfbf28c71438c689e6d5097c2332835f67a40c
2025/04/24 14:40:08 info unpack layer: sha256:97d21b95fb00ac3b08975ab6f8709f3a7e35a05d75e2f9a70fa95348279dac27
2025/04/24 14:40:08 info unpack layer: sha256:d4802e1316679b361e2ebd439a0153a86f1a74de1f6490bce82b6985cdd27bd5
2025/04/24 14:40:08 info unpack layer: sha256:24c9ec169934c78008ef30494c5735cce146c038004a2cf1bd5f63b674c75093
2025/04/24 14:40:08 info unpack layer: sha256:bc05d8da204fd477b8bf4f4aeef2a6ea6694053102449fc04e709c6203026eb8
2025/04/24 14:40:11 info unpack layer: sha256:cf612e53a4c896366012dc36f6caea05fdd787b1ef4f52405a61d081f0fc05a0
INFO: Creating SIF file...
INFO: Build complete: python-train-sd.sif
2 changes: 2 additions & 0 deletions VSC/slurm-20167414.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build containers on VSC
You can now run your container
Binary file added iris_model.pkl
Binary file not shown.
2 changes: 1 addition & 1 deletion server.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
app = Flask(__name__)

# Check if the model file exists and wait until it does
model_path = '/app/models/iris_model.pkl'
model_path = '/my-workdir/iris_model.pkl'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, works as well


while not os.path.exists(model_path):
print(f"Waiting for model file at {model_path}...")
Expand Down
17 changes: 17 additions & 0 deletions train copy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from sklearn.svm import SVC
from sklearn import datasets
import joblib

#Load the Iris dataset
iris = datasets.load_iris()

#Create an SVM classifier
clf = SVC()

#Train the model using the iris dataset
model = clf.fit(iris.data, iris.target_names[iris.target])

#Save the trained model to the shared volume (make sure to use the correct path)
joblib.dump(model, '/my-workdir/iris_model.pkl')

print("Model training complete and saved as iris_model.pkl")
2 changes: 1 addition & 1 deletion train.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
model = clf.fit(iris.data, iris.target_names[iris.target])

#Save the trained model to the shared volume (make sure to use the correct path)
joblib.dump(model, '/app/models/iris_model.pkl')
joblib.dump(model, '/my-workdir/iris_model.pkl')

print("Model training complete and saved as iris_model.pkl")