0

I created a Django project which uses PostgreSQL as database. I already have PostgreSQL container and was trying to create an image of my project when I faced the following errors:

Preparing metadata (setup.py): started
#8 46.75   Preparing metadata (setup.py): finished with status 'error'
#8 46.75   error: subprocess-exited-with-error
#8 46.75
#8 46.75   × python setup.py egg_info did not run successfully.
#8 46.75   │ exit code: 1
#8 46.75   ╰─> [25 lines of output]
#8 46.75       /usr/local/lib/python3.12/site-packages/setuptools/config/setupcfg.py:508: SetuptoolsDeprecationWarning: The license_file parameter is deprecated, use license_files instead.
#8 46.75         warnings.warn(msg, warning_class)
#8 46.75       running egg_info
#8 46.75       creating /tmp/pip-pip-egg-info-h_1_kknf/psycopg2.egg-info
#8 46.75       writing /tmp/pip-pip-egg-info-h_1_kknf/psycopg2.egg-info/PKG-INFO
#8 46.75       writing dependency_links to /tmp/pip-pip-egg-info-h_1_kknf/psycopg2.egg-info/dependency_links.txt
#8 46.75       writing top-level names to /tmp/pip-pip-egg-info-h_1_kknf/psycopg2.egg-info/top_level.txt
#8 46.75       writing manifest file '/tmp/pip-pip-egg-info-h_1_kknf/psycopg2.egg-info/SOURCES.txt'
#8 46.75
#8 46.75       Error: pg_config executable not found.
#8 46.75
#8 46.75       pg_config is required to build psycopg2 from source.  Please add the directory
#8 46.75       containing pg_config to the $PATH or specify the full executable path with the
#8 46.75       option:
#8 46.75
#8 46.75           python setup.py build_ext --pg-config /path/to/pg_config build ...
#8 46.75
#8 46.75       or with the pg_config option in 'setup.cfg'.
#8 46.75
#8 46.75       If you prefer to avoid building psycopg2 from source, please install the PyPI
#8 46.75       'psycopg2-binary' package instead.
#8 46.75
#8 46.75       For further information please check the 'doc/src/install.rst' file (also at
#8 46.75       <https://www.psycopg.org/docs/install.html>).
#8 46.75
#8 46.75       [end of output]
#8 46.75
#8 46.75   note: This error originates from a subprocess, and is likely not a problem with pip.
#8 46.75 error: metadata-generation-failed
#8 46.75
#8 46.75 × Encountered error while generating package metadata.
#8 46.75 ╰─> See above for output.
#8 46.75
#8 46.75 note: This is an issue with the package mentioned above, not pip.
#8 46.75 hint: See above for details.
#8 48.72
#8 48.72 [notice] A new release of pip is available: 23.0.1 -> 23.1.2
#8 48.72 [notice] To update, run: pip install --upgrade pip
------
executor failed running [/bin/sh -c pip install -r requirements.txt]: exit code: 1

It's worth mentioning that my project works locally, well. Project is connected with database perfectly without any error. The problem happens as trying to create a docker container. It seems psycopg2 package refuses to be installed inside the container.

Here is requirements.txt

asgiref==3.6.0
Django==4.2
django-cors-headers==3.14.0
django-environ==0.10.0
djangorestframework==3.14.0
psycopg2==2.9.6
pytz==2023.3
sqlparse==0.4.4
tzdata==2023.3

And this is the Dockerfile

FROM python:3.12.0a7-slim-buster

WORKDIR /MyBackend

COPY requirements.txt .

RUN pip install -r requirements.txt

COPY . .

CMD ["python" , "manage.py" , "runserver" , "0.0.0.0:8000"]

I use a windows machine and I explored this issue on pages such as pg_config executable not found but none of answers fixed my problem. Of curse none of those crushes had raised the errors like mine.

Ramin
  • 21
  • 5

2 Answers2

2

Images that are optimised for size like slim and tiny are often stripped of every non-essential package, as in your case.

In order to install psycopg2 you need two additional libraries, so your Dockerfile looks like the following:

FROM python:3.12.0a7-slim-buster

WORKDIR /MyBackend

COPY requirements.txt .

RUN apt-get update && apt-get install -y gcc libpq-dev
RUN pip install -r requirements.txt

COPY . .

CMD ["python" , "manage.py" , "runserver" , "0.0.0.0:8000"]

and your requirements.txt needs a small adjustment as well:

asgiref==3.6.0
Django==4.2
django-cors-headers==3.14.0
django-environ==0.10.0
djangorestframework==3.14.0
psycopg2-binary==2.9.6
pytz==2023.3
sqlparse==0.4.4
tzdata==2023.3

This way your image will build as expected.

Rick Rackow
  • 1,490
  • 8
  • 19
  • Small addition as comment since it's not part of the answer: why are you first copying the `requirements.txt` and then two steps later copy the whole directory into the container? – Rick Rackow May 03 '23 at 14:53
  • Thank you so much. That's what I've learned following courses on Udemy and Youtube. To be honest I don't know the reason but it worked for me until I decided to connect my project with a PostgreSQL database. It would be honor if you tell me the best way to do that. – Ramin May 03 '23 at 17:32
  • As stated by [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) in the Docker documentation, _All changes made to the running container, such as writing new files, modifying existing files, and deleting files, are written to this writable container layer._ In your case, you create two layers by first copying the requirements and then copying the rest of the files (overwriting, also, the requirements.txt file). – arlugones May 03 '23 at 18:03
1

I've been facing the same issue while running a FastAPI app inside a Docker container built using python:3.10-slim image. Solved by changing to python:3.10 since disk space is not a problem for me.

arlugones
  • 103
  • 7
  • Thanks. You're right, there is no problem using this base Image, however I wanted to build my Image without using such a big base Image. – Ramin May 04 '23 at 14:23
  • If you need to have slim images the solution is the one proposed by @Rick Rackow. Adding *gcc* and *libpq-dev* should add ~300mb. It's also useful to remove apt lists to deflate the resulting image. Keep in mind the Docker's [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) – arlugones May 04 '23 at 18:19