Skip to content

Commit

Permalink
Dockerize the entier wrapping process
Browse files Browse the repository at this point in the history
  • Loading branch information
errordeveloper committed Jan 19, 2018
1 parent 3b168ad commit 6d5c4a8
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 17 deletions.
19 changes: 3 additions & 16 deletions docs/getting_started/minikube.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,24 +64,11 @@ In this session, we show how to wrap the sklearn iris classifier in the [seldon-
cd seldon-core/examples/models/sklearn_iris/
```
```bash
python train_iris.py
make
````
This will train a simple logistic regression model on the iris dataset and save the model in the same folder.
3. Wrap your saved model using the core-python-wrapper docker image:
```bash
docker run -v $(pwd):/model seldonio/core-python-wrapper:0.4 /model IrisClassifier 0.1 seldonio --force
```
4. Build the docker image locally
```bash
cd build
./build_image.sh
```
This will create the docker image ```seldonio/irisclassifier:0.1``` inside the minikube cluster which is ready for deployment with Seldon Core.
This will build a docker image. During the build, the simple model will be trained (see `train_iris.py`).
Image name will be called `seldonio/irisclassifier:0.1`, and it will be ready for deployment with Seldon Core.
### Deploy your model
Expand Down
4 changes: 4 additions & 0 deletions examples/models/sklearn_iris/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.dockerignore
Dockerfile
Makefile
sklearn_iris_deployment.json
84 changes: 84 additions & 0 deletions examples/models/sklearn_iris/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
## Use alpine as build time and runtime image
FROM alpine:3.7 as build-alpine

## Install build dependencies
RUN apk add --update \
build-base \
freetype-dev \
gcc \
gfortran \
libc6-compat \
libffi-dev \
libpng-dev \
openblas-dev \
openssl-dev \
py2-pip \
python2 \
python2-dev\
wget \
&& true

## Symlink missing header, so we can compile numpy
RUN ln -s /usr/include/locale.h /usr/include/xlocale.h

## Copy package manager config to staging root tree
RUN mkdir -p /out/etc/apk && cp -r /etc/apk/* /out/etc/apk/
## Install runtime dependencies under staging root tree
RUN apk add --no-cache --initdb --root /out \
alpine-baselayout \
busybox \
ca-certificates \
freetype \
libc6-compat \
libffi \
libpng \
libstdc++ \
musl \
openblas \
openssl \
python2 \
&& true
## Remove package manager residuals
RUN rm -rf /out/etc/apk /out/lib/apk /out/var/cache

## Enter model source tree and install all Python depenendcies
COPY . /src
WORKDIR /src
## TODO this does take a while to build, maybe a good idea to
## put all related build dependencies into a separate public image
RUN pip install --requirement requirements.txt
## Train the model
RUN python train_iris.py

## Copy source code and Python dependencies to the saging root tree
RUN mkdir -p /out/src && cp -r /src/* /out/src/
RUN mkdir -p /out/usr/lib/python2.7/ && cp -r /usr/lib/python2.7/* /out/usr/lib/python2.7/

## Use Seldon Core wrapper image to wrap the model source code
FROM seldonio/core-python-wrapper:0.4 as build-wrapper

ARG MODEL_NAME
ARG IMAGE_VERSION
ARG IMAGE_REPO

## Copy staging diretory here
COPY --from=build-alpine /out /out
## Wrap the Python model
WORKDIR /wrappers/python
RUN python wrap_model.py /out/src $MODEL_NAME $IMAGE_VERSION $IMAGE_REPO --force

## Copy wrapped model source code into staging tree and cleanup what is not neccessary at runtime
RUN mkdir -p /out/microservice && cp -r /out/src/build/* /out/microservice/ && rm -rf /out/src
WORKDIR /out/microservice
RUN rm -f Dockerfile Makefile requirements*.txt build_image.sh push_image.sh
## TODO dockerfile doesn't support build argument interpolation in array notation for ENTRYPOINT & CMD
## to get rid of `/bin/sh` wrapper, it'd help to make $MODEL_NAME an environment variable and let the
## Python script pick it up
RUN printf '#!/bin/sh\nexec python microservice.py %s REST --service-type MODEL --persistence 0' $MODEL_NAME > microservice.sh && chmod +x microservice.sh

## Copy staging root tree onto an empty image
FROM scratch
COPY --from=build-wrapper /out /
WORKDIR /microservice
EXPOSE 5000
ENTRYPOINT ["/microservice/microservice.sh"]
11 changes: 11 additions & 0 deletions examples/models/sklearn_iris/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
IMAGE_REPO?=seldonio
IMAGE_NAME?=irisclassifier
IMAGE_VERSION?=0.1
MODEL_NAME?=IrisClassifier

container_image:
docker build \
--build-arg IMAGE_REPO=$(IMAGE_REPO) \
--build-arg IMAGE_VERSION=$(IMAGE_VERSION) \
--build-arg MODEL_NAME=$(MODEL_NAME) \
--tag $(IMAGE_REPO)/$(IMAGE_NAME):$(IMAGE_VERSION) .
9 changes: 8 additions & 1 deletion examples/models/sklearn_iris/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
scikit-learn==0.19.0
numpy==1.11.2
pandas==0.18.1
grpc==0.3.post19
grpcio==1.8.4
Flask==0.11.1
futures
redis==2.10.5
scipy==0.18.1
scikit-learn==0.19.0

0 comments on commit 6d5c4a8

Please sign in to comment.