I am running a web server that allows users to upload images to the server. However, I am using git to manage my source code, and the git push operation deletes anything on the server which doesn’t match my local checkout – so I lose the images every time I run git push!

At first I thought that I might be able to protect the uploads folder, so I tried all of these things as suggested in other posts:

None of these solve the issue – the remote directory always disappears when I do git push.

Next, I decided to put the uploaded files outside of git’s working area, so that git push does not delete it. Then I created a symbolic link from the public directory to the private directory so I can see the files publicly. So far so good… However, whenever I run git push it deletes the symbolic link!

Finally, I thought that perhaps I could use a post-receive git hook to create the symbolic link every time I push, but my web server (openshift) is already using that hook for something else and won’t allow me to edit it.

The OPENSHIFT_DATA_DIR persists between deploys, but is NOT shared between gears in a scaled application.

Like most Platform as a Service providers, OpenShift deploys a whole new version of your application each time you push. By default, anything not tracked by Git will not be included in the new version.

You have a couple of options:

OpenShift supports persistent data storage using a special directory:

The best practice for storing files that must persist across deployments is to use the ‘data’ directory that is located one level up from your git repository. You can use the $OPENSHIFT_DATA_DIR env variable to reference this on the host. For example:

If you create a php app called “bunny”. The repo’s php/index.php file gets deployed to:

~/{cartridge name}/repo/php/index.php

The data directory, then, gets deployed to

~/{cartridge name}/app-root/data/

Therefore from your php/index.php file, if you save a file to “../../../data/blah.txt” it will get placed outside of your repo directory into the data directory.

Store generated / uploaded assets elsewhere.

This is the approach favoured by PaaS providers like Heroku. Instead of storing user uploads and other generated content on the PaaS server, store it on something like Amazon S3.

Yes, The git repo you’re pushing to should not be a repository with a working directory. It should be a bare repository which is initiated with

git --bare init

If you still want to work on the target machine, the best solution would be to use two repositories (one bare and one not), you push to the bare, and then with a hook, pull to to normal. An example for this setup can be found here.