0

I'm trying to setup Apache(2.4, built from sources)+Django(1.8.12) on CentOS 6, but when i try to login to my site or create user or something else that writes to DB, i get an error:

attempt to write a readonly database

I already have tried to:

  • change owner of db file to apache user (not works)
  • change permissions: 775, 774, 664 give same error as above; 666, 776 give:

unable to open database file

  • same actions to whole folder with django project

I followed this tutorial.

My httpd.conf (part which i added):

LoadModule wsgi_module modules/mod_wsgi.so WSGIScriptAlias / /var/www/project/project/wsgi.py WSGIPythonPath /var/www/project:/var/www/env/lib/python3.5/site-packages <Directory /var/www/project> <Files wsgi.py> Require all granted </Files> </Directory> 

./manage createsuperuser work correct, user added to DB.

For serving media i use Nginx (all media and static files retrieves correct).

UPD

Full trace back:

Environment: Request Method: POST Request URL: http://localhost:8080/accounts/login/ Django Version: 1.8.12 Python Version: 3.5.1 Installed Applications: ('bootstrap3', 'django_admin_bootstrapped', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'macros', 'django_ajax', 'ckeditor', 'accounts', 'main', 'tutor', 'public_testing', 'control_testing', 'debug_toolbar', 'django_extensions', 'mmc') Installed Middleware: ('django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', 'debug_toolbar.middleware.DebugToolbarMiddleware') Traceback: File "/var/www/env/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response 132. response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/var/www/env/lib/python3.5/site-packages/django/views/decorators/debug.py" in sensitive_post_parameters_wrapper 76. return view(request, *args, **kwargs) File "/var/www/env/lib/python3.5/site-packages/django/utils/decorators.py" in _wrapped_view 110. response = view_func(request, *args, **kwargs) File "/var/www/env/lib/python3.5/site-packages/django/views/decorators/cache.py" in _wrapped_view_func 57. response = view_func(request, *args, **kwargs) File "/var/www/env/lib/python3.5/site-packages/django/contrib/auth/views.py" in login 51. auth_login(request, form.get_user()) File "/var/www/env/lib/python3.5/site-packages/django/contrib/auth/__init__.py" in login 110. request.session.cycle_key() File "/var/www/env/lib/python3.5/site-packages/django/contrib/sessions/backends/base.py" in cycle_key 285. self.create() File "/var/www/env/lib/python3.5/site-packages/django/contrib/sessions/backends/db.py" in create 41. self.save(must_create=True) File "/var/www/env/lib/python3.5/site-packages/django/contrib/sessions/backends/db.py" in save 65. obj.save(force_insert=must_create, using=using) File "/var/www/env/lib/python3.5/site-packages/django/db/models/base.py" in save 734. force_update=force_update, update_fields=update_fields) File "/var/www/env/lib/python3.5/site-packages/django/db/models/base.py" in save_base 762. updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields) File "/var/www/env/lib/python3.5/site-packages/django/db/models/base.py" in _save_table 846. result = self._do_insert(cls._base_manager, using, fields, update_pk, raw) File "/var/www/env/lib/python3.5/site-packages/django/db/models/base.py" in _do_insert 885. using=using, raw=raw) File "/var/www/env/lib/python3.5/site-packages/django/db/models/manager.py" in manager_method 127. return getattr(self.get_queryset(), name)(*args, **kwargs) File "/var/www/env/lib/python3.5/site-packages/django/db/models/query.py" in _insert 920. return query.get_compiler(using=using).execute_sql(return_id) File "/var/www/env/lib/python3.5/site-packages/django/db/models/sql/compiler.py" in execute_sql 974. cursor.execute(sql, params) File "/var/www/env/lib/python3.5/site-packages/debug_toolbar/panels/sql/tracking.py" in execute 159. return self._record(self.cursor.execute, sql, params) File "/var/www/env/lib/python3.5/site-packages/debug_toolbar/panels/sql/tracking.py" in _record 101. return method(sql, params) File "/var/www/env/lib/python3.5/site-packages/django/db/backends/utils.py" in execute 79. return super(CursorDebugWrapper, self).execute(sql, params) File "/var/www/env/lib/python3.5/site-packages/django/db/backends/utils.py" in execute 64. return self.cursor.execute(sql, params) File "/var/www/env/lib/python3.5/site-packages/django/db/utils.py" in __exit__ 98. six.reraise(dj_exc_type, dj_exc_value, traceback) File "/var/www/env/lib/python3.5/site-packages/django/utils/six.py" in reraise 685. raise value.with_traceback(tb) File "/var/www/env/lib/python3.5/site-packages/django/db/backends/utils.py" in execute 64. return self.cursor.execute(sql, params) File "/var/www/env/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py" in execute 318. return Database.Cursor.execute(self, query, params) Exception Type: OperationalError at /accounts/login/ Exception Value: attempt to write a readonly database 

UPD 2

/tmp permissions:

drwxrwxrwt 6 root root 4096 Apr 22 10:06 tmp 

settings.py DATABASES:

DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } 

DATABASES section from error page:

DATABASES {'default': {'ATOMIC_REQUESTS': False, 'AUTOCOMMIT': True, 'CONN_MAX_AGE': 0, 'ENGINE': 'django.db.backends.sqlite3', 'HOST': '', 'NAME': '/var/www/project/db.sqlite3', 'OPTIONS': {}, 'PASSWORD': '********************', 'PORT': '', 'TEST': {'CHARSET': None, 'COLLATION': None, 'MIRROR': None, 'NAME': None}, 'TIME_ZONE': 'UTC', 'USER': ''}} 

4 Answers 4

5

In fact, it is not actually a login error. It happens when the application which writes to the sqlite database does not have write permission. Since login was the first attempt to write to database, you got it as login error.

This can be solved in three ways:

  1. Granting ownership of db.sqlite3 file and its parent directory (thereby write access also) to the user using chown (Eg: chown username db.sqlite3 )
  2. Running the webserver (often gunicorn) as root user (run the command sudo -i before you run gunicorn, apache or django runserver)
  3. Allowing read and write access to all users by running command chmod 777 db.sqlite3 (Dangerous option)

Never go for the third option unless you are running the webserver in a local machine or the data in the database is not at all important for you.

Moreover, this error does not occur if you are using a database like mysql and Postgres. Sqlite is not a good option for a webserver with a high traffic.

Sign up to request clarification or add additional context in comments.

Comments

4

For Django applications running on Apache, you can find the user running apache by checking the apache2/conf/httpd.conf file.

In case of Bitnami Django Stack, the httpd.conf file shows:

User daemon Group daemon 

This will show you which user is running apache.

Now, to solve the issue of "attempt to write a readonly database", simply run the the following commands:

sudo chown {apache_user}:{apache_user} /path/django_project sudo chown {apache_user}:{apache_user} /path/django_project/db.sqlite3 

The chown command will change the ownership of the project folder and the database, allowing the server to communicate with it.

Comments

3

Permission issue: changing the owner of the database and the directory to apache resolved it (centos 7).

chown apache:apache /root/myproject/db.sqlite chown apache:apache /root/myproject 

Please acknowledge https://stackoverflow.com/a/45909954/1218179

Comments

1

Looks like permissions issue. Permissions 777 on db file should work - that way you give all access to all users. However... if you wish to edit there is additional journal file created, so the user needs to edit the directory. Apache user can be apache or nobody.

11 Comments

Temp directory should give full access, so please check that ls -ald should return something like drwxrwxrwt 11 root root 4096 kwi 22 18:41 /tmp. However if apache works, that should not be the case. Can you provide full stack trace? Or... maybe db path is relative, and something is missed here. That would explain why manage works, while wsgi fails. No other ideas.
Question updated. But i don't not understand, where ls -ald i should do? And what is that command does?
Sorry - cd /tmp && ls -ald - this one goes to your temp directory, and checks permissions. Can you check settings.py if your DB is defined with relative path? Also try to debug, or maybe print full db file path + status for your DB - at login screen. That can show where to look next :)
Updated. /tmp is OK, DB defined with absolute path. But i found an intresting thing: when i try to add in view this code (it reading all existing users and write them to file): with open('test.txt', 'w') as f: f.write(list(User.objects.all())) , it fails with [Errno 13] Permission denied: 'test.txt'
just for checking - copy your db file to /tmp, and update configuration - if works - stackoverflow.com/questions/36386418/…
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.