SAML-Toolkits / python3-saml

MIT License
688 stars 305 forks source link

Error when running from docker container #375

Open mostopalove opened 1 year ago

mostopalove commented 1 year ago

I'm trying to start my FastAPI server from a docker container, but it failed due to the following error:

INFO: Will watch for changes in these directories: ['/app']
INFO: Uvicorn running on http://0.0.0.0:3001 (Press CTRL+C to quit)
INFO: Started reloader process [1] using StatReload
Process SpawnProcess-1:
Traceback (most recent call last):
File "/usr/local/lib/python3.10/multiprocessing/process.py", line 314, in _bootstrap
self.run()
File "/usr/local/lib/python3.10/multiprocessing/process.py", line 108, in run
self._target(*self._args, **self._kwargs)
File "/app/.venv/lib/python3.10/site-packages/uvicorn/_subprocess.py", line 76, in subprocess_started
target(sockets=sockets)
File "/app/.venv/lib/python3.10/site-packages/uvicorn/server.py", line 60, in run
return asyncio.run(self.serve(sockets=sockets))
File "/usr/local/lib/python3.10/asyncio/runners.py", line 44, in run
return loop.run_until_complete(main)
File "/usr/local/lib/python3.10/asyncio/base_events.py", line 649, in run_until_complete
return future.result()
File "/app/.venv/lib/python3.10/site-packages/uvicorn/server.py", line 67, in serve
config.load()
File "/app/.venv/lib/python3.10/site-packages/uvicorn/config.py", line 477, in load
self.loaded_app = import_from_string(self.app)
File "/app/.venv/lib/python3.10/site-packages/uvicorn/importer.py", line 24, in import_from_string
raise exc from None
File "/app/.venv/lib/python3.10/site-packages/uvicorn/importer.py", line 21, in import_from_string
module = importlib.import_module(module_str)
File "/usr/local/lib/python3.10/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 883, in exec_module
File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
File "/app/./fast_api_service/main.py", line 16, in <module>
from .authentication import routes as auth_routes
File "/app/./fast_api_service/authentication/routes.py", line 3, in <module>
from onelogin.saml2.auth import OneLogin_Saml2_Auth, OneLogin_Saml2_Error
File "/app/.venv/lib/python3.10/site-packages/onelogin/saml2/auth.py", line 12, in <module>
import xmlsec
ImportError: libxmlsec1-openssl.so.1: cannot open shared object file: No such file or directory

Locally it works. I think I missed something in Dockerfile. This is my pyproject.toml:

[tool.poetry]
name = "test"
version = "0.1.0"
description = ""
authors = [""]
readme = "README.md"

[tool.poetry.dependencies]
python = ">=3.8.1,<3.11"
fastapi = "^0.92.0"
uvicorn = "^0.20.0"
mysqlclient = "2.1.1"
httpx = "^0.23.3"
sqlalchemy = ">=1.4.0,<1.5.0"
pydantic = {extras = ["dotenv"], version = "^1.10.6"}
loggerr = "^1.0.0"
pandas = "^1.5.3"
numpy = "^1.24.2"
dask = "^2023.3.2"
fastapi-redis-cache = "^0.2.5"
google-cloud-bigquery = "2.34.3"
google-cloud-bigquery-reservation = "1.11.1"
google-cloud-bigquery-storage = "2.19.1"
pyarrow = "^12.0.0"
python3-saml = "^1.15.0"
python-multipart = "^0.0.6"

[tool.poetry.group.dev.dependencies]
pytest = "^7.2.2"
autoflake = "^2.0.1"
flake8 = "^6.0.0"
black = "^23.1.0"
mypy = "^1.1.1"
pytest-cov = "^4.0.0"
sqlacodegen = "^2.3.0.post1"
pymysql = "^1.0.2"
requests = "^2.28.2"
locust = "^2.15.1"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

And here Dockerfile:

FROM python:3.10 as python-base

# SET ENV #
ENV PYTHONBUFFERED=1 \
    PIP_NO_CACHE_DIR="off" \
    POETRY_VERSION=1.4.0 \
    POETRY_HOME="/opt/poetry" \
    POETRY_VIRTUALENVS_IN_PROJECT=true \
    POETRY_NO_INTERACTION=1 \
    PYSETUP_PATH="/app" \
    VENV_PATH="/app/.venv"

ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"

FROM python-base as builder-base

# Build arg credentials
ARG DOCKER_JFROG_USER
ARG DOCKER_JFROG_PASS

RUN apt-get update && apt-get install --no-install-recommends -y curl \
    && curl -sSL https://install.python-poetry.org | python

ARG APP_TO_BUILD

WORKDIR $PYSETUP_PATH

RUN apt-get install pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl -y

COPY poetry.lock pyproject.toml ./

RUN python -m venv $VENV_PATH
RUN . ${VENV_PATH}/bin/activate
RUN pip install -U pip
RUN poetry install

FROM python-base as production
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH
COPY . $PYSETUP_PATH
CMD ["uvicorn", "fast_api_service.main:app", "--host", "0.0.0.0", "--port", "3001", "--reload", "--timeout-keep-alive", "60"]

I tried everything, but nothing helps, please help me figure it out

mostopalove commented 1 year ago

The problem was in Dockerfile. We should run this command at the beginning of file: RUN apt-get install pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl -y This is the correct version:

FROM python:3.10 as python-base

# SET ENV #
ENV PYTHONBUFFERED=1 \
    PIP_NO_CACHE_DIR="off" \
    POETRY_VERSION=1.4.0 \
    POETRY_HOME="/opt/poetry" \
    POETRY_VIRTUALENVS_IN_PROJECT=true \
    POETRY_NO_INTERACTION=1 \
    PYSETUP_PATH="/app" \
    VENV_PATH="/app/.venv"

ENV PATH="$POETRY_HOME/bin:$VENV_PATH/bin:$PATH"

RUN apt-get install pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl -y

FROM python-base as builder-base

# Build arg credentials
ARG DOCKER_JFROG_USER
ARG DOCKER_JFROG_PASS

RUN apt-get update && apt-get install --no-install-recommends -y curl \
    && curl -sSL https://install.python-poetry.org | python

ARG APP_TO_BUILD

WORKDIR $PYSETUP_PATH

COPY poetry.lock pyproject.toml ./

RUN python -m venv $VENV_PATH
RUN . ${VENV_PATH}/bin/activate
RUN pip install -U pip
RUN poetry install

FROM python-base as production
COPY --from=builder-base $PYSETUP_PATH $PYSETUP_PATH
COPY . $PYSETUP_PATH
CMD ["uvicorn", "fast_api_service.main:app", "--host", "0.0.0.0", "--port", "3001", "--reload", "--timeout-keep-alive", "60"]