Дело было не в .gitignore и не в git вообще. Проблема была в непонимании механизма деплоя приложений на OpenShift. Каждый раз, когда исполняется команда
git push сервис подчищает папку с репозиторием и разворачивает все заново. Как я понял, для Heroku, это тоже справедливо. Но есть папка app-root/data, которая не удаляется при деплое, туда и нужно складывать медиа файлы, которые грузятся через админку или пользователями приложения.
Чтобы избежать потери файлов поправил
settings.py таким образом:
# Media files
if ON_OPENSHIFT:
MEDIA_ROOT = os.path.join(os.environ['OPENSHIFT_DATA_DIR'], 'media')
MEDIA_URL = '/media/'
else:
MEDIA_ROOT = os.path.join(BASE_DIR, '..', 'media')
MEDIA_URL = '/media/'
Путь до app-root/data как раз содержится в системной переменной OPENSHIFT_DATA_DIR