Adding or changing files in Fleio Docker images

General principles

For a general overview of the Docker deployment, see Fleio Docker deployment notes first.

A Fleio customization process should meet the following requirements:

  1. Keep in mind that Docker containers are immutable and stateless. The static image of each of the Fleio services is downloaded from hub.fleio.com and this image is not changed at all during runtime. Setting files are placed in Docker volumes, state information is kept in the MariaDB database logs are output by containers to the console.

    While you can make some quick and TEMPORARY files changes if you are in a development environment, editing files directly into the container goes completely against the Docker philosophy. Your changes may be lost or overwritten on a Fleio upgrade.

  2. Have a customization process that is upgrade-proof. That is, your changes will not be overwritten on Fleio upgrades.

  3. Apply the customizations automatically when you run fleio upgrade.

  4. Have a simple process that is self documented and can be copied and run in multiple environments, allowing you to test your customization in a staging environment before applying it in production.

Testing your custom code in a lab environment before upgrading your production environment is highly recommended.

Your Docker deployment contains the Docker Compose configuration files in the /home/fleio/compose path.

The /home/fleio/compose/docker-compose.yml defines the services that form your Fleio installation. You must not modify this file as it is sometimes overwritten on Fleio upgrades and your changes will be silently lost.

It is recommended instead that you add your customizations to /home/fleio/compose/docker-compose.override.yml. This is included automatically when you use the fleio command and when you run docker compose commands while in the /home/fleio/compose directory. (The .env file sets this variable for this: COMPOSE_FILE=docker-compose.yml:docker-compose.override.yml.)

Example: Change favicon, add custom CSS and Google Analytics

Let’s take an example that:

  1. Change the favicon

  2. Inserts your Google Analytics code

  3. Adds a custom .css file

Warning

You should create and edit the following files as fleio user. This ensures that no file permission issue later occurs. If you want to know more about file permissions in a Docker deployment, see Docker installation file permissions.

You should switch to fleio user before continuing:

sudo -i -u fleio

Add this to your /home/fleio/compose/docker-compose.override.yml:

# Add here your Docker Compose customizations
# docker-compose.override.yml is not overwritten by Fleio
# (while docker-compose.yml may be OVERWRITTEN on Fleio upgrades)

services:
  frontend:
    build:
      context: ./custom/
      dockerfile: Dockerfile
      args:
        - FLEIO_DOCKER_HUB
        - FLEIO_RELEASE_SUFFIX
    image: fleio_frontend_custom
    pull_policy: never

What happens here:

  • You’re partially redefining the frontend service. Adding a build section with a specific context path and Dockerfile. (we’re creating the file below)

  • Some arguments, defined in .env are made available to the build process.

  • You’re setting a new, custom name, for the image we’re building, to overwrite the default image used by frontend in the base docker-compose.yml file.

  • pull_policy is needed to prevent docker compose pull for attempting to pull the custom image. The base image used in Dockerfile will be pulled during build.

Create two new files to add your customization:

  • /home/fleio/compose/custom/custom.css - just add /* mine */ in it if you’re just testing things out, or add whatever custom CSS code you want.

  • /home/fleio/compose/custom/Dockerfile

Copy your favicon in /home/fleio/compose/custom/favicon.ico.

And add this code to the Dockerfile:

# define the build arguments that are used below to reference the base Docker frontend image
ARG FLEIO_DOCKER_HUB
ARG FLEIO_RELEASE_SUFFIX

FROM ${FLEIO_DOCKER_HUB}/fleio_frontend${FLEIO_RELEASE_SUFFIX}

# we're defining the Fleio installation path in one place and we're using it below
ENV INSTALL_PATH="/var/webapps/fleio"

# copy the favicon
COPY favicon.ico "$INSTALL_PATH/frontend/enduser/favicon.ico"
COPY favicon.ico "$INSTALL_PATH/frontend/staff/favicon.ico"

# copy the custom css file
COPY custom.css "$INSTALL_PATH/frontend/enduser/custom.css"

# insert the custom.css reference before the </head> closing tag
# note that we're using the "^" character as delimiter for sed utility
RUN sed -i \
  's^<head>^<head><link rel="stylesheet" type="text/css" \
  href="/custom.css" \ media="screen"/>^' \
  "$INSTALL_PATH/frontend/enduser/index.html"

# add your Google analytics code

RUN sed -i \
's^<head>^<head><!-- Global site tag (gtag.js) - Google Analytics --> \
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-61451897-1"></script> \
<script> \
  window.dataLayer = window.dataLayer || []; \
  function gtag(){dataLayer.push(arguments);} \
  gtag('js', new Date()); \
  gtag('config', 'UA-XXXXXXXX-1'); \
</script>^' \
"$INSTALL_PATH/frontend/enduser/index.html"

Just build and apply your customizations to the already running Fleio instance:

# make sure you're in the directory where Docker Compose files are
cd /home/fleio/compose

# build your image
docker compose build

# apply your changes to the running frontend
docker compose up -d

Now you should be able to see your changes in the http://fleio-url/ (in the HTML source) and you should be able to see your CSS customization at http://fleio-url/custom.css.

Example: add Python files

Let’s take an example and see how you can add some files to the standard Fleio image and also make sure that your files are not lost on Fleio upgrades.

We’ll create a Django command that outputs the number of active clients in your Fleio database.

For this, we’re customizing the backend image and Docker Compose service.

Warning

You should create and edit the following files as fleio user. This ensures that no file permission issue later occurs. If you want to know more about file permissions in a Docker deployment, see Docker installation file permissions.

You should switch to fleio user before continuing:

sudo -i -u fleio

Add this to your /home/fleio/compose/docker-compose.override.yml file:

# Add here your Docker compose customizations
# docker-compose.override.yml is not overwritten by Fleio
# (while docker-compose.yml may be OVERWRITTEN on Fleio upgrades)

services:
  backend:
    build:
      context: ./custombackend/
      dockerfile: Dockerfile
      args:
        - FLEIO_DOCKER_HUB
        - FLEIO_RELEASE_SUFFIX
    image: fleio_custom_backend
    pull_policy: never

The docker-compose.override.yml file overrides directives from docker-compose.yml (which you should never change as it is overwritten on Fleio upgrade).

The backend service now has a build directive which uses the files ./custombackend/ on build and the image build is defined in ./custombackend/Dockerfile.

pull_policy is needed to prevent docker compose pull for attempting to pull the custom image. The base image used in Dockerfile will be pulled during build.

Create directory /home/fleio/compose/custombackend (don’t forget to create this and the following files as user fleio).

Add this to /home/fleio/compose/custombackend/Dockerfile

# define the build arguments that are used below to reference the base Docker frontend image
ARG FLEIO_DOCKER_HUB
ARG FLEIO_RELEASE_SUFFIX

FROM ${FLEIO_DOCKER_HUB}/fleio_backend${FLEIO_RELEASE_SUFFIX}

# we're defining the Fleio installation path in one place and we're using it below
ENV INSTALL_PATH="/var/webapps/fleio"


COPY --chown=fleio:fleio clientcnt.py "$INSTALL_PATH/project/fleio/core/management/commands/clientcnt.py"

COPY --chown=fleio:fleio clientcnt "$INSTALL_PATH/scripts/clientcnt"

RUN chmod +x "$INSTALL_PATH/scripts/clientcnt"

Create /home/fleio/compose/custombackend/clientcnt.py with content:

from django.core.management.base import BaseCommand

from fleio.core.models import Client


class Command(BaseCommand):
    help = 'Shows number of active clients'

    def handle(self, *args, **options):
        print(Client.objects.filter(status='active').count())  # noqa

Create /home/fleio/compose/custombackend/clientcnt with content:

#!/bin/bash

source /var/webapps/fleio/env/bin/activate
cd /var/webapps/fleio/project
django clientcnt

Build your new image and make sure the running backend container reloads:

cd /home/fleio/compose
docker compose build && docker compose up -d

Now you can run your new script inside the already running backend service:

docker exec -it fleio-backend-1 /var/webapps/fleio/scripts/clientcnt

And you get the number of active clients in your database, e.g.

9341

Note

In this example we’re adding files, but you can also change existing files. See Example: Change favicon, add custom CSS and Google Analytics

Obviously you can run a simple SQL query on the Fleio database to get the number of active clients. We’re just using this as an example. But here’s how you’d do it with a simple SQL query ran in the database container:

  1. Get the MariaDB password by running:

sudo cat /home/fleio/compose/secrets/.db_password
  1. Copy the password and use it in this command:

docker exec -it fleio-db-1 mysql -ufleio -p"<<PASSWORD HERE>>" fleio -e "SELECT COUNT(id) FROM core_client WHERE status='active';"

It will output something similar to:

+-----------+
| COUNT(id) |
+-----------+
|      9341 |
+-----------+

How to customize web config

See Web server configuration and customization.