Note

AppJail and Director have evolved to perform the following steps with less effort. Please keep them up-to-date.

What Are AppJail and AppJail Director?

AppJail is a framework that provides preconfigured and self-contained applications, frameworks and software stacks, such as WordPress. Using this tool we will have a package installed inside a jail, a lightweight and isolated environment with any custom configuration our software needs. See also.

AppJail Director is a complementary tool that help us link individual jails so they can work together using an easy-to-learn YAML file. See also.

Although an optional feature, AppJail has images, a static snapshot of a jail that improves performance by only downloading the image and importing it when needed. Once an image is downloaded, it is cached until the maintainer of that image updates it. Almost all images in the centralized repository take advantage of this feature.

Why Use AppJail Director to Run WordPress?

You can simply use AppJail to install WordPress and its dependencies, such as MariaDB, but the benefit of using AppJail Director is that you have a single YAML file, which is easy for humans to read. Using this single file we can share volumes and options between jails in a much easier way. Updating them is another benefit as AppJail Director detects when you change a parameter in the file.

AppJail Director is not a replacement for AppJail, it is just a tool to create and destroy ephemeral jails in a convenient way.

Note: When using ZFS, AppJail Director will recursively remove the dataset and its references from a jail. Use a copy instead of a snapshot when using AppJail Director.

DNS

The following configuration assumes that you are using DNS. DNS is useful in these cases because we don’t need to set up static IP addresses and remember each one, we just need to follow the convention that each jail has a hostname such as <Jail Name>.<Virtual Network>.<Domain>. <Domain> is .appjail unless you have changed it and <Virtual Network> is ajnet unless you have changed it.

See AppJail#DNS for details.

Set Up WordPress

  1. Create a new directory named ./wordpress/ and cd into it:

    1
    2
    
    mkdir -p ./wordpress/
    cd ./wordpress/
    
  2. Create a file named appjail-director.yml in this folder and add the following contents. Set your passwords for the wp_db_password, mariadb_root_password, and mariadb_password arguments. The password entered for wp_db_password and mariadb_password should be the same.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    options:
      - virtualnet: ":<random> default"
      - nat:
    
    services:
      wordpress:
        makejail: gh+AppJail-makejails/wordpress
        name: wordpress
        options:
          - expose: 80
        arguments:
          - wp_db_name: wordpress
          - wp_db_user: wpuser
          - wp_db_password: 123
          - wp_db_host: mariadb.ajnet.appjail
    
      mariadb:
        makejail: gh+AppJail-makejails/mariadb
        name: mariadb
        arguments:
          - mariadb_user: wpuser
          - mariadb_password: 123
          - mariadb_database: wordpress
          - mariadb_root_password: 321
    
  3. Start your jails:

    1
    2
    3
    4
    5
    
    # appjail-director up -p wordpress
    Starting Director; project ID: wordpress; logs: /root/.local/pipx/venvs/director/director/logs/wordpress/2023-08-23_05h44m11s;
    Creating wordpress (wordpress) ... Done.
    Creating mariadb (mariadb) ... Done.
    Finished: wordpress
    

    Note: Using the -p parameter we can set the name of our project, so we can track the jails using this name.

    We already have WordPress installed, you just have to set up your admin username and password in the web interface.

  4. Volumes (optional, but recommended): We can use WordPress as a bare metal installation and it only took us a few minutes. Now we can add volumes to our WordPress installation, why?:

    • Having a separate directory for our data is much easier to move to, for example, an SSD. The rest of the data can remain on the HDD.
    • Much easier to make backups of the data. Jails in AppJail are treated as ephemeral, not literally, you can stop the jail or reboot your system and the jails will be there anyway, but what I mean by ephemeral is that you can destroy your jail and as you separate the data you have a new updated services but with the old data.

    Why not just use volumes the first time? Remember that nullfs(5) is the default volume type as it is used to mount one directory into another, so if we mount an empty directory our jail will have an empty directory as the last directory is stacked in the old directory. We could use mount_unionfs(8) but as its man page says:

    THIS FILE SYSTEM TYPE IS NOT YET FULLY SUPPORTED (READ: IT DOESN'T WORK)
    AND USING IT MAY, IN FACT, DESTROY DATA ON YOUR SYSTEM.  USE AT YOUR OWN
    RISK.
    

    Our plan is as follows: 1. stop the jails so that their services do not write data until we migrate the data from the jail to the host. 2. copy or move the data from the jail to the host. 3. configure appjail-director.yml to use volumes. 4. re-run the jails.

  5. Stop the jails:

    # appjail-director ls -p wordpress
    wordpress:
    + wordpress (wordpress)
    + mariadb (mariadb)
    # appjail-director down -p wordpress
    Starting Director; project ID: wordpress; logs: /root/.local/pipx/venvs/director/director/logs/wordpress/2023-08-23_06h15m11s;
    Stopping wordpress ... Done.
    Stopping mariadb ... Done.
    # appjail-director ls -p wordpress
    wordpress:
    - wordpress (wordpress)
    - mariadb (mariadb)
    
  6. Copy or move the data from the jail to the host:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    
    # mkdir -p ./mariadb/db/
    # mkdir -p ./mariadb/done/
    # mkdir -p ./wordpress/wp-content/
    # chown -f 88:88 ./mariadb/db/
    # chown www:www ./wordpress/wp-content/
    # appjail cmd local wordpress sh -c "mv usr/local/www/apache24/data/wp-content/* $PWD/wordpress/wp-content"
    # ls ./wordpress/wp-content/
    index.php       languages       plugins         themes          upgrade
    # appjail cmd local mariadb sh -c "mv var/db/mysql/* $PWD/mariadb/db"
    # ls ./mariadb/db/
    aria_log.00000001       ib_buffer_pool          ibdata1                 mysql                   performance_schema      wordpress
    aria_log_control        ib_logfile0             multi-master.info       mysql_upgrade_info      sys
    

    Note: As you can see, chown(8) is used to set permissions. This step is important because mount_nullfs(8) mounts the directories as is.

  7. Configure appjail-director.yml:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    
    options:
      - virtualnet: ":<random> default"
      - nat:
    
    services:
      wordpress:
        makejail: gh+AppJail-makejails/wordpress
        name: wordpress
        options:
          - expose: 80
        arguments:
          - wp_db_name: wordpress
          - wp_db_user: wpuser
          - wp_db_password: 123
          - wp_db_host: mariadb.ajnet.appjail
        volumes:
          - wp-content: /usr/local/www/apache24/data/wp-content
    
      mariadb:
        makejail: gh+AppJail-makejails/mariadb
        name: mariadb
        arguments:
          - mariadb_user: wpuser
          - mariadb_password: 123
          - mariadb_database: wordpress
          - mariadb_root_password: 321
        volumes:
          - db: /var/db/mysql
          - db-done: /.mariadb-done
    
    volumes:
      wp-content:
        device: ./wordpress/wp-content
      db:
        device: ./mariadb/db
      db-done:
        device: ./mariadb/done
        options: ro
    

    As you can see, there is an empty directory named ./mariadb/done/. The purpose of this directory is to tell Makejail scripts not to reconfigure MariaDB. If we reconfigure MariaDB with old databases, the installation will fail because it probably has a password that the scripts do not know.

  8. Re-run the jails:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    # appjail-director up -p wordpress
    Starting Director; project ID: wordpress; logs: /root/.local/pipx/venvs/director/director/logs/wordpress/2023-08-23_13h34m57s;
    Stopping wordpress ... Done.
    Destroying wordpress ... Done.
    Stopping mariadb ... Done.
    Destroying mariadb ... Done.
    Creating wordpress (wordpress) ... Done.
    Creating mariadb (mariadb) ... Done.
    Finished: wordpress
    

Afterword

As you can see, it’s much easier to create jails this way and it only takes a few minutes to deploy a WordPress installation with MariaDB.

If you find this article or the projects useful, please contribute to them: