I have a Django app using DgangoChannels, Djangochannelrestframework. It establishes a websocket connection with ReactJS frontend. As channel layers I use Redis like that
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": [("redis", 6379)],
},
},
}
Redis and Django runs in docker. My redis docker setup is
redis:
image: "redis:7.0.4-alpine"
command: redis-server
ports:
- "6379:6379"
networks:
- nginx_network
When I run my app on production server everything works for 5-8 hours. But after that period, if Django app trying to send a message via ws if falls with the error
ReadOnlyError at /admin/operations/operation/add/
READONLY You can't write against a read only replica.
Request Method: POST
Request URL: http://62.84.123.168/admin/operations/operation/add/
Django Version: 3.2.12
Exception Type: ReadOnlyError
Exception Value:
READONLY You can't write against a read only replica.
Exception Location: /usr/local/lib/python3.8/site-packages/channels_redis/core.py, line 673, in group_send
Python Executable: /usr/local/bin/python
Python Version: 3.8.13
Python Path:
['/opt/code',
'/usr/local/bin',
'/usr/local/lib/python38.zip',
'/usr/local/lib/python3.8',
'/usr/local/lib/python3.8/lib-dynload',
'/usr/local/lib/python3.8/site-packages']
Server time: Tue, 02 Aug 2022 08:23:18 +0300
I understand that it somehow connected with Redis replication, but no idea why if falls after period of time and how to fix it
I have the same error, the possible solution is here
Fix by adding command to docker and disable the replica-read-only config,
add this to your redis docker compose
command: redis-server --appendonly yes --replica-read-only no
then you could try to verify if the replica-read-only is disable usingredis-cli > config get replica-read-only command , if the result is no then it successful to disable.
Related
I am working on Django web application which store the data in mongoDB database. When I run the docker using the docker-compose.yml file, it open the login page and gives the CSFR token error. Following are the logs of Django container:
pymongo.errors.ServerSelectionTimeoutError: localhost:27017: [Errno 111] Connection refused, Timeout: 30s, Topology Description: <TopologyDescription id: 61ad29e66ee4fa015775e4b9, topology_type: Single, servers: [<ServerDescription ('localhost', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('localhost:27017: [Errno 111] Connection refused')>]>
[05/Dec/2021 21:13:23] "GET /dashboard/ HTTP/1.1" 500 94504
Content of docker-compose.yml file:
version: "3.7"
services:
mongodb_container:
image: mongo:latest
volumes:
- mongodb_data_container:/data/db
ports:
- 27017:27017
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- django_data_container:/home/app/webapp
ports:
- "8000:8000"
links:
- mongodb_container
depends_on:
- mongodb_container
Can anyone tell me how I can communicate the Django with mongoDB using dockers?
From the error:
pymongo.errors.ServerSelectionTimeoutError: localhost:27017
we can tell that you are trying to connect to the localhost on port 27017, but localhost will only address the django container itself. In order to connect to another container (mongodb), change the connection string or connection configuration in django settings to point to that other container's name. In your case you want to change localhost to mongodb_container.
I have a Django project that uses django-elasticsearch-dsl. The project is dockerized, so elasticsearch and the web projects leave in separate containers.
Now my goal is to recreate and repopulate the indices running
python manage.py search_index --rebuild
In order to do that, I try to run the command from the container of the web service the following way:
docker-compose exec web /bin/bash
> python manage.py search_index --rebuild
Not surprsiginly, I get an error
Failed to establish a new connection: [Errno 111] Connection refused)
apparently because python tried to connect to elasticsearch using localhost:9200.
So the question is, how do I tell the management command the host where elasticsearch lives ?
Here's my docker-compose.yml file:
version: '2'
services:
web:
build: .
restart: "no"
command: ["python3", "manage.py", "runserver", "0.0.0.0:8000"]
env_file: &envfile
- .env
environment:
- DEBUG=True
ports:
- "${DJANGO_PORT}:8000"
networks:
- deploy_network
depends_on:
- elasticsearch
- db
elasticsearch:
image: 'elasticsearch:2.4.6'
ports:
- "9200:9200"
- "9300:9300"
networks:
- deploy_network
db:
image: "postgres"
container_name: "postgres"
restart: "no"
env_file: *envfile
ports:
- "5432:5432"
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
networks:
deploy_network:
driver: bridge
UPDATE:
In the Django project's settings I setup the elasticsearch dsl host:
# settings.py
ELASTICSEARCH_DSL = {
'default': {
'hosts': 'localhost:9200'
}
}
Since your Django project and Elasticsearch are in 2 separate containers, setting ELASTICSEARCH_DSL's host to 'localhost:9200' won't work, in this case localhost refers to localhost inside Django container.
So you need to set it like this:
# settings.py
ELASTICSEARCH_DSL = {
'default': {
'hosts': 'elasticsearch:9200'
}
}
I'm currently trying to setup a Google app engine flex using a django framework with django-channels. for my current project i need a websocket, so i'm trying to reconstruct the tutorial offered on the website by Django-channels: https://channels.readthedocs.io/en/latest/tutorial/
Currently I'm stuck on adding redis to my google-app-flex instance. I followed the google documentation on setting up a redis connection - unfortunatly the example is in Flask: google doc
I assume my error is trivial, and i just need to connect django CHANNEL_LAYERS to redis proporly.
executing sudo gcloud redis instances describe <redisname> --region=us-central1 gives me following responce:
Image: "Redis Describtion"
executing sudo gcloud app describe, this responce:
I configured my app.yaml as follows:
# app.yaml
# [START runtime]
runtime: python
env: flex
entrypoint: daphne django_channels_heroku.asgi:application --port $PORT --bind 0.0.0.0
runtime_config:
python_version: 3
automatic_scaling:
min_num_instances: 1
max_num_instances: 7
# Update with Redis instance IP and port
env_variables:
REDISHOST: '<the ip in "host" from "Redis Describtion" image above>'
REDISPORT: '6379'
# Update with Redis instance network name
network:
name: default
# [END runtime]
..and in my settings.py i added this as the redis connection (which feels really wrong btw):
#settings.py
import redis
#settings.py stuff...
#connect to redis
redis_host = os.environ.get('REDISHOST', '127.0.0.1')
redis_port = int(os.environ.get('REDISPORT', 6379))
redis_client = redis.StrictRedis(host=redis_host, port=redis_port)
# Channels
ASGI_APPLICATION = "django_channels_heroku.routing.application"
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
what am i doing wrong. how do i connect to Redis using Django correctly?
here are some Links:
https://cloud.google.com/memorystore/docs/redis/connect-redis-instance-flex
Django, Redis: Where to put connection-code
Deploying Django channels app on google flex engine
How to connect to Redis instance (memorystore) from Google's Standard App Engine (Python 3.7)
https://cloud.google.com/memorystore/docs/redis/connect-redis-instance-flex
https://cloud.google.com/memorystore/docs/redis/quickstart-gcloud
My mistake is in the settings.py:
Correct version:
#settings.py
#settings stuff...
redis_host = os.environ.get('REDISHOST', '127.0.0.1')
redis_port = int(os.environ.get('REDISPORT', 6379))
#redis_client = redis.StrictRedis(host=redis_host, port=redis_port) #this is not needed
# Channels
ASGI_APPLICATION = "django_channels_heroku.routing.application"
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [(redis_host, redis_port)],
},
},
}
I'm writing the project using Django REST Framework, Django, Postgres as database and Redis as caching. I want to dockerize my project.
But Redis doesn't want to access connection.
Django settings:
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
}
}
}
docker-compose.yml:
services:
postgres:
image: postgres:latest
env_file:
- ./src/main/.env
volumes:
- ./scripts/postgres:/docker-entrypoint-initdb.d
polls:
build: .
volumes:
- .:/code
env_file:
- ./src/main/.env
ports:
- "8000:8000"
depends_on:
- postgres
- redis
command: ./scripts/wait_for_it.sh
redis:
restart: always
image: redis:3.2.0
expose:
- "6379"
When I run command to up containers there are follow warnings:
polls_cache | 1:M 15 Aug 10:47:36.719 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
polls_cache | 1:M 15 Aug 10:47:36.720 # Server started, Redis version 3.2.0
polls_cache | 1:M 15 Aug 10:47:36.720 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
polls_cache | 1:M 15 Aug 10:47:36.720 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
polls_cache | 1:M 15 Aug 10:47:36.720 * The server is now ready to accept connections on port 6379
And when I try to do GET request to the endpoint where I'm using Redis for caching there is exception:
ConnectionError at /question/top/
Error 111 connecting to 127.0.0.1:6379. Connection refused.
...
Maybe someone had a similar problem?
Change connection string to below -
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://redis:6379/',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
}
}
}
For Polls service container, 127.0.0.1 is the polls container itself. While using docker compose containers are always reachable by using their service names like redis polls postgres.
I developed an e-commerce site on my local laptop and the project uses redis and when I run the project from localhost, it works perfectly using the following
r = redis.StrictRedis(host=settings.REDIS_HOST, port=settings.REDIS_PORT, db=settings.REDIS_DB):
REDIS_HOST = 'localhost'
REDIS_PORT = 6379
REDIS_DB = 1
Now, I am trying to deploy the project to python anywhere. I have installed the redis and started the server, changed localhost to myhost.pythonanywhere.com but when I run visit the site I get the following error:
Error 111 connecting to 50.19.109.98:6379. Connection refused.
Request Method: GET
Request URL: http://myhost.pythonanywhere.com/en/4/black-garbage-t-shirt/
Django Version: 1.8.3
Exception Type: ConnectionError
Exception Value:
Error 111 connecting to 50.19.109.98:6379. Connection refused.
Exception Location: /home/dguy/dguy/venv/lib/python3.4/site-packages/redis/connection.py in connect, line 436
Python Executable: /usr/local/bin/uwsgi
Python Version: 3.4.3
Python Path:
['/var/www',
'.',
'',
'/var/www',
'/home/dguy/dguy/venv/lib/python3.4',
'/home/dguy/dguy/venv/lib/python3.4/plat-x86_64-linux-gnu',
'/home/dguy/dguy/venv/lib/python3.4/lib-dynload',
'/usr/lib/python3.4',
'/usr/lib/python3.4/plat-x86_64-linux-gnu',
'/home/dguy/dguy/venv/lib/python3.4/site-packages',
'/home/dguy/dguy',
'/home/dguy']
Server time: Wed, 17 Aug 2016 16:10:56 +0100
Can someone please help me. what are the right configuration.
Redis will not work on PythonAnywhere.