简体   繁体   中英

Can't install dependencies in docker container

I'm using poetry library to manage project dependencies, so when I use

docker build --tag=helloworld .

I got this error

[AttributeError]               
'NoneType' object has no attribute 'group'  

Installing breaks on umongo (2.1.0) package

Here is my pyproject.toml file

[tool.poetry.dependencies]
python = "^3.7.0"
asyncio = "^3.4"
aiohttp = "^3.4"
motor = "^2.0"
umongo = "^2.0"
pyyaml = "^3.13"

[tool.poetry.dev-dependencies]
pytest = "^3.4"
black = {version = "^18.3-alpha.0",allows-prereleases = true}
mypy = "^0.650.0"
wemake-python-styleguide = "^0.5.1"
pytest-mock = "^1.10"
pytest-asyncio = "^0.9.0"
pytest-aiohttp = "^0.3.0"

And poetry.lock https://pastebin.com/kUjAKJHM

Dockerfile:

FROM python:3.7.1-alpine

RUN mkdir -p /opt/project/todo_api
RUN pip --no-cache-dir install poetry

COPY ./pyproject.toml /opt/project
COPY poetry.lock /opt/project

RUN cd /opt/project && poetry install --no-dev

COPY ./todo_api /opt/project/todo_api
COPY ./todo_api.yml /opt/project/todo_api.yml

WORKDIR /opt/project

ENTRYPOINT poetry run python -m aiohttp.web todo_api.main:main

Alternative approach

Don't install poetry into your deployment environment. It's a package management tool, which aims to improve development of and collaboration on libraries. If you want to deploy an application, you only need a package installer (read: pip ) - and the opinionated stance of poetry regarding the build process and virtual environments is harmful rather than helpful there.

In this case, the artifacts you want to copy into your docker image are 1) your most recent build of the library you work on and 2) a wheelhouse of tested dependencies, as defined by poetry.lock .

The first one is easy, run poetry build -f wheel and you have a nicely portable wheel. The second one is not yet easy, because poetry doesn't support building wheelhouses (and maybe never will), and pip wheel does not accept poetry.lock 's file format. So if you want go down this road, you need to work on a beta build of poetry ( v1.0.0b7 is rather stable) that supports poetry export -f requirements.txt > requirements.txt , which lets you create a requirements.txt file equivalent to your current lockfile.

Once you got that, you can run pip wheel -w dist -r requirements.txt , and finally , you're done creating all the artifacts for the docker image. Now, the following will work:

FROM python:3.7.1-alpine

WORKDIR /opt/project

COPY dist dist

RUN pip install --no-index --find-links dist todo_api

ENTRYPOINT python -m aiohttp.web todo_api.main:main

Pros

  • no unnecessary dependency on poetry in your server (might be relevant, since it's still <v1.0 )
  • you skip the virtualenv in your server and install everything right into the system (you might still choose to create a virtualenv on your own and install your app into that, since installing your application into the system python's side-packages can lead to problems )
  • your installation step doesn't run against pypi, so this deployment is guaranteed to work as far as you tested it (this is a very important point in many business settings)

Cons

  • it's a bit of a pain if you do it by hand each time, the target executor here should be a CI/CD and not a human
  • if the architecture of your workstation and the docker image differ, the wheels you build and copy over might not be compatible

The following works for me:

FROM python:3.7.1-alpine

WORKDIR /opt/project

RUN pip install --upgrade pip && pip --no-cache-dir install poetry

COPY ./pyproject.toml .

RUN poetry install --no-dev

with pyproject.toml:

[tool.poetry]
name = "57331667"
version = "0.0.1"
authors = ["skufler <skufler@email.com>"]

[tool.poetry.dependencies]
python = "^3.7.0"
asyncio = "^3.4"
aiohttp = "^3.4"
motor = "^2.0"
umongo = "^2.0"
pyyaml = "^3.13"

[tool.poetry.dev-dependencies]
pytest = "^3.4"
black = {version = "^18.3-alpha.0",allows-prereleases = true}
mypy = "^0.650.0"
wemake-python-styleguide = "^0.5.1"
pytest-mock = "^1.10"
pytest-asyncio = "^0.9.0"
pytest-aiohttp = "^0.3.0"

Then:

docker build --tag=57331667 --file=./Dockerfile .

results:

...
Creating virtualenv 57331667-py3.7 in /root/.cache/pypoetry/virtualenvs
Updating dependencies
Resolving dependencies...

Writing lock file


Package operations: 15 installs, 0 updates, 0 removals

  - Installing idna (2.8)
  - Installing multidict (4.5.2)
  - Installing six (1.12.0)
  - Installing async-timeout (3.0.1)
  - Installing attrs (18.2.0)
  - Installing chardet (3.0.4)
  - Installing marshmallow (2.19.5)
  - Installing pymongo (3.8.0)
  - Installing python-dateutil (2.8.0)
  - Installing yarl (1.3.0)
  - Installing aiohttp (3.5.4)
  - Installing asyncio (3.4.3)
  - Installing motor (2.0.0)
  - Installing pyyaml (3.13)
  - Installing umongo (2.1.0)
Removing intermediate container c6a9c7652b5c
 ---> 89354562cf16
Successfully built 89354562cf16
Successfully tagged 57331667:latest

If you want to install it with pip3 in production, here's how the latest version of Poetry (late 2021) can export a requirements.txt file:

# Production with no development dependencies
poetry export --no-interaction --no-ansi --without-hashes --format requirements.txt --output ./requirements.prod.txt

# For development, including development dependencies
poetry export --no-interaction --no-ansi --without-hashes --format requirements.txt --dev --output ./requirements.dev.txt

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM