I'm trying to create a small size python image with mysqlclient for a flask API, this is the dockerfile:
FROM python:3.7-slim as builder
WORKDIR /build
RUN apt update && apt install -y build-essential default-libmysqlclient-dev git
ARG MYSQLCLIENT_VERSION=v2.0.3
RUN git clone --branch ${MYSQLCLIENT_VERSION} --depth 1 https://github.com/PyMySQL/mysqlclient-python
WORKDIR /build/mysqlclient-python
RUN python /build/mysqlclient-python/setup.py --static bdist_wheel && mv ./dist/*.whl /build
RUN pip install build
WORKDIR /app
COPY . /app
RUN python -m build . --outdir /build
FROM python:3.7-slim
COPY --from=builder /build /build
RUN pip install --find-links=/build app
CMD ["flask", "run"]
This is the error I receive when trying to connect to the db:
File "/usr/local/lib/python3.7/site-packages/MySQLdb/__init__.py", line 18, in <module>
from . import _mysql
ImportError: /usr/local/lib/python3.7/site-packages/MySQLdb/_mysql.cpython-37m-x86_64-linux-gnu.so: undefined symbol: TLS_client_method
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/bin/flask", line 8, in <module>
sys.exit(main())
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 967, in main
cli.main(args=sys.argv[1:], prog_name="python -m flask" if as_module else None)
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 586, in main
return super(FlaskGroup, self).main(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1062, in main
rv = self.invoke(ctx)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1668, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1404, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 763, in invoke
return __callback(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/click/decorators.py", line 26, in new_func
return f(get_current_context(), *args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/flask/cli.py", line 426, in decorator
return __ctx.invoke(f, *args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 763, in invoke
return __callback(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/app/db.py", line 26, in init_db_command
init_db()
File "/usr/local/lib/python3.7/site-packages/app/db.py", line 13, in init_db
db.create_all()
File "/usr/local/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 1090, in create_all
self._execute_for_all_tables(app, bind, 'create_all')
File "/usr/local/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 1082, in _execute_for_all_tables
op(bind=self.get_engine(app, bind), **extra)
File "/usr/local/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 1013, in get_engine
return connector.get_engine()
File "/usr/local/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 590, in get_engine
self._engine = rv = self._sa.create_engine(sa_url, options)
File "/usr/local/lib/python3.7/site-packages/flask_sqlalchemy/__init__.py", line 1023, in create_engine
return sqlalchemy.create_engine(sa_url, **engine_opts)
File "<string>", line 2, in create_engine
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/util/deprecations.py", line 298, in warned
return fn(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/create.py", line 548, in create_engine
dbapi = dialect_cls.dbapi(**dbapi_args)
File "/usr/local/lib/python3.7/site-packages/sqlalchemy/dialects/mysql/mysqldb.py", line 167, in dbapi
return __import__("MySQLdb")
File "/usr/local/lib/python3.7/site-packages/MySQLdb/__init__.py", line 24, in <module>
version_info, _mysql.version_info, _mysql.__file__
NameError: name '_mysql' is not defined
I know that building the wheel with static argument is supposed to deal with not having the default-libmysqlclient-dev installed.
If I build the mysqlclient module with build-essential and default-libmysqlclient-dev in same build stage it works, but I'm trying to remove those from final build as they take a lot of space.
I tryed with python 3.6-slim and this method works but couldn`t make it work for python 3.7 and higher.
What am I doing wrong?