0

This Python 3.9 project has a Dockerfile, that builds successfully. The file makes use of an ENTRYPOINT script to create some directories and handle some clean-up at run time. It is a bash script. The ENTRYPOINT script has no problem running until the very end, where it is expected to execute the CMD that is passed next. Well, I should say this behavior only happens when Kaniko builds the image. When the image is built locally, no such problem occurs. However, I am willing to chalk that up to the fact that locally is on a Windows machine. However, that shouldn't matter here because the error thrown is:

/opt/project/conf/entrypoint.sh: /usr/bin/supervisord: /usr/bin/python3: bad interpreter: No such file or directory
/opt/project/conf/entrypoint.sh: line 8: /usr/bin/supervisord: Success

Now I have looked at many "bad interpreter" questions. They all seem to revolve around the interpreter being in a custom place. I am reliant upon the default spot for the Python 3.9 interpreter. On Debian Bullseye (The OS behind the base image) that should be /usr/local/bin/python or /usr/local/bin/python3. So I am completely stumped as to why it is unable to find or use it.

Here are the implementation details:

Dockerfile:

FROM python:3.9-slim-bullseye

# Minimum Required Environment Variables
ENV SHELL=/bin/bash
ENV CC /usr/bin/gcc
ENV CXX /usr/bin/g++
ENV LANG=C.UTF-8
ENV DEBIAN_FRONTEND=noninteractive
ENV PYMSSQL_BUILD_WITH_BUNDLED_FREETDS=1
ENV PIP_CONFIG_FILE=/etc/pip.conf
ENV TZ=America/Los_Angeles

# Project Specific Environment Variables
ENV PROJECT_LOGFILE=/var/log/project/project.log
ENV PROJECT_CONFIG_DIRECTORY=/opt/project/conf
ENV PROJECT_SETTINGS_MODULE="project.settings"

# Files Needed for Dependency Installation
COPY dev/.pip.conf /etc/pip.conf
COPY dev/dev-requirements.txt /usr/local/requirements.txt

# Dependency Installation
WORKDIR /tmp
RUN apt-get  update \
    && apt-get upgrade -y \
    && apt-get install musl-dev g++ bash curl gnupg -y \
    && curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \
    && curl https://packages.microsoft.com/config/debian/11/prod.list > /etc/apt/sources.list.d/mssql-release.list \
    && apt-get  update \
    && apt-get install --no-install-recommends libfreetype-dev freetds-dev python-dev git libpng-dev libxml2-dev \
         libxslt-dev libssl-dev libopenblas-dev rsyslog supervisor tini tzdata libghc-zlib-dev libjpeg-dev cron \
         libgssapi-krb5-2 unixodbc-dev -y \
    && ACCEPT_EULA=Y apt-get install -y msodbcsql18 \
    && ln -s /usr/include/locale.h /usr/include/xlocale.h \
    && pip install --no-cache-dir --upgrade pip setuptools wheel \
    && pip install matplotlib --no-cache-dir \
    && pip install --no-cache-dir -r /usr/local/requirements.txt

# Setting Up For Install
COPY conf/ /opt/project/conf/
RUN mkdir -p /var/log/project /conf \
    && cp /opt/project/conf/supervisord.conf /conf/supervisord.conf \
    && cp /opt/project/conf/rsyslog.conf /conf/rsyslog.conf

WORKDIR /opt

# Copy Over Packages
COPY project-db-migrations /opt/project/project-db-migrations
COPY infrastructure /opt/infrastructure
COPY project /opt/project/src
COPY README.md /opt/project/README.md

# Install Infrastructure
RUN cd /opt/infrastructure && python3 setup.py install

# Install Project Service
RUN cd /opt/project/src && python3 setup.py install

RUN ["chmod", "+x", "/opt/project/conf/entrypoint.sh"]

WORKDIR /

EXPOSE 80

ENTRYPOINT ["tini", "--", "/opt/project/conf/entrypoint.sh"]
CMD ["supervisord", "-c", "/conf/supervisord.conf"]

entrypoint.sh

#!/bin/bash
set -eu

echo "Setting Up Project Service"

# Adding Temp Directory
mkdir -p /opt/project/tmp

echo "Service has been setup"

exec $@

supervisord.conf

[supervisord]
nodaemon=true
logfile=/var/log/project/supervisord.log
childlogdir=/var/log/project


[program:rsyslogd]
command=/usr/sbin/rsyslogd -n -f /conf/rsyslog.conf
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0


[program:crond]
command=/usr/sbin/cron -f -l 15
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0


[program:project]
command=python -m project.run --server
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0

The image is ran and deployed without changes to the user, so it should be running as root.

Beehive
  • 23
  • 1
  • 7
  • A Docker container is different from a virtual machine; it normally only runs a single process. Can you make the image's `CMD` be to run the Python project (without supervisord), and launch a second container from the same image to run the cron daemon? – David Maze Sep 27 '22 at 23:17

1 Answers1

0

In this case, after some digging I found there is an issue with the Kaniko version DevOps had running. That was causing the issue. Because the image wasn't being flattened correctly, Python could not start properly.

Beehive
  • 23
  • 1
  • 7