FROM ubuntu:18.04 RUN apt-get update \ && apt-get upgrade -y \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* LABEL maintainer="Amazon AI" # Specify LABEL for inference pipelines to use SAGEMAKER_BIND_TO_PORT # https://docs.aws.amazon.com/sagemaker/latest/dg/inference-pipeline-real-time.html LABEL com.amazonaws.sagemaker.capabilities.accept-bind-to-port=true LABEL dlc_major_version="2" # Add arguments to achieve the version, python and url ARG PYTHON=python3.7 ARG PYTHON_VERSION=3.7.10 ARG PIP=pip3 ARG HEALTH_CHECK_VERSION=1.8.0 ARG S3_TF_EI_VERSION=1-6 ARG S3_TF_VERSION=2-3-0 # See http://bugs.python.org/issue19846 ENV LANG=C.UTF-8 # Python won’t try to write .pyc or .pyo files on the import of source modules ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 ENV SAGEMAKER_TFS_VERSION="${S3_TF_VERSION}" ENV PATH="$PATH:/sagemaker" ENV LD_LIBRARY_PATH='/usr/local/lib:$LD_LIBRARY_PATH' ENV MODEL_BASE_PATH=/models # The only required piece is the model name in order to differentiate endpoints ENV MODEL_NAME=model # To prevent user interaction when installing time zone data package ENV DEBIAN_FRONTEND=noninteractive # nginx + njs RUN apt-get update \ && apt-get -y install --no-install-recommends \ curl \ gnupg2 \ build-essential \ ca-certificates \ emacs \ git \ wget \ unzip \ vim \ && curl -s http://nginx.org/keys/nginx_signing.key | apt-key add - \ && echo 'deb http://nginx.org/packages/ubuntu/ bionic nginx' >> /etc/apt/sources.list \ && apt-get update \ && apt-get -y install --no-install-recommends \ nginx \ nginx-module-njs \ libbz2-dev \ libc6-dev \ libffi-dev \ libgdbm-dev \ libncursesw5-dev \ libreadline-gplv2-dev \ libsqlite3-dev \ libssl-dev \ libtiff5 \ tk-dev \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* # upgrade libpcre2-8-0 RUN wget http://ftp.de.debian.org/debian/pool/main/p/pcre2/libpcre2-8-0_10.36-2+deb11u1_amd64.deb \ && dpkg -i libpcre2-8-0_10.36-2+deb11u1_amd64.deb \ && rm -rf libpcre2-8-0_10.36-2+deb11u1_amd64.deb RUN wget https://www.python.org/ftp/python/$PYTHON_VERSION/Python-$PYTHON_VERSION.tgz \ && tar -xvf Python-$PYTHON_VERSION.tgz \ && cd Python-$PYTHON_VERSION \ && ./configure \ && make \ && make install \ && rm -rf ../Python-$PYTHON_VERSION* RUN ${PIP} --no-cache-dir install --upgrade \ pip \ setuptools # Some TF tools expect a "python" binary RUN ln -s $(which ${PYTHON}) /usr/local/bin/python \ && ln -s $(which ${PIP}) /usr/bin/pip # cython, falcon, gunicorn, grpc RUN ${PIP} install --no-cache-dir \ "awscli<2" \ boto3 \ certifi \ cython==0.29.21 \ falcon==2.0.0 \ gunicorn==20.0.4 \ gevent==21.1.1 \ requests==2.28.1 \ grpcio==1.31.0 \ protobuf==4.21.7 \ urllib3==1.26.12 \ # using --no-dependencies to avoid installing tensorflow binary && ${PIP} install --no-dependencies --no-cache-dir \ tensorflow-serving-api==2.3 COPY sagemaker /sagemaker # Get EI tools RUN wget https://amazonei-tools.s3.amazonaws.com/v${HEALTH_CHECK_VERSION}/ei_tools_${HEALTH_CHECK_VERSION}.tar.gz -O /opt/ei_tools_${HEALTH_CHECK_VERSION}.tar.gz \ && tar -xvf /opt/ei_tools_${HEALTH_CHECK_VERSION}.tar.gz -C /opt/ \ && rm -rf /opt/ei_tools_${HEALTH_CHECK_VERSION}.tar.gz \ && chmod a+x /opt/ei_tools/bin/health_check \ && mkdir -p /opt/ei_health_check/bin \ && ln -s /opt/ei_tools/bin/health_check /opt/ei_health_check/bin/health_check \ && ln -s /opt/ei_tools/lib /opt/ei_health_check/lib RUN wget https://amazonei-tensorflow.s3.amazonaws.com/tensorflow-serving/v2.3/archive/tensorflow-serving-${S3_TF_VERSION}-ei-${S3_TF_EI_VERSION}.tar.gz \ -O /tmp/tensorflow-serving-${S3_TF_VERSION}-ei-${S3_TF_EI_VERSION}.tar.gz \ && cd /tmp \ && tar zxf tensorflow-serving-${S3_TF_VERSION}-ei-${S3_TF_EI_VERSION}.tar.gz \ && mv tensorflow-serving-${S3_TF_VERSION}-ei-${S3_TF_EI_VERSION}/amazonei_tensorflow_model_server /usr/bin/tensorflow_model_server \ && chmod +x /usr/bin/tensorflow_model_server \ && rm -rf tensorflow-serving-${S3_TF_VERSION}* # Expose ports # gRPC and REST EXPOSE 8500 8501 # Set where models should be stored in the container RUN mkdir -p ${MODEL_BASE_PATH} # Create a script that runs the model server so we can use environment variables # while also passing in arguments from the docker command line RUN echo '#!/bin/bash \n\n' > /usr/bin/tf_serving_entrypoint.sh \ && echo '/usr/bin/tensorflow_model_server --port=8500 --rest_api_port=8501 --model_name=${MODEL_NAME} --model_base_path=${MODEL_BASE_PATH}/${MODEL_NAME} "$@"' >> /usr/bin/tf_serving_entrypoint.sh \ && chmod +x /usr/bin/tf_serving_entrypoint.sh RUN HOME_DIR=/root \ && curl -o ${HOME_DIR}/oss_compliance.zip https://aws-dlinfra-utilities.s3.amazonaws.com/oss_compliance.zip \ && unzip ${HOME_DIR}/oss_compliance.zip -d ${HOME_DIR}/ \ && cp ${HOME_DIR}/oss_compliance/test/testOSSCompliance /usr/local/bin/testOSSCompliance \ && chmod +x /usr/local/bin/testOSSCompliance \ && chmod +x ${HOME_DIR}/oss_compliance/generate_oss_compliance.sh \ && ${HOME_DIR}/oss_compliance/generate_oss_compliance.sh ${HOME_DIR} ${PYTHON} \ && rm -rf ${HOME_DIR}/oss_compliance* RUN curl https://aws-dlc-licenses.s3.amazonaws.com/tensorflow-2.3/license.txt -o /license.txt CMD ["/usr/bin/tf_serving_entrypoint.sh"]