Reputation: 4008
I've a Django APP hosted on Heroku.
I upload some images within the admin panel, so the show in my site. First minutes/hours after upload they show fine.
However, after a few hours they don't show anymore. I've to upload them again within the admin panel for them to show correctly.
When in the HTML when no image appear:
<img class="my_image_medium" src="/media/category/Artboard_1_PNG.png" alt="Stickers">
HTML with image re-uploaded:
<img class="my_image_medium" src="/media/category/Artboard_1_PNG.png" alt="Stickers">
Django APP Settings:
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '^_67&#r+(c+%pu&n+a%&dmxql^i^_$0f69)mnhf@)zq-rbxe9z'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['127.0.0.1', 'stickers-gallito-app.herokuapp.com',
'stickersgallito.pe', 'www.stickersgallito.pe']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'shop',
'search_app',
'cart',
'stripe',
'order',
'crispy_forms',
'embed_video',
]
MIDDLEWARE = [
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'stickers_gallito.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates'),
os.path.join(BASE_DIR, 'shop', 'templates/'),
os.path.join(BASE_DIR, 'search_app', 'templates/'),
os.path.join(BASE_DIR, 'cart', 'templates/'),
os.path.join(BASE_DIR, 'order', 'templates/'),]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'shop.context_processor.menu_links',
'shop.context_processor.has_shop',
# 'cart.context_processor.current_time',
'cart.context_processor.cart_items_counter'
],
},
},
]
WSGI_APPLICATION = 'stickers_gallito.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases
DATABASES = {
'default': {
# 'ENGINE': 'django.db.backends.sqlite3',
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'd39a83vqn3afdj',
'USER': 'u9qchlpdl8pbao',
'PASSWORD': 'pcf1d926adfd169634371480b03c270d7da7b9033c81210482571f1a8d0ad689b',
'HOST': 'ec2-3-93-140-235.compute-1.amazonaws.com',
'PORT': '5432',
# 'OPTIONS': {
# 'sslmodule': 'required'
# }
}
}
# add this
# import dj_database_url
# db_from_env = dj_database_url.config()
# DATABASES['default'].update(db_from_env)
# Password validation
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.1/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.1/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
# STATICFILES_STORAGE = 'whitenoise.django.GzipManifestStaticFilesStorage'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static', 'media')
CRISPY_TEMPLATE_PACK = 'bootstrap4'
### Culqui Settings ###
CULQI_PUBLISHABLE_KEY = 'pk_test_d4d1nYriXvMV0YKk'
CULQI_SECRET_KEY = 'sk_test_sOlYqSB5PDAkwQuZ'
Upvotes: 0
Views: 2418
Reputation: 1582
This is because heroku nodes are not persistent. Meaning everytime your free node shuts down, it actually gets deleted and a new instance gets started when you access your application again.
The solution is actually to use some other hoster to store your media files. Amazon S3 or a simple FTP Server for example.
Check these links for further information:
Using AWS S3 to Store Static Assets and File Uploads
Heroku Help: Why are my file uploads missing/deleted?
Upvotes: 3
Reputation: 599788
You are storing your uploaded images on the local filesystem. You cannot do that in Heroku.
Heroku instances are ephemeral, and do not share filesystems between them. Whenever you deploy, or launch a new instance by scaling up, it will not have any of your uploaded files.
You must store them somewhere more permanent. S3 is a good choice; there are plenty of third-party Django file storage libraries available that will do this for you.
Upvotes: 6