Inspired by @walidtlili's accepted answer (which uses the DockerFile syntax) as an inspiration, here is something I use for GitHub Actions, but my guess is that something very similar can be adapted for other CI/CD workflows.
GitHub has several choices for Linux 'runners' (the virtual machines on Microsoft Azure that run these scripts) and one of them has been the latest LTS version of Ubuntu (at the time of writing, Ubuntu noble 24.04.3 LTS). GitHub already adds lots of packages (the exact list is provided after a successful run), but, of course, you still only get ImageMagick 6.9.
Previously, I avoided compiling everything from scratch. Instead, I used the Debian ('universal') repositories to directly install it. However, recently, I noticed that Debian had released so many upgrades to those .deb packages since I first started to use them, that the versions I had were not only obsolete, but not even available from Debian's repositories (and mirrors!). As such, this method no longer worked.
I made an attempt to bring them up to date, but the problem is that they now have several conflicts with the (also updated) packages installed by Ubuntu: the versions don't match (which is understandable, since, to support ImageMagick 7 — released in 2016!! — you might need to have post-2016 versions of dependancy packages...). You can juggle around a bit with the GitHub runners' configuration (up t a point; a few things are off-limits) and certainly remove mismatched packages, replacing the original Ubuntu packages with shiny new ones from Debian, but... I quickly succumbed to the 'dependency hell'.
The solution was to inspire myself on @walidtlili's answer and do the equivalent for GitHub Actions. Note the slight differences in the packages being fetched; @walidtlili, for some reason, does three separate sudo apt-get update, possibly to guarantee that the packages are being installed in the correct order, but, in my case, it suffices listing all that are needed (considering that a few extra ones will be retrieved anyway — dependencies! — and many, such as compilers, are already pre-installed).
name: 'Compile ImageMagick 7 on Ubuntu 24.04.3'
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install packages needed for compilation
run: |
sudo apt-get update
sudo apt-get install -y --quiet wget autoconf pkgconf build-essential curl pkgconf libbz2-dev libfontconfig-dev libfreetype-dev libgs-dev libgvc6 libjpeg-dev libpng-dev libtiff-dev libxml2-dev
- name: Download ImageMagick source files to /tmp
run: |
cd /tmp
wget https://github.com/ImageMagick/ImageMagick/archive/refs/tags/7.1.2-7.tar.gz
tar xzf 7.1.2-7.tar.gz
rm 7.1.2-7.tar.gz
- name: Configure the ImageMagick build
run: |
cd /tmp/ImageMagick-7.1.2-7
sh ./configure --prefix=/usr/local --with-bzlib --with-fontconfig --with-freetype --with-gslib --with-gvc --with-jpeg --with-png --with-tiff --with-xml --with-gs-font-dir
- name: Compile ImageMagick
run: |
cd /tmp/ImageMagick-7.1.2-7
make -j
- name: Install ImageMagick
run: |
cd /tmp/ImageMagick-7.1.2-7
sudo make install
sudo ldconfig /usr/local/lib/
- name: Check if ImageMagick was built successfully
run: $(which identify) -list configure
# Moving on to the rest of the build...
Also note that I have broken up the full sequence in several steps, and, for each, I have to force cd /tmp/ImageMagick-7.1.2-7 each time¹ (each step runs independently from the others, albeit in sequence). There is no real "need" for having separate steps, but it was more convenient for me to debug. The above lines will also be quite chatty, to show what is being done, but I'd guess you could run them with --quiet flags (or the equivalent) and just ignore all the messages.
As of late 2025, the GitHub 'runners' currently take around 5 minutes to download everything, install the packages, run the ImageMagick autoconf building configuration, and finally compile all the components. I've also done all the checks (with make check) just to be 100% sure everything worked. But, to make things easier, I just list the compilation result by running identify -list configure: if that works, and shows all that I expect it to show, I know it's working correctly! 😉
If you just need to do all the above on your command line, or put it inside a script, then all you need is the following:
sudo apt-get update
sudo apt-get install -y --quiet wget autoconf pkgconf build-essential curl pkgconf libbz2-dev libfontconfig-dev libfreetype-dev libgs-dev libgvc6 libjpeg-dev libpng-dev libtiff-dev libxml2-dev
cd /tmp
wget https://github.com/ImageMagick/ImageMagick/archive/refs/tags/7.1.2-7.tar.gz
tar xzf 7.1.2-7.tar.gz
rm 7.1.2-7.tar.gz
cd /tmp/ImageMagick-7.1.2-7
sh ./configure --prefix=/usr/local --with-bzlib --with-fontconfig --with-freetype --with-gslib --with-gvc --with-jpeg --with-png --with-tiff --with-xml --with-gs-font-dir
make -j
sudo make install
sudo ldconfig /usr/local/lib/
identify -list configure
(the last step is, again, entirely optional)
Note that you don't need to do the actual compilation under the superuser (I'd seriously recommend not to); it's just the package installation that require superuser privileges, as well as the installation step. The ldconfig was added mostly because @walidtlili placed it at the end 😂
The point is helping the dynamic libraries to be found by existing packages, especially if you recompile everything and might have other things that depend on ImageMagick's dynamically loaded libraries.
Under Ubuntu, you can also do a simple
sudo echo "/usr/local/lib/ImageMagick-7.1.2/modules-Q16HDRI/filters" > /etc/ld.so.conf.d/ImageMagick.conf
... which should guarantee that the Linux code interpreter (which runs all compiled ELF binaries) correctly finds the location of the libraries. Just check that the above is the right directory — it was on my case, but YMMV.
This last step cannot be done on GitHub Acions, however, because not even the superuser is allowed to write to /etc on the virtual machine launched by a runner, for obvious security reasons. But sudo ldconfig /usr/local/lib/ works!
A last tip, you can host your own 'runners' locally, even when using GitHub Actions, allowing you full control over the virtual machine being launched. But that is definitely not relevant to the OP's original question!
I hope this can be useful for others as well.
¹ It's not strictly necessary to do it under /tmp. You can build everything locally, i.e., on whatever the virtual machine considers to be your "home". It's not as if everything will be permanently cluttered with litter — the virtual machine, after all, will be completely purged by GitHub Actions once it finishes the run. Technically speaking, even removing the downloaded source code is absolutely unnecessary; again, I just tried to keep everything as close as possible to @walidtlili solution.