Step by step guide to deploy Jam-V7 on Ubuntu 24

108 views
Skip to first unread message

EKuzmin

unread,
Jun 11, 2025, 6:11:14 AM6/11/25
to Jam.py Users Mailing List
I would like to share my experience of deployment on Ubuntu server.
Software versions:
- jam.py-v7 7.0.57  https://pypi.org/project/jam.py-v7/
- Ubuntu 24.04 LTS
- python 3.12.3
- apache 2.4.58
- libapache2-mod-wsgi-py3 5.0.0

1. Preparing the system.

sudo apt update
sudo apt upgrade -y
sudo apt install -y python3.12 python3.12-venv python3.12-dev python3-pip
sudo apt install -y apache2 apache2-dev
sudo apt install -y build-essential
sudo apt install -y git wget curl
sudo apt install -y libssl-dev libffi-dev
sudo apt install -y python3-full

2. Installing and configuring mod_wsgi

sudo apt install libapache2-mod-wsgi-py3
sudo a2enmod wsgi
sudo systemctl restart apache2

Checking:  
apache2ctl -M | grep wsgi

Result:
wsgi_module (shared)

3. Creating a project structure

sudo mkdir -p /var/www/jam
sudo chown -R $USER:www-data /var/www/jam
cd /var/www/jam
python3.12 -m venv jam-env
source jam-env/bin/activate
pip install --upgrade pip
pip install jam.py-v7

4. Creating a JAM project
source /var/www/jam/jam-env/bin/activate
jam-project.py

5. Project configuration
Update file /var/www/jam/server.py :  

server.py:
-------------------------------------
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import os
import sys
 
PROJECT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, PROJECT_DIR)
 
import jam.wsgi
 
def create_application():
    return jam.wsgi.create_application(PROJECT_DIR)
 
application = create_application()
 
if __name__ == '__main__':
    app = create_application()
    app.start()

-------------------------------------

Update file /var/www/jam/wsgi.py :  

wsgi.py:
-------------------------------------
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import os
import sys
 
PROJECT_DIR = '/var/www/jam'
VENV_DIR = '/var/www/jam/jam-env'
 
sys.path.insert(0, os.path.join(VENV_DIR, 'lib', 'python3.12', 'site-packages'))
sys.path.insert(0, PROJECT_DIR)
 
os.chdir(PROJECT_DIR)
 
import jam.wsgi
 
application = jam.wsgi.create_application(PROJECT_DIR)

-------------------------------------

6. Setting up access permissions

sudo chown -R www-data:www-data /var/www/jam
sudo chmod -R 755 /var/www/jam
sudo chmod -R 775 /var/www/jam/static
sudo chmod 664 /var/www/jam/admin.sqlite


7. Setting up Apache Virtual Host

Create file /etc/apache2/sites-available/jam.conf :  

jam.conf:
-------------------------------------
<VirtualHost *:80>
    ServerName jam.local
    ServerAlias www.jam.local
    DocumentRoot /var/www/jam
 
    # WSGI Configuration
    WSGIDaemonProcess jam user=www-data group=www-data python-home=/var/www/jam/jam-env python-path=/var/www/jam
    WSGIProcessGroup jam
    WSGIScriptAlias / /var/www/jam/wsgi.py
    WSGIPassAuthorization On
 
    # Directory permissions
    <Directory /var/www/jam>
        WSGIApplicationGroup %{GLOBAL}
        Require all granted
    </Directory>
 
    # Static files
    Alias /static /var/www/jam/static
    <Directory /var/www/jam/static>
        Require all granted
        ExpiresActive On
        ExpiresDefault "access plus 1 month"
    </Directory>
 
    # Logs
    ErrorLog ${APACHE_LOG_DIR}/jam_error.log
    CustomLog ${APACHE_LOG_DIR}/jam_access.log combined
    LogLevel info
 
    # Additional security headers
    Header always set X-Content-Type-Options nosniff
    Header always set X-Frame-Options DENY
    Header always set X-XSS-Protection "1; mode=block"
</VirtualHost>
-------------------------------------

8. Activation of modules and site

sudo a2enmod headers
sudo a2enmod expires
sudo a2enmod rewrite
 
sudo a2ensite jam.conf
sudo a2dissite 000-default.conf
sudo systemctl reload apache2


Check site configuration:
sudo apache2ctl configtest

Restart apache service:

sudo systemctl restart apache2
sudo systemctl enable apache2
sudo systemctl status apache2

I was able to successfully deploy jam-v7 several times by strictly following these steps.

Dean D. Babic

unread,
Jun 12, 2025, 12:51:18 AM6/12/25
to Jam.py Users Mailing List
Nice man!
Thanks. Nor sure if wsgi or server needs touching at all tho.
The virtual env. for Python is handled by WSGIDaemonProcess python-home.
Also, 755 is quite open.
So now just install certificates :)

EKuzmin

unread,
Jun 23, 2025, 11:59:16 AM6/23/25
to Jam.py Users Mailing List

Thanks.
I went further: I set up the JAM using Gunicorn and Nginx with a PostgreSQL backend. Everything runs as Docker containers. Certificates are in place. Credentials for connecting to PostgreSQL are stored in encrypted form.
However, I'm still concerned about admin.sqlite — the fact that passwords are stored there in plain text is troubling.  
четверг, 12 июня 2025 г. в 06:51:18 UTC+2, Dean D. Babic:

Dean D. Babic

unread,
Jun 23, 2025, 10:09:28 PM6/23/25
to Jam.py Users Mailing List
This means only one thing: you are not using external Auth where password are encrypted:

You want OAuth? Here:

SAML? No probs either....

Manos S. Pappás

unread,
Jun 24, 2025, 12:14:29 AM6/24/25
to EKuzmin, Jam.py Users Mailing List
Hi,

An article exists on this forum  - and if I remember correctly, on the how to - regarding storing the passwords on a table on a remote database. That is what I am doing with MSSQL and ot can be done in Postgres. No passwords are saved on the admin.sqlite, except one that is used to invoke the builder.
You do need however custom login code and since passwords are no longer on text but encrypted, a means to reset the passwords in case you forget them.

M.

---
Best Regards,
Manos Stylianos Pappαs
Address: D. Synadinou 8, 82100 Chios, GREECE
PGP key available on request
http://net314.eu

--
You received this message because you are subscribed to the Google Groups "Jam.py Users Mailing List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jam-py+un...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/jam-py/072a5042-b22b-48c8-89d3-8651c26baaf8n%40googlegroups.com.

EKuzmin

unread,
Jun 24, 2025, 9:33:59 AM6/24/25
to Jam.py Users Mailing List
Hello.

I configured (on Postgres) everything as described in the instructions https://jam-py.com/docs/how_to/authentication/how_to_authenticate_from_custom_users_table.html

Now, access to the main site is only possible using accounts from the "Users" table. However, access to builder still requires an account from admin.sqlite database.

How can i configure secure access to builder?

SAML, OAuth, or Active Directory integration won't work for this case. The requirement is to manage access to the resource separately.

вторник, 24 июня 2025 г. в 04:09:28 UTC+2, Dean D. Babic:

Dean D. Babic

unread,
Jun 24, 2025, 9:43:04 AM6/24/25
to Jam.py Users Mailing List

Hide it.

EKuzmin

unread,
Jun 24, 2025, 10:24:59 AM6/24/25
to Jam.py Users Mailing List
Do you mean hiding builder.html? I'm afraid that's only a temporary workaround. A pentester would still be able to find it, and access to admin.sqlite was previously obtained via http requests — without having shell access to the server.

Also, the default file is located at: /usr/local/lib/python3.12/site-packages/jam/project/admin.sqlite

However, after changing the administrator password in the current project, this is not a threat.

вторник, 24 июня 2025 г. в 15:43:04 UTC+2, Dean D. Babic:
Message has been deleted
Message has been deleted
Message has been deleted

Dean D. Babic

unread,
Jun 26, 2025, 12:13:44 AM6/26/25
to Jam.py Users Mailing List
So, 
if we look at admin.py:
def login_user(task, log, password, admin, ip=None, session_uuid=None):

and look at how hash is implemented here:

in items.py there is a generate_password_hash.

It is not that hard to implement even a custom hash, and not use werkzeug.security,
if someone wants to be on super safe side. 

Hope this helps. 
Reply all
Reply to author
Forward
0 new messages