Stateful PHP app?

Hi,

my php application is stateful, meaning that the state of the whole app (files) should be saved somehow.
Basically, my app allows users to change some specific files so they can customize the look/feel (html) as per their needs, it also generates some additional files that are required for the app to work properly.

This means that if i use the container/image to deploy nodes in a kubernetes cluster all changes will be lost in case it restarts or a new pod gets deployed for higher availability.

What are the solutions for such cases?

Hello,

HTTP is by default a stateless protocol.
You can add some ā€œstatefulnessā€ (at least it feels this way) by using session-cookies so that the application can create a response that feels stateful.
Storing data within a container is not a good idea for persistence (as you already mentioned).
And if you add new application-pods they (by default) do know nothing about a session created by another application-pod.
So an idea is to store session-data on a single database-instance (could be redis or something similar - keep in mind to store persistent data in a docker-volume) used by all application-pods so that every pod is aware of session-information created/modified by another pod.

Or you can store all information needed to be stateful in a cookie stored on the client or in HTML5-client-side storage.

Hi, unfortunately these solutions do not solve my problem.

A good example is a wordpress site. WP allows the admin to add new plugins (new php,image,csv,xml etc. files), change existing files (css/html for example) etc.

If i initialize a pod with a container all these changes/additions will be lost.

How do you keep the new state of these files? My application also allows the user to create/modify files.

The answer is there in the post of @matthiasradde

Of course, creating a volume in a Kubernetes cluster is harder than doing it on a single machine. You need a network filesystem or your application needs to replicate itā€™s data across multiple nodes running multiple pod instance. This is what databases are doing. Your Wordpress will not do it. Here is some idea what you can use:

  • NFS volume: probably the easiest to configure, but you can have problems with file locking, NFS will be a single point of failure if the NFS server stops or becomes slow while your appliation is still running. And you will not have data redundancy by default (I heard some ways to do it, but there are better ways)
  • GlusterFS: Similar to NFS, but you can configure multiple server to replicate your data and have multiple servers to connect to in case one of them stops or you need to update them one by one.
  • Ceph: You will find it when you are searching for volumes for Kubernetes, but it is very much harder to configure and it is mainly for much larger amount of data than your wordpress will ever need.
  • Cloud storage: You can also buy some storage from a cloud povider like Amazon S3 In this case you need to handle the S3 API or mount the volume on your nodes. I donā€™t know if Kubernetes has a volume plugin for that. Of course S3 is not the only way, but I havenā€™t used any cloud storage yet.

For your use case, I think the best would be either NFS or GlusterFS, but I would recommend GlusterFS. Here is a good GlusterFS tutorial which I tried: How To Create a Redundant Storage Pool Using GlusterFS on Ubuntu 20.04 | DigitalOcean

Update:

When I last used Wordpress in a container, it was very hard to configure the volumes, because Wordpress had multiple writable folders. I ended up with using the whole wordpress on a volume and I used Docker only to run the application.

1 Like

Hello,

Thanks for the detailed reply. When you used wp on a volume did you encounter any issues?

My only issue was that I could not easily update it since even if I started the container from a new image, my entire Wordpress came from the old volume and I could not remove that volume without loosing my data. I am sure there would have been a better way to do it and it was years ago, so the current Worpdress could be better. Usually when I need to use volumes, I create my own image where I change some folders replacing them with symbolic links so I can have one data volume instead of multiple volumes for each plugin. I donā€™t remember why I could not do it with WordPress, so try to find out if the current Wordpress can be used more easily in a container. You can start here: https://hub.docker.com/_/wordpress, but it puts the whole document root to a volume.

Here is an other way from bitnami: https://hub.docker.com/r/bitnami/wordpress/

Bitnami has many good solutions and often better than the official.

Use S3 or some other persistent storage inside your docker image to hold the app config directory.