Connecting upstash redis to my django prject

I’m pretty new to fly, this is my first project, and I’m having trouble connecting redis to my already deployed and fucntional app. I use redis to manage chat messages for my site, and it works fine locally. When I follow the instructions linked here: Upstash for Redis®* · Fly Docs
I am warned that I do not have redis-cli installed in my path. I do have redis-cli in my dependencies, and it works locally, so i’m not sure how to solve that. It also provides me with a link that should allow my app to access the database, which may or may not require redus-cli, but I have no odea where to put it. In short, I really don’t know what I’m doing, and I can’t find any documentation that explains how I can fix these errors. Happy to paste any and all files you guys need to see, just let me know, or any general advice would be great. Thanks a ton for reading this far, and I would appreciate any help you can give me. Thanks!

Are you trying to run fly redis connect from within the Fly Machine? E.g. are you doing something like fly ssh console then running fly redis connect in the new console?

Could you share the dependencies file you’re referring to here?

This is usually a sign that dependencies are misconfigured, so I think let’s rule that out first.

This depends on your app. How do you configure your app to use your local Redis instance when developing locally?

Here’s my requirements.txt:
asgiref==3.6.0

async-timeout==4.0.2

attrs==22.2.0

autobahn==22.12.1

Automat==22.10.0

backports.zoneinfo==0.2.1

cffi==1.15.1

channels==4.0.0

channels-redis==4.0.0

constantly==15.1.0

cryptography==38.0.4

daphne==4.0.0

dj-database-url==2.1.0

Django==4.1.4

django-ipware==5.0.0

django-utils==0.0.2

environs==9.5.0

gunicorn==21.2.0

hyperlink==21.0.0

idna==3.4

incremental==22.10.0

marshmallow==3.20.1

msgpack==1.0.4

packaging==23.2

pyasn1==0.4.8

pyasn1-modules==0.2.8

pycparser==2.21

pyOpenSSL==22.1.0

pyscopg2==66.0.2

python-dotenv==1.0.0

redis==4.4.0

redis-cli==1.0.1

service-identity==21.1.0

six==1.16.0

sqlparse==0.4.3

Twisted==22.10.0

txaio==22.2.1

typing_extensions==4.2.0

tzdata==2022.7

whitenoise==6.5.0

zope.interface==5.5.2

And here’s my settings.py, where I configured redis:

“”"
Django settings for mysite project.

Generated by ‘django-admin startproject’ using Django 4.1.4.

For more information on this file, see

For the full list of settings and their values, see

“”"

from pathlib import Path
from environs import Env

env = Env()
env.read_env()

Build paths inside the project like this: BASE_DIR / ‘subdir’.

BASE_DIR = Path(file).resolve().parent.parent

Quick-start development settings - unsuitable for production

See Deployment checklist | Django documentation | Django

SECURITY WARNING: keep the secret key used in production secret!

SECRET_KEY = ‘django-insecure-c03xfc_y^u(z%ds-b0ds0&g3sr!gwj1k0bmg#dsca7mn!is4k8’
‘’’
SECRET_KEY = env.str(
“SECRET_KEY”,
default=“gOQawfblQWnGbA0DxfhVg6iiE8HCf3u8MTHr9PmHiXzb85fCsW”,
)
‘’’

SECRET_KEY = django.core.management.utils.get_random_secret_key()

SECURITY WARNING: don’t run with debug turned on in production!

DEBUG = False

#ALLOWED_HOSTS = [‘localhost’, ‘127.0.0.1’, ‘192.168.1.254’]
ALLOWED_HOSTS = ['']
CSRF_TRUSTED_ORIGINS = ["https://
.fly.dev",“https://discuss-it.net”]

Application definition

INSTALLED_APPS = [
‘daphne’,
‘chat’,
‘core’,
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘whitenoise.runserver_nostatic’,
‘django.contrib.staticfiles’,
]

MIDDLEWARE = [
‘django.middleware.security.SecurityMiddleware’,
‘whitenoise.middleware.WhiteNoiseMiddleware’,
‘django.contrib.sessions.middleware.SessionMiddleware’,
“whitenoise.middleware.WhiteNoiseMiddleware”,
‘django.middleware.common.CommonMiddleware’,
‘django.middleware.csrf.CsrfViewMiddleware’,
‘django.contrib.auth.middleware.AuthenticationMiddleware’,
‘django.contrib.messages.middleware.MessageMiddleware’,
‘django.middleware.clickjacking.XFrameOptionsMiddleware’,
]

ROOT_URLCONF = ‘mysite.urls’

TEMPLATES = [
{
‘BACKEND’: ‘django.template.backends.django.DjangoTemplates’,
‘DIRS’: ,
‘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’,
],
},
},
]

WSGI_APPLICATION = ‘mysite.wsgi.application’

Database

Settings | Django documentation | Django

‘’‘DATABASES = {
‘default’: {
‘ENGINE’: ‘django.db.backends.sqlite3’,
‘NAME’: BASE_DIR / ‘db.sqlite3’,
}
}
‘’’

DATABASES = {
“default”: env.dj_db_url(“DATABASE_URL”, default=“sqlite:///db.sqlite3”),
}

Password validation

Settings | Django documentation | Django

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

Internationalization and localization | Django documentation | Django

LANGUAGE_CODE = ‘en-us’

TIME_ZONE = ‘UTC’

USE_I18N = True

USE_TZ = True

Static files (CSS, JavaScript, Images)

How to manage static files (e.g. images, JavaScript, CSS) | Django documentation | Django

STATIC_ROOT = BASE_DIR / ‘staticfiles’
STATIC_URL = ‘static/’
STATICFILES_STORAGE = “whitenoise.storage.CompressedManifestStaticFilesStorage”
LOGIN_REDIRECT_URL = ‘/’
LOGOUT_REDIRECT_URL = ‘/login/’

Default primary key field type

Settings | Django documentation | Django

DEFAULT_AUTO_FIELD = ‘django.db.models.BigAutoField’

ASGI_APPLICATION = “mysite.asgi.application”

CHANNEL_LAYERS = {
“default”: {
“BACKEND”: “channels_redis.core.RedisChannelLayer”,
“CONFIG”: {
“hosts”: [(“127.0.0.1”, 6379)],
},
},
}

No, I’m running fly redis connect straight from the powershell. Where would I need to have redis-cli installed for that to work?

Ok, as far as getting your Upstash Redis to work with your deployed app, the problem is above. hosts is configured to talk to 127.0.0.1 (which is commonly referred to as localhost). But your Upstash Redis instance is not on localhost.

Run fly redis list to find the name of your Redis instance, e.g. mine was aged-forest-2800. Then do fly redis status aged-forest-2800, replacing aged-forest-2800 for your own instance name. This should show you a line that looks like:

Private URL    = redis://default:2bad98a37c2e43d687455fc7bdf16d89@fly-aged-forest-2800.upstash.io:6379

I’ve very briefly scanned these docs, so take what follows with a grain of salt (e.g. it may be insecure, amongst other things), but it looks like you want your config to be along the lines of:

CHANNEL_LAYERS = {
    "default": {
        "BACKEND": "channels_redis.core.RedisChannelLayer",
        "CONFIG": {
            "hosts": ["redis://default:2bad98a37c2e43d687455fc7bdf16d89@fly-aged-forest-2800.upstash.io:6379"],
        },
    },
}

but using the private URL for your own Redis.

WARNING: I don’t recommend putting secrets like this private URL in a settings file that you’re going to commit to git. Instead, the recommendation is to load these settings from an environment variable. I’d suggest taking a look at the docs on secrets.

Are you using WSL? If you’ve installed Redis but you’re getting an error saying redis-cli can’t be found, you just need to locate it and put it in your PATH.

ok, how do I do that? I have used WSL for my local redis_CLI, but I’m not super familair with it.

Hmm okay I’m not super familiar with Windows so bear with me and let me know if anything below doesn’t make sense or you have issues.

The instructions for installing Redis on Windows say that you can’t install Redis directly in Windows and instead detail installing it within a Linux environment that you setup using WSL2.

The consequence of this is that if you’re trying to fly redis connect from Powershell, then redis-cli doesn’t exist because it wasn’t installed in your Windows environment, it was installed in your Linux (WSL) environment.

So you need to be in your linux environment, install flyctl there, and then hopefully fly redis connect should work, because it’ll use the redis-cli that you already have installed.

That makes a lot of sense. Will fly on WSL still have access to my account, or do I need to relaunch and redeploy from WSL?

Once you’ve downloaded, you’ll need to fly auth login, but you don’t need to relaunch or redeploy. Launching is basically a thing you do once to create an app and deploy it all in a single command. Deploying is something you do if you need to update app config (fly.toml), update the image, etc.

After you’ve logged in, you should be able to immediately fly redis connect.

Thanks so much! I got fly and redis set up on WSL, and I’m at least getting a different error message. When I go to try to chat on my site, it tells me that my websocket connection failed. I’m assuming this is still redis, because it worked fine locally, so I’m wondering if I’m not letting it access the right port. Do I need something in fly.toml to configure a redis port?

What’s the error message?

Did you modify your settings.py file as I suggested here?

If you can paste the error message you’re getting, that’d be useful in determining the problem.

There’s no error message in the logs, but Inspect Element on chrome shows me this message: “4682/:142 WebSocket connection to ‘wss://discuss-it.fly.dev/wss/chat/4682/’ failed:”
I followed your instructions for settings.py, using the url that I got from the powershell.

Hmm this looks unrelated to Redis - how are you using websockets in the app and have you configured your fly.toml appropriately?

These links might be useful:

I am using django channels for my websocket connection. I haven’t changed anything in my fly.toml. Is there a way you know of to check what port my websocket is on and tell fly.toml to listen on that port? I suspect that may be the issue, but I haven’t found much on how to see what port a websocket is listening on.

Could you share your fly.toml here? Redact anything sensitive!

Here you go:

fly.toml app configuration file generated for discuss-it on 2023-12-16T12:27:14-05:00

See Fly Launch configuration (fly.toml) · Fly Docs for information about how to use this file.

app = “discuss-it”
primary_region = “bos”
console_command = “/code/manage.py shell”

[build]

[mounts]
source=“data”
destination=“/data”

[env]
PORT = “8000”

[http_service]
internal_port = 8000
force_https = true
auto_stop_machines = true
auto_start_machines = true
min_machines_running = 0
processes = [“app”]

[[vm]]
cpu_kind = “shared”
cpus = 1
memory_mb = 1024

[[statics]]
guest_path = “/code/static”
url_prefix = “/static/”

Ok, I figured it out. Writing this here in case anyone else is trying to do what I am. If you use django channels with daphne, replace the CMD line in your dockerfile with “CMD [“python3”, “manage.py”, “runserver”, “0.0.0.0:8000”]” to make websockets work. Chat works great now. Thanks for all your help jfent!