High-Availability Xibo CMS

Hey guys,

We’ve been successfully running Xibo in a multi-node Docker Swarm Mode cluster behind a load balancer for a few months now. Up to this point it’s only been myself and and the API connecting to the system, but just recently we began to allow more users access, and we’d like to try making the system more resilient when it comes to potential failures of the CMS.

Do you guys foresee any problems with running additional replicas of the CMS container? The entire filesystem is already mounted from NFS so they’d have the same files. My biggest concern would be session handling, but as long as that is done via cookies and the DB, I don’t think that would be a problem either.

Would love your input, thanks!

P.S. I’m not savvy enough with ZMQ to know for sure, but I assume that running replicas of XMR is off-limits. If I’m wrong, please correct me.

2 Likes

You should be OK running multiple replicas of the web container, providing as you say they are using shared storage for the library.

Sessions are handled in the database so there’s no issue there.

You may run in to issues with cache locking depending on how your NFS is setup. It’s not a configuration we run ourselves so I can’t comment how that will work in reality. You’ll have to try it and see.

For XMR to work, you’ll need all your web containers to be able to address its private port, and then all your Players to be able to see the same XMR instance’s public port.

Swarm should be able to enforce that one copy is always running somewhere, so I’d imagine that would be good enough?

XMR itself isn’t cluster aware as it’s stateless and you can just spin up another without loss.

1 Like

Hey Alex,

Thank you for your help with this. I appreciate the time and thought you put into it, and I never responded.

As an update, it seems to be working fine. Swarm spreads the services across multiple containers based on resource availability and then spins up new ones as needed. I’ll report back if I discover any issues with the configuration, but the results are encouraging.

2 Likes

I would really be interested to know how he got Xibo to run in swarm mode. According to docker documents the project needs to be at version 3.0+ to do that.

Brodkin,

Any chance you could share the details on how you got this to run in swarm mode?

Hey @Fred_Ward,

The file version is really the only thing getting in your way, and thankfully they haven’t depreciated much in terms of config options so you can probably just switch to a newer version and use the compose file as is.

That said, ours is much more customized:

version: "3.4"

services:
    xmr:
      image: xibosignage/xibo-xmr:release-0.7
      ports:
        - "9505:9505"
      deploy:
        resources:
          limits:
            memory: 50M
          reservations:
            memory: 10M
        placement:
          constraints:
            - "node.labels.purpose == general"
            - "node.labels.site == batac"
      networks:
        - xibo
    web:
      image: xibosignage/xibo-cms:release-1.8.7
      healthcheck:
        test: ["CMD", "curl", "-f", "http://localhost"]
        interval: 1m30s
        timeout: 10s
        retries: 3
        start_period: 2m
      volumes:
        - "/mnt/data/xibo/shared/cms/custom:/var/www/cms/custom"
        - "/mnt/data/xibo/shared/backup:/var/www/backup"
        - "/mnt/data/xibo/shared/cms/web/theme/custom:/var/www/cms/web/theme/custom"
        - "/mnt/data/xibo/shared/cms/library:/var/www/cms/library"
        - "/mnt/data/xibo/shared/cms/web/userscripts:/var/www/cms/web/userscripts"
      environment:
        XMR_HOST: "cms-xmr"
        CMS_SMTP_SERVER: "smtp-relay.gmail.com:587"
        CMS_SMTP_USE_TLS: "YES"
        CMS_SMTP_USE_STARTTLS: "YES"
        CMS_SMTP_REWRITE_DOMAIN: "domain.tld"
        CMS_SMTP_HOSTNAME: "domain.tld"
        CMS_SMTP_FROM_LINE_OVERRIDE: "YES"
        MYSQL_HOST: mysql_batac-master
        MYSQL_PORT: 3306
        MYSQL_DATABASE: xibo
        MYSQL_USER: xibo
        MYSQL_PASSWORD: xyz123
      ports:
        - "80"
      networks:
        - xibo
        - mysql_db
        - traefik_public
      deploy:
        replicas: 2 
        resources:
          limits:
            memory: 2G
          reservations:
            memory: 1.8G
        placement:
          constraints:
            - node.labels.site == batac
          preferences:
            - spread: node.hostname
        labels:
          - "traefik.enable=true"
          - "traefik.port=80"
          - "traefik.docker.network=traefik_public"
          - "traefik.frontend.rule=Host:xibo.chancetheater.net"
networks:
    xibo:
      driver: overlay
      ipam:
        driver: default
        config:
        - subnet: 10.30.4.0/24
    mysql_db:
      external: true
    traefik_public:
      external: true

Feel free to ask any questions!

Some of the config deals with placement and our load balancer, but there are also enhancements like the health check.

2 Likes

Thank you very much. I will run a test scenario and let you know how I come along. I am working on porting the storage for the library to a NFS share too.

The mount paths you see there are actually NFS and work like a charm. We chose to mount the NFS on the hosts rather than indivually mounting storage using the local nfs driver. It seemed to create unnecessary complexity to have each container start its own mount. Also, Swarm Mode mounts all volumes using bind mounts so if the directory cannot be mounted due to a failed host mount, it just moves to the next host.

I already have Xibo running on GCP but need High availability because we are going to have connections all over North America. Brodkin - I know you got it running with docker-swarm but is there any hope for Kubernetes? I can not find any documentation. The only thing I can come close to is Kompose.io converter, which by the way does not work. I could use any help I can get with swarm or Kubernetes.

Sorry, been away from this project for a sec… I don’t really have anything to add anyway since I’m not familiar with Kubernetes. That said, I don’t see any reason why it couldn’t work. It’s also possible to deploy a Docker stack directly to Kubernetes now, but I haven’t tried that either.

Best of luck!