heroku / base-images

Recipes for building the base images for Heroku's stacks
BSD 3-Clause "New" or "Revised" License
267 stars 75 forks source link

Reintroduce ghostscript for heroku-24 #324

Closed joshwlewis closed 1 month ago

joshwlewis commented 1 month ago

We've received some feedback about ghostscript (which was included in Heroku-18, Heroku-20, and Heroku-22, but was not included in Heroku-24):

Removing ghostscript has an effect on imagemagick based libraries on Python(eg. wand etc). We had to revert to using a custom buildpack(https://github.com/Airbase/heroku-buildpack-ghostscript) to install these back. The imagemagic libraries are fairly common in the python world to do PDF, image manipulations, thumb-nailing etc.

So, while not being used directly a ton, folks do use ghostscript via ImageMagick to work with PDFs.

~Other packages we could consider:~

~- libgs10~ ~- gsfonts~

GUS

edmorley commented 1 month ago

Does the APT buildpack work for installing ghostscript?

joshwlewis commented 1 month ago

Does the APT buildpack work for installing ghostscript?

In my testing (with CNBs), no. gs needs libXt.so.6 which comes from libxt6t64. libxt6t64 is installed on heroku/heroku:24-build, so the Debian packages CNB won't install it. libxt6t64 is not present on the heroku/heroku:24 image, though, so gs fails at runtime.

If we would rather make ghostscript installable by the Debian packages CNB, we might have to add libxt6t64 to the run image. This library is probably in the same bucket as those in #317.

edmorley commented 1 month ago

Checking against the nightly image tag (since that has #321), the size impact of adding Ghostscript isn't as bad as I would have thought (albeit it still is +10%):

$ dr --user root heroku/heroku:24.nightly bash -c 'apt-get update -qq && apt-get install --no-install-recommends ghostscript'
Unable to find image 'heroku/heroku:24.nightly' locally
24.nightly: Pulling from heroku/heroku
1567e7ea90b6: Pull complete
1bb2a64922ff: Pull complete
Digest: sha256:5afdec7165e02ba0334afc2b1246c9ce3b9ad94e4c79082ee3fae73a065573a3
Status: Downloaded newer image for heroku/heroku:24.nightly
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following additional packages will be installed:
  libavahi-client3 libavahi-common-data libavahi-common3 libcups2t64 libdbus-1-3 libgs-common libgs10 libgs10-common libice6 libidn12 libijs-0.35 libjbig2dec0 libpaper1 libsm6
  libxt6t64 poppler-data
Suggested packages:
  texlive-binaries cups-common fonts-japanese-mincho | fonts-ipafont-mincho fonts-japanese-gothic | fonts-ipafont-gothic fonts-arphic-ukai fonts-arphic-uming fonts-nanum
Recommended packages:
  dbus fonts-droid-fallback libpaper-utils
The following NEW packages will be installed:
  ghostscript libavahi-client3 libavahi-common-data libavahi-common3 libcups2t64 libdbus-1-3 libgs-common libgs10 libgs10-common libice6 libidn12 libijs-0.35 libjbig2dec0
  libpaper1 libsm6 libxt6t64 poppler-data
0 upgraded, 17 newly installed, 0 to remove and 46 not upgraded.
Need to get 7481 kB of archives.
After this operation, 44.1 MB of additional disk space will be used.
Do you want to continue? [Y/n] n

Other packages we could consider:

  • libgs9
  • gsfonts

ghostscript already transitively depends of libgs10, so we don't need to add an explicit libgsNN dep.

And gsfonts is only a transitional package that wraps fonts-urw-base35 (which itself is both a transitive dep of ghostscript and also included after #321): https://packages.ubuntu.com/noble/gsfonts

...so we don't need to explicitly include gsfonts either.

edmorley commented 1 month ago

Fwiw I'd be fine with either adding back ghostscript, or else adding libxt6t64 and mentioning using the APT buildpack for ghostscript in the Heroku-24 migration guide.

joshwlewis commented 1 month ago

The full Aptfile to get gs --version working with the classic buildpack heroku-buildpack-apt:

ghostscript
libxt6t64
libidn12
libsm6
libice6

Though, gs still throws errors about not being able to find initialization scripts. This can be solved by manually setting GS_LIB. I say this just to illustrate the point that the apt and debian packages buildpacks won't get users all the way to a working gs and some extra steps are needed.

If we want to support installation via the Debian packages CNB, we'd need to addlibxt6t64, libidn12, libsm6, libice6 to the run image. These are all in heroku/heroku:24-build, but not heroku/heroku:24, so the Debian packages CNB won't install them.

edmorley commented 1 month ago

Hmm yeah so adding ghostscript to the run image is sounding like the easier option for now.

Though long long term, if we introduce a slim image, I suppose we'll want to update the Debian packages CNB to set GS_LIB as one of the compatibility env vars it sets, which would then make it possible to use the slim image and add ghostscript via the CNB.

colincasey commented 1 month ago

Tried installing ghostscript using the deb CNB and @joshwlewis is correct. We need to be careful with packages we add to the build image but not the run image or find some way to detect this build/runtime discrepancy.