feat(ship): first-party official docker images and supporting utilities#2004
feat(ship): first-party official docker images and supporting utilities#2004iamdadmin wants to merge 12 commits intotempestphp:3.xfrom
Conversation
|
|
While this is a working start, there's more to be done on making a fixed bill-of-materials, pinning and tracing versions in each build. At the moment we're just inheriting frankenphp and plopping it in a distroless image which works, but we can do better. Alpine is out for this reason https://frankenphp.dev/docs/performance/#dont-use-musl
So that brings us to options.
Downsides - php-zts packages aren't in Sury repo and will have to be built from source, Bazel really wants to deploy from repos, and it's a fairly big fork to maintain
Downsides - The tool is lower-level but can make fixed-file systems from package lists. We'll have to do some work to wrap a file-pinning BOM around it, and maintain that. Again, Sury repo doesn't do php-zts so we'd have to build PHP from source. We'd have to make and maintain it, breaking fairly fresh ground.
Downsides - Adopting Canonical may not be the wisest due to their not entirely FOSS-friendly choices at times (i.e. insisting on Snap instead of using Flatpak) and Chisel cannot work with non-Ubuntu repos. So we'd have to build php-zts and frankenphp from source and manage all those deps, which is a bit less ideal. That means no single BOM.
Downsides - relying on community maintainers to bump the php-zts and frankenphp packages, although granted, we could potentially submit PRs if we needed to. Learning curve, I'm willing to dive in, but it is it's own whole thing. My suggestionGiven all of the above, my feeling is that NixOS is probably actually the best way to go. We can inject our Caddyfile, and Nix can build an OCI-compatible image that we can just import to Docker or podman locally, or push to a registry. We'd produce a flake file for each build, and then as with composer, a flake.lock file is generated with a fixed package list. If we get a security advisory in dependencies, we can bump individual files and re-build. When frankenphp and/or php gets a bump, aka our 'primary' packages, we could either manage with git tags so we can inspect point in time, or we can literally duplicate the original flake file side-by-side in another folder or something. |
|
Okay, I've done a test with Nix, and there's some constraints that I think rule it out.
On to the next one! |
aidan-casey
left a comment
There was a problem hiding this comment.
Hey, @iamdadmin! I apologize for only just now getting around to this, there's a lot to review here. 🙂
First off, I appreciate the work you have put into this. Thank you!
Generally, as I look at this PR, I'm less concerned with the substance of it than I am of the complexity of it.
For example, let's envision the ideal user experience as something like:
# Publishes the Docker stubs to the root of our project.
tempest aloft:install
# Starts a dev environment.
docker compose up -d
# Builds a production image.
docker build .If we are publishing the stubs to the root of our project, is the average user going to be able to figure out how to add a PHP extension easily? Will they be able to debug a distroless container with little to no logs?
I'm thinking we might need to simplify this further, which might mean publishing a base build to the Docker registry and pulling from that for our stub. That would create an issue with distroless, however.
Dunno, I'm open to discussion on all this, just spitballing as I think about the dev experience.
How about RedHat's UBI? |
No worries at all, it helps me as much as it helps the community as I intend to use it myself. Equally, if I am not going in the direction wanted for Tempest, that's also fine, I'm not going to try to force it on you or anything and if what I want doesn't match I will just make my own package and use it :) So please, don't hold anything back or worry about wording, I won't be offended.
I agree, this implementation is more fragile than I was aiming for.
You're right that the PHP extensions issue is big. On the distroless side, the debug container has a shell, and we can figure out tweaks like logging configs, or even make sure all the logs go into /var/logs and we make that a container path so they're literally written in /logs/aloft/, or they can be viewed on the shell of course. We already set environment in .env so that can be utilised, or we can just turn all logs on in debug with a 7 day rotation/retention and all off in the distroless PROD image. I think the goal to aim for is that both images are in the registry for those who want no changes, or extendable locally.
I agree that this won't work in it's current iteration. My next test is:
What this means is that one will be able to do ./tempest aloft:build --with-phpExtensions "yml,other-extension,another-one,whatever" --composeInternally the --compose flag will just run ./tempest aloft:compose which can be used independently with the registry images. What this will do is automate the docker-build, locally, and with the --compose flag also build a docker-compose for those who need the full stack. For the end user? One or two simple commands. For us? We can use it in CI/CD to make SBOM-traceable images for each version pairing of php/frankenphp. We should probably envision some kind of version strategy for example for when Tempest itself moves past PHP8.5 to PHP8.6 - at this point maybe we archive all older versions from the registry itself, excepting the very last PHP8.5.x and frankenphp image, while retaining the SBOMs in the github repo in case people need to build them locally for their own needs, to keep storage costs managed etc. Looking forward, we should probably also tie in a package security check and actively remove images with known defects, I'm not sure on that mechanism yet and suspect best to put that in a second release as this commit will just get huge otherwise. I'm working on the Dagger workflow at the moment, given I have a working Dockerfile it hopefully won't take too much effort to convert it into Dagger commands, and test. Will keep you posted. |
I am not sure that RedHat’s FOSS strategy works best for us, I used to use CentOS for example… while it still exists I’m out of the loop on its state and fitness for purpose. So it makes me a little wary that we base on that and they change their minds. As I mentioned in another reply I managed to get file size down to within spitting distance of Alpine under Debian and it’s almost a default for docker containers to support Debian and Alpine (although not Alpine for us because of MUSL ofc). It’s about ready for another check when you can Aidan, I will go back over the last comments above and be sure to reply explaining how I’ve dealt with them, some I haven’t fully addressed yet and will need another commit, and we will need to figure out CI/CD and a repo at some point too. |
|
I'm a total docker noob so I'll follow @aidan-casey 's opinion on anything. One thing I do have an opinion on: we generally don't use names for our packages. Just use |
No worries, I would suggest we avoid |
…al docker images for TempestPHP
…initial, moved ServeCommand back to router package
…evelopment, fixed issue in stage-files under amd64
…o run a non-existent local image
…ipping and deploying utilities
|
Refactored to use tempest/ship referencing #352 and will nudge it into Ready for review. Still perhaps some questions to answer on CI/CD and public images, but this should provide a fully local deployment as it stands, and we could consider public image repos etc separately. |
Closes #1983
Introducing tempestphp/aloft
Or, at least, if you like the name! 'aloft' was my idea for this pseudo-package because it invokes imagery of things in the sky ... among the clouds ... and docker images are very 'cloudy'.
I'll write out some Q&A in another reply, probably tomorrow now, so you can understand my choices in the design and production of this image, including the answers to "why not alpine?", "why rootless?" and "why distroless?".
Initial draft PR includes
./tempest serve --aloftto pull and run the docker image to serve a dev server, alongside php dev server remaining primaryThings to be checked
Still to be done
Future roadmap