Beginnen met Python op je hostingpakket!

Vanaf het Plus-pakket is het nu mogelijk om een Python-applicatie op je hostingpakket te draaien. Het opzetten van zo’n webapplicatie heeft iets meer voorbereiding nodig dan bijvoorbeeld het uploaden van een PHP-website. Wil je beginnen met Python, dan leg ik je graag stap voor stap uit hoe je dit het beste aanpakt.

Beginnen met Python op je hostingpakket!

Basisbenodigdheden

Python-ondersteuning is bij Antagonist beschikbaar vanaf het Plus-pakket. Kun je de Python-selector in het DirectAdmin-menu niet vinden, bekijk dan in Mijn Antagonist welk hostingpakket je hebt. Je kunt dat zien op de productpagina. Voor het installeren en testen van de Python-applicatie is het ook handig dat je weet hoe je een SSH-verbinding met je pakket kunt maken.

Belangrijke kanttekeningen

  • Met deze uitleg zet je direct op productie een applicatie op. Volg het alleen als je op jouw domein geen belangrijke website hebt draaien. Er bestaat een risico bestaat dat je de bestaande website beschadigt.
  • Deze uitleg is puur geschikt voor een testproject. Zorg dat je een nieuwe productiewebsite eerst lokaal of op een testomgeving bouwt.
  • Vul geen belangrijke (klant)informatie in deze testapplicatie in, voordat je begrijpt hoe de beveiliging van Django werkt.

Python-applicatie aanmaken

Het toevoegen van een Python-applicatie begint in DirectAdmin. Ga in het menu naar Extra functies → Python Selector en klik op ‘Create application’ om met een nieuwe applicatie te beginnen.

De Python-selector in DirectAdmin.

Er verschijnen nu een aantal velden. Het ene veld is intuïtiever dan het andere, daarom licht ik ze graag elk even toe.

Instellingen in de Python-selector.
  • Python version | Geeft aan onder welke Python-versie je omgeving wordt aangemaakt. Python 2.7 is sterk verouderd, dus ik zou adviseren om hier Python 3.7 te selecteren.
  • Application root | Bepaalt in welke map je project komt te staan. Deze waarde is vaak de projectnaam van je applicatie. Gebruik hier geen submap om problemen met pip-pakketten installeren te voorkomen. Wil je een subpad gebruiken, stel dit dan in bij ‘Application URL’.
  • Application URL | Dit is standaard de URL van je website met de ‘application root’ als pad (voorbeeld.nl/demo). Je kunt ook het project op de URL draaien zonder pad. Vul dan gewoon je domein in (voorbeeld.nl).
  • Application startup file | Dit is het aanknopingspunt voor onze server om te kunnen bepalen hoe jouw webapplicatie wordt geserveerd. Laat je dit veld leeg bij het voor de eerste keer opslaan, dan wordt er standaard een passenger_wsgi.py-bestand aangemaakt en gelinkt. Als je een Django-applicatie aanmaakt of uploadt, dan wil je deze waarde achteraf aanpassen naar de bijbehorende wsgi.py. Dit volgt later in deze uitleg.
  • Application Entry point | De ondertekst bij dit veld doet vermoeden dat dit de plek is waar je linkt naar de wsgi.py van je applicatie, maar dit werkt niet als zodanig. Laat dit veld leeg, zodat hier de standaardwaarde ‘application’ wordt ingevuld.
  • Passenger log file | Vul hier de bestandsnaam in waar de standaard passenger_wsgi naar kan loggen (bijvoorbeeld ‘passenger.log’). Hierin worden eventuele problemen gelogd die Passenger wsgi bij het inladen van je applicatie ondervindt.

Nieuwe Python-applicatie gebruiken

Als je alle instellingen naar wens hebt ingevoerd, dan klik je op ‘Create’. Na het opslaan van de nieuwe configuratie, zie je dan hoe je via SSH je virtualenv activeert en naar je projectmap navigeert.

Python-selector: virtualenv activeren en naar je projectmap navigeren.

Let op dat de inhoud van je project dus niet in public_html-map staat, maar in:

/home/<deb12345>/<projectnaam>

Dit is ook de locatie waar je wijzigingen in de applicatie naar wilt uploaden met SFTP of SCP. In de public_html-map heb je ook een map met een vergelijkbare naam, maar hierin staat enkel een .htaccess-bestand. Die zorgt ervoor dat de server jouw applicatie kan vinden.

Virtualenv

Je virtualenv is een hulpmiddel om alle benodigde pip-pakketten (en de versie van Python) in de context van een specifieke applicatie in te stellen. Mocht je op je website meerdere applicaties willen draaien, dan houdt de virtualenv de context gescheiden. Zo hoef je je niet druk te maken als verschillende apps verschillende versies van Python of van pakketten nodig hebben – dit blijft netjes gescheiden.

Django installeren

Hoewel er alternatieve opties zijn om met je eigen webapplicatie verder te gaan (from scratch, met Flask of Web2py), ga ik voor deze demo-applicatie uit van Django. Nadat je via SSH je virtualenv hebt geactiveerd, kun je eenvoudig starten met Django door met pip de benodigde pakketten te installeren.

pip install --upgrade pip
pip install django mysqlclient

Vervolgens initialiseer je je project in de huidige map met django-admin.

django-admin startproject demo .

Configuratie

Een paar aanpassingen in het bestand demo/settings.py helpen je op weg met de databaseverbinding en de logging. Merk op dat een wijziging in settings.py pas actief wordt na een herstart van de applicatie. De applicatie herstarten, kan in de Python-selector.

Voeg nu je website-URL toe aan ALLOWED_HOSTS om Django-verzoeken naar deze URL te laten accepteren. De debug modus zetten we uit, omdat het veiliger is om foutmeldingen op de server te loggen. Zonder debug modus worden statische bestanden (CSS/JS) ook op een slimmere manier geserveerd.

ALLOWED_HOSTS = [‘<example.com>']
DEBUG = False
STATIC_ROOT = '/home/<deb12345>/domains/<example.com>/public_html/static'

De toevoeging van de STATIC_ROOT-instelling laat Django weten waar de statische bestanden uit de applicatie terecht moeten komen. Vergeet niet de gebruikersnaam en het domein te vervangen door je eigen gegevens.

Om fouten in de applicatie op te sporen, wil je dat Django naar een bestand kan loggen. Voeg hiervoor het volgende blok code toe. Vervang de gegevens bij ‘filename’ met je eigen gebruikersnaam en locatie.

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'file': {
            'level': 'INFO',
            'class': 'logging.FileHandler',
            'filename': '/home/<deb12345>/django.log',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'INFO',
            'propagate': True,
        },
    },
}

De gegevens van je Django-applicatie worden standaard opgeslagen in een SQLite-database (db.sqlite3). Gebruik je liever een MySQL-database? Vervang dan het blok DATABASES met onderstaande code. Vul tussen de quotes je eigen MySQL-gegevens in.

ATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': '<database_naam>',
        'USER': '<database_gebruiker>',
        'PASSWORD': '<database_wachtwoord>',
        'HOST': 'localhost',   
        'PORT': '3306',
    }
}

Je eerste testpagina toevoegen

Om te kunnen testen of de applicatie naar behoren werkt, maken we een hello-world-testpagina. Start hiervoor een nieuwe app binnen je project met:

python manage.py startapp begin

Dit maakt een nieuwe map ‘begin’ aan, een submodule waarin je de view voor je testpagina kunt toevoegen. Vervang hiervoor de inhoud van begin/views.py met de view-functie voor de testpagina:

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hallo wereld, je testpagina werkt!")

Zorg dat de URL’s uit je app ‘begin’ worden ingeladen door de hoofdapplicatie met de volgende code in demo/urls.py:

from django.contrib import admin
from django.urls import path
from begin.views import index

urlpatterns = [
    path('', index),
    path('admin/', admin.site.urls),
]

Als laatste wil je in settings.py de nieuwe module toevoegen in de lijst van INSTALLED_APPS (gewoon de string ‘begin’, zonder ‘django.contrib’).

Voorbereiding op livegang

Je hebt de code voor de testpagina nu klaar! Er zijn een paar voorbereidende stappen die nog handig zijn om uit te voeren, voor je aan de slag gaat met je Django-applicatie. Gebruik het commando uit de Python-selector om je virtualenv te activeren en in de juiste projectmap te komen. Vervolgens kun je met het manage.py-script van Django je applicatie klaarmaken voor gebruik.

python manage.py collectstatic
python manage.py migrate
python manage.py createsuperuser

In Django zit een standaard admin-gedeelte, waarmee je eenvoudig de gegevens in je database kunt onderhouden.

  • Met ‘collectstatic’ zet je de CSS- en JavaScript-bestanden klaar in public_html (zoals aangegeven in de waarde STATIC_ROOT). 
  • Met ‘migrate’ maak je de initiële databasestructuur aan die nodig is voor de Django admin.
  • Met ‘createsuperuser’ maak je een beheeraccount aan voor de admin pagina. Gebruik een sterk wachtwoord.

Je applicatie activeren  

Je Django-applicatie is klaar voor gebruik, maar de Python-selector weet nog niet hoe het de applicatie kan inladen. Hiervoor navigeer je terug naar de Python-selector en vervang je de waarde bij ‘Application startup file’. Dit was voorheen passenger_wsgi.py en wordt in ons geval nu demo/wsgi.py. Sla op met ‘Save’ en klik op ‘Restart’ om alle wijzigingen door te voeren.

Testen en vervolg

Gefeliciteerd! Als alles goed gelukt is, dan zie je nu op jouw domeinnaam de volgende testpagina.

Hello-world-testpagina met Python.

Ook moet het admingedeelte van Django beschikbaar zijn.

Het Django-admingedeelte.

Wil je meer info over het installeren en uitbreiden van een Django-applicatie, volg dan de officiële tutorial van het Django-project.


Mogelijke foutmeldingen en oplossingen

Loop je vast bij de aanmaken van je Python-applicatie, bekijk dan eerst deze veelvoorkomende foutmeldingen en oplossingen daarvoor.

403 forbidden

Controleer in de Python-selector of je applicatie draait en of de juiste wsgi.py staat ingesteld.

404 not found

Controleer het subpath in de Python-selector met de URL die je gebruikt. Check of die instellingen overeenkomen met het voorbeeld en of je de wsgi.py uit je Django-project goed hebt ingesteld onder ‘Application startup file’. Controleer verder de urls.py in ‘demo’ en ‘begin’ om te zien of de index view onder de juiste URL is gekoppeld (een lege string, geen slash). Vergeet de app niet te restarten na eventuele wijzigingen in deze bestanden.

500 Internal Server Error

Zie je geen beginpagina, maar een foutpagina? Kijk dan in de django.log of start de server handmatig in SSH om te zien waar de fout zit:

python ./manage.py runserver

Can’t acquire lock for app: <applicatienaam>

Het kan gebeuren dat in DirectAdmin de pagina herladen of gesloten wordt tijdens het uitvoeren van een commando of wijziging in de Python-selector. Er kan dan er een lockfile achterblijven, het bestand dat DirectAdmin normaal gesproken gebruikt om te voorkomen dat er twee acties door elkaar lopen. Wacht een paar minuten en als je zeker weet dat er geen acties meer lopen, dan kun je de lockfile via SSH verwijderen. Deze is te vinden in:

virtualenv/<applicatienaam>/.lock

Django admin heeft geen styling

Als de Django admin er niet zo uitziet als in het voorbeeld, ga dan na of de static-map in je public_html is gevuld met bestanden voor de admin-module. Mochten deze ontbreken, bekijk dan de STATIC_ROOT-instelling. Controleer of STATIC_URL verwijst naar de juiste static-map en draai het volgende commando opnieuw:

python manage.py collectstatic

P.S. Blijf op de hoogte en volg ons via Facebook, Twitter, Instagram, e-mail en RSS. Heb je vragen, tips of opmerkingen? Laat het achter als reactie. Vond je het artikel nuttig? Deel het dan met anderen!

Deel App Tweet Mail Deel

10 thoughts on “Beginnen met Python op je hostingpakket!

  1. Sebastiaan op zei:

    Geweldig nieuws! Ik zat al een tijd te zoeken naar een nieuwe host omdat ik steeds meer met Python doe, maar eigenlijk wou ik helemaal niet weg bij Antagonist. Fijn dat ik nu het beste van beide werelden kan gebruiken!

  2. Robert Loeber op zei:

    Hoi jonathan, complimenten voor deze uitbreiding. Ik was zelf al plm 2 maanden geleden aan de slag gegaan en had een django app draaiend gekregen die ik als api gebruik. Op 18 juni exact werkte hij niet meer, wat jullie ongetwijfeld via mijn mail aan de helpdesk te weten zijn gekomen.

    Omdat verder niets lukte heb ik de hele app maar verwijderd en ben opnieuw begonnen. Toen ook dat een fout bleef geven heb ik slaafs je voorbeeld gevolgd en een demo app gemaakt zoals beschreven. Waar ik nu achter ben is het volgende: je kan de app niet in een folder op een niveau dieper installeren, zoals ik aanvankelijk gedaan had, en wat toen werkte. Het zat bij mij in : naam1/naam2/ in de virtual env. Waarschijnlijk worden zodoende paden niet gevonden. Ik heb alles nu direct in de hoofdfolder gezet, en via de url toch weer het path op naam1/naam2/ kunnen zetten. Ik heb nu gelukkig weer een django die reageert. Nu nog alles verder werkend krijgen. Ook gaat er bij het installeren van de mysql client nog iets fout, wat een algemeen probleem is: eerst moet pip geupdated worden van vs 9 naar vs 20. Dat kan via pip install –upgrade pip. Wellicht handig om dit in de tutorial te vermelden.
    Groeten, Robert

    • Bedankt voor de nuttige feedback, Robert! We hebben op basis daarvan een aantal aanpassingen aan het artikel doorgevoerd.

  3. Stefan op zei:

    Verrassend en tegelijkertijd geweldig nieuws !

    Vorig jaar al de vraag neergelegd bij Antagonist of er de mogelijkheid bestond om Python te draaien ….. ben erg blij dat hiernaar geluisterd is (zal vast niet de enige zijn geweest) en er nu ook de mogelijkheid bestaat om dit te gebruiken.

    Zelf gebruik ik al een aantal jaar web2py. Zou mooi zijn als ook hiervoor een korte instructie komt hoe dit in te richten.

    Goed gedaan

    • Bedankt voor je feedback, Stefan. Tof dat je er wat aan hebt! Het uitrollen van een Python-applicatie kan bij ons meestal, zoals je het ook gewend bent van andere platforms. De wens voor een Web2py-handleiding staat in ieder geval genoteerd. Mocht je daar trouwens erg thuis in zijn en vind je het leuk om er de basis voor aan te leveren, dan kan zo’n handleiding ook gezamenlijk tot stand komen. Deze info is verder wellicht nuttig voor nu: http://web2py.com/books/default/chapter/29/13/deployment-recipes#anyserver-py

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *