-
-
Notifications
You must be signed in to change notification settings - Fork 803
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dev: Create a Python package, build Docker images from it #4551
base: mealie-next
Are you sure you want to change the base?
Conversation
Without wanting to speak to the overall validity of this PR (I've not looked in any details), I just wanted to note that the below is not an objective for the Mealie project:
|
I understand, but is it an anti-objective? That is, if a PR improves things overall (e.g. faster CI, or easier dev environment setup) will it be rejected just because it happens to make it easier to install Mealie from a package? |
dbcd6a6
to
2276563
Compare
Now that #4329 has been merged, I've rebased this PR onto the latest |
2276563
to
30594a5
Compare
Sorry, I've been meaning to respond. No, not an anti-objective. However, if it requires any meaningful additional maintenance time from the team, it's not what we want to do. We are all for improvements! But we have limited time. |
* Remove assumption about the root of the mealie package being on the Python path (change "app:app" -> "mealie.app:app" in `main.py`). * Remove `start` entrypoint because it is not used and the name "start" is too generic.`
* Add a GitHub workflow to build a Python wheel for Mealie * The release and e2e workflows use the wheel (and requirements.txt) to create Docker images, instead of building them from scratch.
7802f67
to
1f5b653
Compare
That's completely fair; I don't want to take your time away from adding features and fixing bugs. With this PR I've tried to keep the old developer workflows the same (to not burden developers with having to learn a new way of doing things), and I've made sure the GitHub workflows are completely automated, without needing any extra maintainer oversight. |
There's some workflow checks that aren't completing ("Frontend and End-to-End Tests"), because they're defined in the |
What type of PR is this?
What this PR does / why we need it:
Build a Python package (sdist and wheel) that can be used to install Mealie, including the frontend SPA files. The package is then used to create the Docker images used for testing and release.
The advantage here is that the frontend code (Javascript) and backend code (Python) are both platform-independent, and so the same package can be installed into both the ARM64 and AMD64 Docker images. This saves having to build them twice.
Eventually, Mealie will be completely installable from PyPI as a Python package, as an option in addition to the Docker images. But more work is needed to achieve that goal and further PRs will follow this one. Until then, this PR stands on its own to benefit the E2E testing and CI release process, and can be merged now.
Changes in detail
The backend by default looks for the frontend SPA files in
mealie/frontend
(actually, thefrontend
sub-directory of themealie
Python package). This can still be overridden by settingSTATIC_FILES
.There is a new top-level task in
Taskfile.yml
,py:package
, that builds the Python packages. The generated frontend files are copied fromfrontend/dist
tomealie/frontend
by the taskpy:package:copy-frontend
(called bypy:package
).During the package build, a
requirements.txt
file is generated from Poetry's lock file. This ensures that exact pinned dependencies are installed.I have documented the 2 ways to build Mealie in building-packages.md.
A few extra stages are added to the Dockerfile to allow setting an additional build context which holds the pre-built Python package (and associated
requirements.txt
). This can be done by using the docker build argument--build-context packages=dist
, wheredist
is the directory holding a pre-built package. When this context is not set, the Dockerfile will build the package itself. When it is set, the build steps will be skipped.The steps of the
py:package
task are replicated in the Dockerfile's frontend and backend build stages. This ensures that runningdocker-compose up
will give the same result, regardless of whether the Docker image was built from a pre-built package or from scratch.The GitHub workflows have been modified to make use of this. There is a new
partial-package.yml
workflow that incorporates the frontend build, adds a backend build, and stores the resulting package as an artifact for later jobs. The E2E testing workflow uses the package for its Docker build, ensuring that it gets tested. The partial-builder workflow also uses the package for its Docker image build and push, saving the effort of rebuilding the frontend and backend for each platform.Finally, to make the Python package a bit nicer to use (not needing to modify
PYTHONPATH
), I've incorporated #4323 into this PR.Which issue(s) this PR fixes:
This is a few tasks from discussion 4322.
Testing
task docker:prod
to build from scratch and test the Docker image.task docker:build-from-package
to rebuild the Docker image (after deleting the previous one), followed bytask docker:prod
to test it.