Building with FPM
We build RPMs for all of our internal projects at DataSift, which means that we end up writing (or more likely, copying) an RPM spec file in to each project. Some of our build tools use FPM to build themselves, and I figured it was worth a look.
Imagine that we have a project name shinything
. I've simplified our actual project layout a lot, but at it's core it looks like the following:
bash
.├── resources├── src│ ├── application│ │ ├── controller│ │ │ └── IndexController.php│ │ ├── model│ │ │ └── User.php│ │ └── view│ │ └── show-user.php│ ├── composer.json│ ├── composer.lock│ ├── config│ │ ├── mappings.json│ │ └── targets.json│ └── public│ └── index.php└── test
From this, we want everything in the src
folder to be in our RPM package, making sure that the test
and resources
folders never make it to production. We want to install the application to /var/www/shinything
and it's config to /etc/shinything
.
The first thing we need to do is to tell fpm
that we want to build from a directory, we want an RPM as our output and that our RPM should be called "shinything".
bash
fpm -s dir -t rpm -n shinything
Next, we need to map the files on disk to their location once installed. To do this, you use the source=dest
option
bash
fpm -s dir -t rpm -n shinything src/=/var/www/shinything
This means that everything in src
will be installed to /var/www/shinything
. The /
after src
is important, as it means use everything inside that directory, without using that directory itself.
As well as the application, we need to install the config files we need to /etc/shinything
. We can add another source=dest
option to do this:
bash
fpm -s dir -t rpm -n shinything src/=/var/www/shinything src/config/=/etc/shinything
We want to mark anything in /etc
as a config file so that they are not overwritten when we update our RPM if there are local changes:
bash
fpm -s dir -t rpm -n shinything --config-files /etc --exclude src/config src/=/var/www/shinything src/config/=/etc/shinything
Finally, we want to remove the config files from /var/www/shinything/config
so that people don't mistakenly use them. To do this, we can use the exclude
filter. Be careful not to add a leading slash or it won't match.
bash
fpm -s dir -t rpm -n shinything --config-files /etc --exclude "var/www/shinything/config*" src/=/var/www/shinything src/config/=/etc/shinything
At this point, we've created the perfect RPM!
bash
$ fpm -s dir -t rpm -n shinything --config-files /etc --exclude "var/www/shinything/config*" src/=/var/www/shinything src/config/=/etc/shinythingCreated package {:path=>"shinything-1.0-1.x86_64.rpm"}
If we take a look inside this RPM using the rpm
tool, it will list everything that will be installed.
bash
$ rpm -qlp shinything-1.0-1.x86_64.rpm/etc/shinything/mappings.json/etc/shinything/targets.json/var/www/shinything/application/controller/IndexController.php/var/www/shinything/application/model/User.php/var/www/shinything/application/view/show-user.php/var/www/shinything/composer.json/var/www/shinything/composer.lock/var/www/shinything/public/index.php