Home > front end >  Connecting Django on Ubuntu EC2 to AWS RDS MySQL: pymysql tries to connect to localhost instead of f
Connecting Django on Ubuntu EC2 to AWS RDS MySQL: pymysql tries to connect to localhost instead of f

Time:07-02

I am in the process of deploying a Django project on an Ubuntu EC2. It should connect to a MySQL server on AWS RDS. The project works fine on the built-in Django development server you start with runserver and it also connects to the RDS instance properly there. However, if I try running it in production, it throws a 500 Internal Server Error that creates the following output in the error log:

mod_wsgi (pid=18656): Exception occurred processing WSGI script '/home/ubuntu/mysite/mysite/wsgi.py'.
Traceback (most recent call last):
File "/home/ubuntu/mysite/mysite_venv/lib/python3.8/site-packages/pymysql/connections.py", line 613, in connect 
  sock = socket.create_connection(
File "/usr/lib/python3.8/socket.py", line 808, in create_connection
  raise err
File "/usr/lib/python3.8/socket.py", line 796, in create_connection
  sock.connect(sa)
ConnectionRefusedError: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

...
pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' ([Errno 111] Connection refused)")

This socket error occurs both with my custom views and with the mydomain.com/admin view. The relevant snippet of views.py looks like this:

# get environment variables
db_host = os.environ.get('DB_HOST')
db_user = os.environ.get('DB_USER')
db_pass = os.environ.get('DB_PASS')

# connect to db
conn = pymysql.connect(host=db_host,
                   user=db_user,
                   password=db_pass)

c = conn.cursor()
c.execute('''USE mysitedatabase''')

The file is generally executed properly, log statements I inserted as a test before the database connection are created without errors. I have already tried removing all inbound traffic rules from my RDS security group, setting it to all IPv4 traffic with 0.0.0.0/0 but the error persisted. I assume that the socket error and the localhost error are connected since I don’t think it would make sense to connect via a unix socket when not being on localhost.

How do I stop pymysql from trying to connect on localhost when it should connect to RDS?

I use Ubuntu 20.04, Django 4.0, Apache/2.4.41 (Ubuntu) and Python 3.8.

CodePudding user response:

The environment variables were not configured in production, thank you @Mark B for pointing me in the right direction. There are multiple ways of going about this. I decided to take an easy route and add the database credentials to settings.py like so:

DB_HOST = 'your_rds_endpoint'
DB_PASS = 'your_secure_password'
DB_USER = 'your_username'

Then just import settings.py into views.py and access the variable you need. In views.py:

from django.conf import settings as my_settings

db_host = my_settings.DB_HOST
db_user = my_settings.DB_USER
db_pass = my_settings.DB_PASS

However, this is not the best way to do it because from what I could find, you should reference the settings file as little as possible because of security concerns.

Better alternatives to this problem are probably RDS Instance

  • Related