# Creating a portable Jail template



## Antonio Modesto (Jun 25, 2018)

Hello folks,

We use FreeBSD to host our web application, for every new client that wants our product we must install a new instance for them. Usually they install the base system and just give us access so that we can finish the deployment. I was wondering if it is possible to create a Jail with all the packages we need and just use it as a template for new deployments. The problem is that I'm not sure if the jail would work correctly after being migrated to different machines, even though they have the same FreeBSD version installed.

Does someone use something similar? Thanks.


----------



## ucomp (Jul 4, 2018)

your question is very interesting because I suspect that  many people are confused by
1. jails
2. Software-Distribution
and
3.the Tux-Docker ...

Number 1. / jails is for security,
Number 3. / 'Tux' is for virtualization ,
... so we are 'hanging' at Number 2  ....
this is what you really want:
Distribute your preconfigured FreeBsd - Service-applications .



Antonio Modesto said:


> they install the base system



good idea  , tell them to create a new zfs-volume ( 1-liner)
let's call it step 1



Antonio Modesto said:


> with all the packages we need and just use it as a template for new deployments



good idea  , create a zfs-volume with all your packages

let's call it Step 2



Antonio Modesto said:


> I'm not sure if .....would work correctly after being migrated to different machines, even though they have the same FreeBSD version installed.



But I'm sure  it will work if you use the zfs send | recv - mechanism ,
let`s call it Step 3 :

send your volume to the user`s volume ( via ssh)
or vice versa :
let the user recv your volume .   ( via ssh)

( you can even set up the new Volume on your users machine as the boot volume  )


Enjoy your new distribution-service and extend it with your own ideas, if needed... !


----------



## ShelLuser (Jul 4, 2018)

Antonio Modesto said:


> I was wondering if it is possible to create a Jail with all the packages we need and just use it as a template for new deployments.


I don't see why not. See, keep well in mind that a Jail isn't some magical virtual environment, it's merely a new installation of the base system of which you made your own system aware so that it would spawn a new kernel thread to accommodate for that new system.

Even the FreeBSD base system itself isn't something special where installation is concerned. Did you know that installing a FreeBSD base system basically boils down to unpacking base.txz and kernel.txz?

For example, this is the heart of my Jail environments:

```
peter@zefiris:/opt/jails $ ls
base.txz        kernel.txz      lib32.txz       psi/
```
... well, this and a few shell scripts which perform the actual process of unpacking and applying the necessary changes to certain system files such as /etc/rc.conf of course. That's all there is to it.

So... if you install ports what happens with those? They get installed to /usr/local. So it should be relatively easy to simply archive that stuff and then use that as template.

Unless of course you're doing the right thing and you keep your system up to date and also upgrade the ports when there's a need. In that case my recommendation would be to build your own package repository. Look into pkg-repo(8) to see how to start doing that.

It's really very easy...  Basically all you need is a huge collection of packages. You can easily collect those yourself; either by checking your cache if you're already using `pkg install` (see /var/db/pkg, this is the original location) or by creating packages yourself, for example from your currently installed packages. You can do that using the pkg-create(8) command. Once you have a huge collection you'll need to create an index so that remote clients can quickly look up the stuff they need. That is where pkg-repo comes into play.

For example... If you wanted to create a repository from your currently installed packages?


```
# pkg create -ao /var/db/myrepo/All
# pkg repo /var/db/myrepo
```

Once you have this setup all you have to do next is to make sure that your new jail is aware of this new repository (create a config file based on /etc/pkg/FreeBSD.conf and dump that into /usr/local/etc/pkg/repos). After that there's only 1 thing left to do: running `pkg install` to quickly install the required Ports.

Depending on how your application is set up you could even use this methodology to distribute that application itself as well. pkg-create is also perfectly capable of creating a package based on an existing directory structure.



Antonio Modesto said:


> The problem is that I'm not sure if the jail would work correctly after being migrated to different machines, even though they have the same FreeBSD version installed.


I don't see why it wouldn't. A Jail isn't some kind of virtual machine running 'on top' of your OS. It's basically a new kernel thread which has been instructed to spawn a new instance based on the userland found in your Jail root. And a little bit more of course but what I'm getting at is that a Jail isn't comparable to, say, VirtualBox.


----------



## sko (Jul 4, 2018)

Instead of manually packing lots and lots of boilerplate (e.g. all the base system), and potentially outdated packages; I'd highly recommend using some proper configuration management like e.g. Ansible.
Ansible can be used to set up the jail host; set up the jail(s) and then set up your application within a/multiple jail(s). By separating these tasks it's much easier to maintain, test, scale and evolve/develop the whole stack and you are always using the current version of packages and the base system.
With Ansible you basically just write the recipe for what you are now doing manually every time: installing packages, modifying/replacing config files etc. If you use modules to e.g. abstract the package installation its also relatively easy to port the application (or parts of it) to another platform: E.g. I've used the same playbooks to deploy nameservers in jails and on smartOS zones (although it was more of a proof-of-concept and isn't used any more for several reasons)

I've recently discovered that ansible can also be easily combined with the CI/CD feature in gitlab, which is amazing for automated testing and deployment.
I'm currently testing with this to to roll out zone configuration for our local DHCP- and nameservers and configs for our cisco switches when adding new clients to the network. If something gets pushed into the repo(s), gitlab runs a worker that fires ansible which grabs the new config from the repo and installs it on the switch or pulls it to the DHCP-/nameserver and issues a service restart or `rndc reload`. Still pretty basic but already extremely useful.


----------

