# Deploy Django on apache

**URL:** <https://forum.djangoproject.com/t/deploy-django-on-apache/19143>\
**Category:** Deployment\
**Created:** [February 27, 2023, 12:12pm UTC](https://forum.djangoproject.com/t/deploy-django-on-apache/19143 "2023-02-27T12:12:39Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![goncaloLopesMarques](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/goncalolopesmarques/32/4207_2.png) [@goncaloLopesMarques](https://forum.djangoproject.com/u/goncaloLopesMarques)\
**Post date:** [February 27, 2023, 12:12pm UTC](https://forum.djangoproject.com/t/deploy-django-on-apache/19143/1 "2023-02-27T12:12:39Z")

</div>

Hi guys,

Question, i deployed django on a apache but it can´t access the virtual env files. I missing something?

best regards

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [February 27, 2023, 12:29pm UTC](https://forum.djangoproject.com/t/deploy-django-on-apache/19143/2 "2023-02-27T12:29:50Z")

</div>

If you’re looking for assistance here, we’re going to need a _lot_ more detail about what’s going on. At a minimum I think we’d need a description of your environment, how you’ve tried to deploy it, the relevant configuration files, and the exact error message(s) you’re receiving in the log(s).

---

<div class="post-metadata">

**Author:** ![goncaloLopesMarques](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/goncalolopesmarques/32/4207_2.png) [@goncaloLopesMarques](https://forum.djangoproject.com/u/goncaloLopesMarques)\
**Post date:** [February 27, 2023, 2:01pm UTC](https://forum.djangoproject.com/t/deploy-django-on-apache/19143/3 "2023-02-27T14:01:16Z")

</div>

I deployed a django app on apache 2 with mod wsgi. All the website works, less a function wich use some libraries that are installed in the virtual environment.  
I´m using a raspberry py with raspberrian  
Database its working like a charm.  
Apache file:

```auto
<VirtualHost *:80>
        ServerAdmin webmaster@localhost
        DocumentRoot /var/www

        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        Alias /static /var/www/nfcReader/static
                <Directory /var/www/nfcReader/static>
                         Require all granted
                 </Directory>

                 <Directory /var/www/nfcReader/nfcReader>
                         <Files wsgi.py>
                                 Require all granted
                         </Files>
                 </Directory>

        WSGIDaemonProcess inov python-path=/var/www/nfcReader python-home=/home/inov/env
        WSGIProcessGroup inov
        WSGIScriptAlias / /var/www/nfcReader/nfcReader/wsgi.py
</VirtualHost>

```

By the way, where does django store actual wsgi errors?

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [February 27, 2023, 2:22pm UTC](https://forum.djangoproject.com/t/deploy-django-on-apache/19143/4 "2023-02-27T14:22:39Z")

</div>

That’s a start. We’re still going to need more specifics on the errors being received though.

> [@goncaloLopesMarques](#):
>
> By the way, where does django store actual wsgi errors?

The mod\_wsgi-based errors are going to be found in the Apache logs - usually in `/var/log/apache2`. (All configurable based upon your Apache settings.)

The Django-related errors are going to be wherever your Django logger is directing them.

---

<div class="post-metadata">

**Author:** ![goncaloLopesMarques](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/goncalolopesmarques/32/4207_2.png) [@goncaloLopesMarques](https://forum.djangoproject.com/u/goncaloLopesMarques)\
**Post date:** [February 27, 2023, 2:33pm UTC](https://forum.djangoproject.com/t/deploy-django-on-apache/19143/5 "2023-02-27T14:33:10Z")

</div>

dont have any errors on the /var/log/apache2/error.log, only somes prints in the functions goes to this file. When a execute the function give sme 500 error but no error on the error.log

---

<div class="post-metadata">

**Author:** ![goncaloLopesMarques](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/goncalolopesmarques/32/4207_2.png) [@goncaloLopesMarques](https://forum.djangoproject.com/u/goncaloLopesMarques)\
**Post date:** [February 27, 2023, 2:51pm UTC](https://forum.djangoproject.com/t/deploy-django-on-apache/19143/6 "2023-02-27T14:51:33Z")

</div>

Finaly i can see some error:

```auto
[Errno 13] Permission denied: '/dev/spidev0.0'
Request Method:	GET
Request URL:	http://10.200.1.60/ajax/getTagId
Django Version:	4.1.5
Exception Type:	PermissionError
Exception Value:	
[Errno 13] Permission denied: '/dev/spidev0.0'
Exception Location:	/home/inov/env/lib/python3.9/site-packages/Adafruit_PureIO/spi.py, line 169, in __init__
Raised during:	nfcSite.views.getTagId
Python Executable:	/home/inov/env/bin/python
Python Version:	3.9.2
Python Path:	
['/var/www/nfcReader', '/usr/lib/python39.zip', '/usr/lib/python3.9', '/usr/lib/python3.9/lib-dynload', '/home/inov/env/lib/python3.9/site-packages']
Server time:	Mon, 27 Feb 2023 14:38:07 +0000

```

---

<div class="post-metadata">

**Author:** ![goncaloLopesMarques](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/goncalolopesmarques/32/4207_2.png) [@goncaloLopesMarques](https://forum.djangoproject.com/u/goncaloLopesMarques)\
**Post date:** [February 27, 2023, 2:52pm UTC](https://forum.djangoproject.com/t/deploy-django-on-apache/19143/7 "2023-02-27T14:52:16Z")

</div>

there ir the folder root project

```auto
-rw-r--r-- 1 inov root 11207 fev 27 00:00 cronLogs.txt
-rw-r--r-- 1 inov root 131072 fev 16 14:20 db.sqlite3
drwxr-xr-x 4 inov inov 4096 fev 27 14:07 env
-rwxr-xr-x 1 inov root 665 fev 16 14:20 manage.py
drwxr-xr-x 3 inov root 4096 fev 16 14:20 nfcReader
drwxr-xr-x 7 inov root 4096 fev 16 14:20 nfcSite
drwxr-xr-x 2 inov root 4096 fev 16 14:20 __pycache__
-rw-r--r-- 1 inov root 9005 fev 27 00:00 recordsLog.txt
drwxr-xr-x 5 inov root 4096 fev 16 14:20 static
drwxr-xr-x 7 inov root 4096 fev 16 14:20 staticfiles
drwxr-xr-x 3 inov root 4096 fev 16 14:20 templates

```

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [February 27, 2023, 3:12pm UTC](https://forum.djangoproject.com/t/deploy-django-on-apache/19143/8 "2023-02-27T15:12:35Z")

</div>

> [@goncaloLopesMarques](#):
>
> `[Errno 13] Permission denied: '/dev/spidev0.0'`

That’s pretty straight forward. The `www-data` uid most-likely doesn’t have direct access to that device.

But first, my biggest concern would be handling the possibility of concurrent access between process instances of Apache.

When I’ve had to expose hardware interfaces to the web on a Pi, I create an intermediate layer “shim” that runs as a persistent task. I then use Redis as the communication link between Django and that shim.

The shim is a Python program running as root, giving it direct access to the hardware.

The flow of the request/response ends up being:

- Browser issues a request
- Web server receives a request
- Django view executes
  - Posts a message on redis, including the name of a response queue
  - Does a blocking read on the response queue
  - Builds the response from the data returned
  - Return the response to the browser.

Meanwhile, the shim consists of:

- While True:
  - Do a blocking read on the message queue
  - When a message is received, set/retrieve the data from the hardware
  - Return a response to the response queue.

The latency involved in this is negligible compared to the amount of time that Django is going to spend preparing the response to be returned to the browser.

I have also done this using Channels, where one or more browsers are monitoring a Pi, and when data is updated, it’s sent asynchronously to all connected browsers.

---

<div class="post-metadata">

**Author:** ![goncaloLopesMarques](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/goncalolopesmarques/32/4207_2.png) [@goncaloLopesMarques](https://forum.djangoproject.com/u/goncaloLopesMarques)\
**Post date:** [February 27, 2023, 3:24pm UTC](https://forum.djangoproject.com/t/deploy-django-on-apache/19143/9 "2023-02-27T15:24:06Z")

</div>

Humm its a nice question. But my apache will have only running one project, so i have sure that one process will acess the hardware.

---

<div class="post-metadata">

**Author:** ![KenWhitesell](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/kenwhitesell/32/280_2.png) [@KenWhitesell](https://forum.djangoproject.com/u/KenWhitesell)\
**Post date:** [February 27, 2023, 3:27pm UTC](https://forum.djangoproject.com/t/deploy-django-on-apache/19143/10 "2023-02-27T15:27:21Z")

</div>

> [@goncaloLopesMarques](#):
>
> But my apache will have only running one project, so i have sure that one process will acess the hardware.

That by itself is not an accurate statement. The standard Apache configuration starts multiple worker processes.

Also, have you ever (intentionally or otherwise) opened up two browser tabs to the same page? Same situation.

You **need** to assume multiple access.

---

<div class="post-metadata">

**Author:** ![goncaloLopesMarques](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/goncalolopesmarques/32/4207_2.png) [@goncaloLopesMarques](https://forum.djangoproject.com/u/goncaloLopesMarques)\
**Post date:** [February 27, 2023, 3:40pm UTC](https://forum.djangoproject.com/t/deploy-django-on-apache/19143/11 "2023-02-27T15:40:45Z")

</div>

i will try to test that. But this its a admin tool. So one person will use this in a very controled whay(by me =p) Later i will look at your use case but now i need to send the first version of the project till friday.

I add the www-data to the spi group but no luck, this time the error its:

```auto
	
No access to /dev/mem. Try running as root!

```
