31 Quick Guide to publishing websites on hal.elte.hu with Python3 backend
baskayj edited this page 4 years ago

Quick Guide to publishing websites on hal.elte.hu with Python3 backend

Making a website with Flask

Requirements:

  • Python3 virtual environment
  • Flask (pip3 install Flask)

To make a basic website using the Flask python package you can follow any guides you can find. For example:

It's also worth mentioning, that Flask has various \“AddOn\” modules, like flask-wtf, which allows you to create forms on your website for data collection.

Once you’re done, collect all Python packages needed in a requirements.txt with version number included. It should look something like this:

Flask==2.0.2
Flask-WTF==1.0.0
.
.
.

Configuring Apache2

Since Flask’s built-in server is not fit for live traffic, you need another WSGI server, that’s where Apache2 comes in the picture.

  1. Install Apache2: sudo apt-get install apache2
  2. Install mod_wsgi compiled with python3: sudo apt-get install libapache2-mod-wsgi-py3
  3. Enable mod_wsgi: sudo a2enmod wsgi
  4. Create a config file for your website:

Creating your_app.conf

This file contains the paths to all the important Files needed for Apache2 to run your Python3 scripts. The minimal config file for a Flask-app, with static files (Images, CSS) present looks like:

<VirtualHost *:80>
    ServerAdmin username    # Change it to your username
    DocumentRoot /var/www/html/your_app    # All data for your site “should” be at /var/www/html/
    
    WSGIDaemonProcess your_app python-home=/var/www/html/your_app/your_app/venv python-path=/var/www/html/your_app/your_app:/var/www/html/your_app/your_app/venv/local/lib/python3.9/site-packages threads=5    # Location of your Python3 virtualenv
    WSGIScriptAlias /your_app /var/www/html/your_app/your_app.wsgi    # Your site will be available at hal.elte.hu/your_app
    WSGIApplicationGroup %{GLOBAL}
    <Directory /var/www/html/your_app/your_app/>    # Location of your Python scripts
        WSGIProcessGroup your_app
        WSGIApplicationGroup %{GLOBAL}
        Order deny,allow
        Allow from all
    </Directory>
    Alias /static /var/www/html/your_app/your_app/static
    <Directory /var/www/html/your_app/your_app/static/>
        Order allow,deny
        Allow from all
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log    # Logging
    LogLevel warn
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Replace your_app with the appropriate name of your website and folders. If you use a different folder structure, make sure it’s reflected here.

  1. To be able to test the website, place the config file you’ve just made in /etc/apache2/sites-available/
  2. To be able to test your website, place your python scripts folder in /var/www/html/your_app/, resulting in a file structure like this:

|----/var/www/html/
|-----------------your_app/
|---------------------your_app.wsgi --> We’ll make this in the next step
|---------------------your_app/
|-------------------------static/
|-------------------------templates/
|-----------------------------main.html
|----------------------------- (…)
|-------------------------venv/
|-------------------------main.py
|------------------------- (…)

  1. Create a wsgi script, that can start your Python app in your virtualenv:

Creating your_app.wsgi

#!/var/www/html/your_app/your_app/venv/bin/python
import sys
import logging
import os

APP_HOME = "/var/www/html/your_app/your_app/"
sys.path.insert(0,"/var/www/html/your_app/your_app/venv/lib/python3.9/site-packages")

logging.basicConfig(stream=sys.stderr)
sys.path.insert(0,APP_HOME)
os.chdir(APP_HOME)

from main import app as application

Make sure to replace your_app, appropriately, and set the location of your python scripts(APP_HOME) and venv correctly.

  1. Place your_app.wsgi in var/www/html/your_app/ as seen at step 6., to be able to test the Apache2 server.

  2. Double check, that you've got a Python3 virtual environment in /var/www/html/your_app/your_app/ with all the packeges specified in requirements.txt.
    IF NOT:
    1. cd /var/www/html/your_app/your_app
    2. python3 -m venv venv
    3. source venv/bin/activate
    4. pip3 install -r requirements.txt
    5. deactivate

  3. Enable the website by sudo a2ensite your_app

  4. Restart the Apache2 server sudo service apache2 restart (To start or stop Apache2 you can use sudo service apache2 start/stop)

By going to localhost/your_app in your browser you should be able to see now your website, and if it has any interacitvity that runs some Python in the background it should work too. This will be up until you turn of you computer, or stop Apache2.

Testing your website with Docker

Since the site on hal.elte.hu will run inside a Docker container, before publishing you should test your work locally. To install Docker visit this link. Once Docker is up and running, you should make a new project folder DO NOT USE /var/www/html/!, and copy your_app.conf and the your_app folder from /var/www/html/ inside. (You should omit copying the venv.) Once you're done adding some other scirpts detailed a little further, the folder struture should look like this:

|----/your_app_docker/
|-----------------your_app.conf
|-----------------Dockerfile --> We’ll make this later
|-----------------locale.gen --> We’ll make this later
|-----------------start_apache.sh --> It's a surprise tool that'll help us later
|-----------------requirements.txt --> Move from your_app/your_app/ to here
|-----------------your_app/
|---------------------your_app.wsgi
|---------------------your_app/
|-------------------------static/
|-------------------------templates/ `` |-----------------------------main.html
|----------------------------- (…)
|-------------------------main.py
|------------------------- (…)

To make the missing files:

Dockerfile (NO EXTENSION)

ARG pyversion=3.9
FROM python:${pyversion}-bullseye
ARG pyversion=3.9
ENV PYVERSION ${pyversion:-3.9}

# Install packages
RUN apt-get -yqq update && \
    apt-get -yqq install apache2 apache2-dev locales libapache2-mod-wsgi-py3 && \
    apt-get clean

# Install locale
COPY ./locale.gen /etc/locale.gen
RUN locale-gen

COPY your_app /var/www/html/your_app

RUN chown -R www-data:www-data /var/www/
RUN chmod -R 755 /var/www/

USER www-data

# Prepare virtualenv
WORKDIR /var/www/html/your_app/your_app/
COPY ./requirements.txt .
RUN python3 -m venv ./venv
RUN . ./venv/bin/activate
RUN ./venv/bin/pip install --upgrade pip setuptools
RUN ./venv/bin/pip install -r ./requirements.txt

# Configure Apache
USER root
COPY ./start-apache.sh /
RUN a2dismod mpm_event && a2enmod mpm_prefork
COPY ./your_app.conf /etc/apache2/sites-available/000-default.conf

# Start Apache
EXPOSE 80
CMD ["/bin/sh", "/start-apache.sh"]

Make sure that your_app is replaced with the name of your folder, and the paths are the same, as in the folder structure above.

start_apache.sh

#!/bin/sh

set -e

. /etc/apache2/envvars
ulimit -n 8192
chown root:www-data /var/lock/apache2
chown -R www-data:www-data /var/www/html
exec /usr/sbin/apache2 -k start -DFOREGROUND

locale.gen

hu_HU.UTF-8 UTF-8

Add here other languages as needed.

With everything in place go to /your_app_docker and run the following commands:

  1. Build an image: docker build --rm -t your_app_img .
  2. Run the container: docker run -d --name your_app -p 8085:80 your_app_img

Then you should be able to access your website at localhost:8085/your_app. Once you're done you can stop and remove both the container and the image.

Upload your project to Gitea

Now that Docker can run your site with an Apache2 server locally you can upload it to Gitea, so it can also be built and run on hal.elte.hu.

  1. Navigate to /your_app_docker, you don't need to remove any file, nor you need to add anything.
  2. touch README.md
  3. git init
  4. git add .
  5. git commit -m "Initial commit"
  6. git remote add origin ssh://git@hal.elte.hu:2222/username/your_app.git
  7. git push -u origin master For the push to succed you have to add an ssh public key to your gitea account. (Settings->SSH/GPG keys->Add Key) The easiest (laziest) solution would be to upload the public key that corresponds to your .ssh/is_rsa.

Testing Docker & Gitea together

Now your site is ready to be deployed, but it's good practice to test locally first.

  1. docker build --rm -t your_app_img https://hal.elte.hu/gitea/username/your_app.git
  2. docker run -d --name your_app -p 8085:80 your_app_img

Then you should be able to access your website at localhost:8085/your_app.

Congratulations your project is now ready for live deployment! For any further alterations you just have to push your project folder to gitea, however do not forget to test locally first...