Install mod-wsgi in a poetry virtual environment

Question:

I have a django app.

I’ve created a poetry virtual environment to manage dependencies.

This app runs on python 3.10.

My pyproject.toml looks like this:

[tool.poetry]
name = "django_manager"
version = "0.1.0"
description = "A Game manager"
authors = [""]

[tool.poetry.dependencies]
python = "^3.10"
Django = "^4.1.7"
beautifulsoup4 = "^4.12.0"
requests = "^2.28.2"
pillow = "^9.4.0"

[tool.poetry.dev-dependencies]

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

Now I’m trying to move the app to a CentOS VM, I copied the whole project folder to /var/www/html/GameManager and inside it run poetry install then poetry shell

Now if I do python -V I get Python 3.10.4 so that side works OK.

If I try to serve the app with apache:

/etc/httpd/conf.d/gamemanager.com.conf

<VirtualHost *:80>
  ServerName gamemanager.com
  ServerAlias *.gamemanager.com

  Redirect permanent / https://gamemanager.com/
</VirtualHost>

<VirtualHost *:443>
  ServerName gamemanager.com
  ServerAlias *.gamemanager.com

  <Directory /var/www/html/GameManager>
    <Files wsgi.py>
      Require all granted
    </Files>
  </Directory>

  WSGIDaemonProcess gamemanager.com display-name=gamemanager user=user group=user_group processes=2 threads=15
  WSGIScriptAlias / /var/www/html/GameManager/app/wsgi.py
  WSGIProcessGroup gamemanager.com


  TimeOut 3600
  LogLevel info
  ErrorLog "/var/log/httpd/gamemanager.com-error.log"
  CustomLog "/var/log/httpd/gamemanager.com-access.log" common
</VirtualHost>

I see in gamemanager.com-error.log an expception executing wsgi.py, probably because that it’s trying to use /home/user/.local/lib/python3.6/site-packages/django/conf/__init__.py

So right now I’m trying to fix that by installing mod-wsgi inside the venv with python3.10 and pip3.10.

But I get a bunch of errors:

/usr/bin/ld: /usr/local/lib/libpython3.10.a(pegen.o): relocation R_X86_64_32 against symbol `_Py_NoneStruct' can not be used when making a shared object; recompile con -fPIC
      /usr/bin/ld: /usr/local/lib/libpython3.10.a(parser.o): relocation R_X86_64_32 against `.text' can not be used when making a shared object; recompile con -fPIC
      /usr/bin/ld: /usr/local/lib/libpython3.10.a(string_parser.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile con -fPIC
      /usr/bin/ld: /usr/local/lib/libpython3.10.a(myreadline.o): relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile con -fPIC
      /usr/bin/ld: falló el enlace final: Sección no representable en la salida
      collect2: error: ld devolvió el estado de salida 1
      error: command '/usr/local/bin/gcc' failed with exit code 1
      [end of output]

I’ve read to build python with --enable-shared (not sure if possible since it’s installed by poetry) or needing LD_RUN_PATH environment variable but I don’t know what the value would be, /usr/local/lib/python3.10/???

Asked By: Daviid

||

Answers:

If Apache mod_wsgi refuses to use the virtual env, you can try gunicorn or uwsgi instead. Both can serve HTTP. You can use Apache with mod_proxy to forward requests or you can consider directly exposing uwsgi or gunicorn. You can also mod_uwsgi to Apache talk over uwsgi protocol. Nginx supports uwsgi too.

Doesn’t look like Apache knows about Poetry or the virtual environment. I would try wrapping your wsgi.py in a shell script that uses Poetry to start wsgi.py. That way Apache can use the wrapper script which will force it to use the right Python version.

The script should look like:

#!/bin/sh
exec poetry run python wsgi.py

And then Apache config should use:

WSGIScriptAlias / /var/www/html/GameManager/app/my-script-that-calls-poetry-run-python-wsgi-py.sh

Answered By: kichik
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.