Python Flask app aan Docker in ISPConfig3 met Nginx - deel 1: Minimale app
ISPConfig is een geweldig hostingcontrolepaneel, maar het ondersteunt geen Python applicaties uit de doos. Dit bericht laat zien hoe je het kunt doen met behulp van Docker.
Dit is een post die laat zien hoe je een Flask app op ISPConfig3 kunt draaien. Waarom? Ik heb een VPS op het internet draaien Debian en ISPConfig3. Het beheert statische sites en PHP sites. Maar nu wil ik ook mijn Flask python apps hier draaien. Op deze manier kan ik gebruik maken van het domeinbeheer dat ik gewend ben en heb ik geen extra server nodig voor Python apps.
Deze oplossing gebruikt Docker voor het draaien van de Flask app, het afdrukken van 'Hallo World', en is een eerste proof of concept dat laat zien dat het mogelijk is om een Flasp app op ISPConfig3 in te zetten.
Mijn lokale machine:
- Ubuntu desktop 18.04.1
- Python3.6.7
- nginx 1,14,0
- Docker 18.09.0
- Docker-samenstellen 1.23.2
Mijn VPS:
- Debian 9 (Stretch)
- ISPConfig3 3.1.13
- Nginx 1.10.3
- dokwerker 18.09.0
- Docker-samenstellen 1.23.2
Probeer de Docker en Docker-samenstellen versies op beide machines identiek te houden. Docker ontwikkelaars slagen er soms niet in om achterwaartse compatibiliteit te behouden.
Inhoud:
- Stap 1: Creëer en run een Flask app helloworld op de lokale machine, met behulp van de ontwikkeling server
- Stap 2: Voer helloworld uit op de lokale machine, met behulp van de productieserver. Gunicorn
- Stap 3: Run helloworld op de lokale machine, met behulp van de Docker
- Stap 4: Op de lokale machine de dockarized hellewereld bedienen met een omgekeerde proxy nginx server
- Stap 5: Op de ISPConfig3 machine, zet de dockarized hellewereld in.
- Samenvatting
- Opmerkingen
Stap 1: Creëer en run een Flask app helloworld op de lokale machine, met behulp van de ontwikkeling server
1.1. Creëer een virtuele omgeving en activeer
Zie de instructies op het internet. Doe zoiets als:
> mkdir flask_docker
> cd flask_docker
> mkdir python3
> cd python3
> mkdir venvs
> python3 -m venv venvs/helloworld
> source venvs/helloworld/bin/activate
> cd venvs/helloworld
> pwd
.../flask_docker/python3/venvs/helloworld
1.2. Bekijk de directory helloworld
Je zou zoiets moeten zien:
.
|-- bin
|-- include
|-- lib
|-- lib64 -> lib
|-- __pycache__
|-- share
`-- pyvenv.cfg
All commands below are from this directory.
1.3. Installeer Flask
Type:
> pijp installeer de kolf
1.4. Creëer een eenvoudige Flask toepassing hello.py
Maak samen met je redacteur een Flask app helloworld.py:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return "<h1>Hello world!</h1>"
if __name__ == '__main__':
app.run()
1.5. Voer het uit met behulp van de ontwikkelingsserver
> python3 helloworld.python3 helloworld.py in
uw browser type: localhost:5000 U
zou het moeten zien: Hallo wereld
Stop de ontwikkelingsserver met Ctrl-C.
Stap 2: Voer helloworld uit op de lokale machine, met behulp van de productieserver. Gunicorn
2.1. Installeer de productieserver gunicorn
pip installeer de gunicorn
2.2. Maak een applicatie-object wsgi.py bestand voor gunicorn:
Maak de wsgi.py als volgt aan:
from helloworld import app
if __name__ == "__main__":
app.run()
We importeren gewoon de app uit helloworld.py.
2.3. Voer het uit met behulp van de gunicorn server
> gunicorn --bind 0.0.0.0.0:8000 wsgi:app In
uw browser type: localhost:80000 U zou
moeten zien: Hallo wereld (Hallo World
) Stop de gunicorn server met behulp van Ctrl-C.
Stap 3: Run helloworld op de lokale machine, met behulp van de Docker
3.1. Installeren Docker en Dockersamenstellen
Zie instructies op docker.com, digitalocean.com, etc.
Als je geen commando' Docker s kunt geven zonder sudo, voeg jezelf dan toe aan de Docker groep:
Stappen na de installatie voor Linux
https://docs.docker.com/install/linux/linux-postinstall/
3.2. Sla de benodigde software op in requirements.txt.
> pip freeze > requirements.txt Als
er een regel 'pkg-resources==0.0.0.0' aanwezig is in requirements.txt, verwijder deze dan.
Dit is een bug op sommige systemen.
Mijn requirements.txt bestand ziet er zo uit:
Click==7.0
Flask==1.0.2
gunicorn==19.9.0
itsdangerous==1.1.0
Jinja2==2.10
MarkupSafe==1.1.0
Werkzeug==0.14.1
3.3. Maak een Dockerbestand
Het Dockerdossier ziet er zo uit:
FROM python:3.6-alpine
RUN adduser -D helloworlduser
RUN mkdir -p /home/flask_app/helloworld
WORKDIR /home/flask_app/helloworld
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY helloworld.py wsgi.py boot.sh ./
RUN chmod +x boot.sh
ENV FLASK_APP helloworld.py
RUN chown -R helloworlduser:helloworlduser ./
USER helloworlduser
EXPOSE 5000
ENTRYPOINT ["./boot.sh"]
Het opstart-script boot.sh:
#!/bin/sh
# called by Dockerfile
# go to directory where wsgi.py is
cd /home/flask_app/helloworld
# start gunicorn
exec gunicorn -b :5000 --access-logfile - --error-logfile - wsgi:app
De directory ziet er nu zo uit:
.
|-- bin
|-- include
|-- lib
|-- lib64 -> lib
|-- __pycache__
|-- share
|-- boot.sh
|-- docker-compose.yml
|-- Dockerfile
|-- Dockerfile_web
|-- helloworld.py
|-- image_helloworld.tar
|-- pyvenv.cfg
|-- requirements.txt
`-- wsgi.py
3.4. Bouw het containerbeeld op
> Docker build -t helloworld:latest .
De output eindigt met iets als...:
...
Successfully built d3e8bc220161
Successfully tagged helloworld:latest
U kunt controleren of de container is aangemaakt:
> Dockers beelden
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld latest d3e8bc220161 2 minutes ago 84.8MB
python 3.6-alpine 1837080c5e87 5 weeks ago 74.4MB
3.5. Voer de containerafbeelding uit
Voer eerst de container als voorgrondtoepassing uit, d.w.z. zonder de optie -d:
> Docker run --naam helloworld -p 8001:5000 -rm helloworld: latest
Dit zal debug-informatie tonen. Als er iets mis is, bijvoorbeeld in boot.sh, kunt u dit corrigeren en de container opnieuw bouwen:
> Docker build -t helloworld:latest .
U kunt ook de container invoeren om te zien wat er gebeurt, bijvoorbeeld of de bestanden er echt zijn:
> dokwerker -het-ingangspunt /bin/sh-rm hellowoworld: recentste
Als alles in orde is, kunt u de container op de achtergrond laten draaien met de -d optie:
> Docker run --naam helloworld -d -p 8001:5000 -rm hellowoworld: latest
In uw browser type: localhost:80001
Je zou het moeten zien: Hallo wereld
Controleer of de container loopt:
> Dokwerker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
37f06d44cd30 helloworld:latest "./boot.sh" 4 seconds ago Up 4 seconds 0.0.0.0:8001->5000/tcp helloworld
Controleer de logboeken:
> Docker logs helloworld
[2019-02-02 14:52:57 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2019-02-02 14:52:57 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
[2019-02-02 14:52:57 +0000] [1] [INFO] Using worker: sync
[2019-02-02 14:52:57 +0000] [9] [INFO] Booting worker with pid: 9
Om de container te stoppen:
> dokwerker doodt hellewereld
Controleer of de container niet meer loopt:
> Dokwerker ps
Stap 4: Op de lokale machine de dockarized hellewereld bedienen met een omgekeerde proxy Nginx server
4.1. Installeer Nginx op de lokale machine
Als het nog niet geïnstalleerd is:
> sudo apt installeren nginx installeren
4.2. Configureer Nginx
We gaan de helloworld.net website bedienen op poort 8080. Configureer als een Nginx omgekeerde, d.w.z proxy. het leidt de verzoeken van de klant naar onze Gunicorn server die draait op .
Maak een bestand /etc/nginx/sites-available/helloworld.conf aan:
server {
listen 8080;
server_name helloworld.net;
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 1M;
}
}
Maak een symbolische link aan in /etc/nginx/sites-enabled:
> sudo ln -s /etc/nginx/sites-beschikbaar/helloworld.conf /etc/nginx/sites-enabled/helloworld.conf
Herstart Nginx:
> sudo systemctl heropstarten nginx
Als er iets misgaat, kijk dan naar de status:
> sudo systemctl status nginx.service
4.3. Voeg helloworld.net toe aan het hosts-bestand
> sudo nano /etc/hosts
Voeg een regel toe:
127,0,0,0,1 heloworld.net
Controleer of het werkt, het zou 127.0.0.0.1 op ping moeten reageren:
> ping helloworld.net
PING helloworld.net (127.0.0.1) 56(84) bytes of data.
64 bytes from helloworld.net (127.0.0.1): icmp_seq=1 ttl=64 time=0.023 ms
64 bytes from helloworld.net (127.0.0.1): icmp_seq=2 ttl=64 time=0.042 ms
Bij chroom (chroom) kunt u de dns controleren en verwijderen door de adresbalk in te typen:
chroom://netto-intern/#dns
4.4. Start de container en krijg toegang tot uw website
In uw browser type: helloworld.net:8080
Als u de helloworld docker containerafbeelding nog niet hebt gestart, wordt de browser weergegeven:
502 Slechte poort
Start uw container:
> Docker run --naam helloworld -d -p 8001:5000 -rm hellowoworld: latest
In je browser zou je het moeten zien: Hallo wereld
Stap 5: Op de ISPConfig3 VPS, zet de dockarized hellewereld in...
We hebben nu een Docker containerbeeld dat werkt op onze lokale machine. Om dit op onze ISPConfig3 machines te laten draaien hebben we verschillende opties. Hier gebruiken we: kopieer de Docker afbeelding naar een andere host.
5.1. Installeren Docker en Docker-samenstellen op de VPS
Volg de installatieprocedures.
5.2. Kopieer Dockerbestand en dockerafbeelding naar ISPConfig3 machines
Lokaliseer ons imago:
> Dockers beelden
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld latest bee00f1c8607 21 hours ago 84.8MB
Sla de dockerafbeelding op als een teerbestand:
> docker save -o ./image_helloworld.tar helloworld.tar helloworld
Gebruik een programma voor bestandsoverdracht om het Dockerbestand en de afbeelding naar de ISPConfig3 machines te kopiëren.
Ga op de ISPConfig3 machines naar de directory waar de bestanden zich bevinden en voeg onze afbeelding toe aan Docker:
> docker load -i image_helloworld.tar
Dit kan enige tijd duren. Controleer of de afbeelding beschikbaar is:
> Dockers beelden
REPOSITORY TAG IMAGE ID CREATED SIZE
helloworld latest bee00f1c8607 21 hours ago 84.8MB
5.3. Configureer uw site in ISPConfig3
Aangenomen wordt dat u al een domeinnaam heeft die naar uw ISPConfig3 machines verwijst, u heeft het domein toegevoegd, en de site toegevoegd. In dit geval bij het intypen van uw browser:
<Domein>
moet je zoiets zien als...:
Welcome to your website!
Log in op ISPConfig3.
Ga naar: Sites->Uw site
In het tabblad Domein:
- CGI uitvinken
- PHPgehandicapten
Klik op Opslaan.
In het tabblad Opties
Het volgende toevoegen aan de Nginx-richtlijnen:
location / {
proxy_pass http://127.0.0.1:8001;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 1M;
}
Klik op Opslaan.
Als uw site werkte voordat deze nu zou moeten worden getoond:
ERROR 502 - Bad Gateway!
5.4. Start de container
> Docker run --naam helloworld -p 8001:5000 -rm helloworld: latest
Nu na het intypen van uw browser:
<Domein>
je moet het zien: Hallo wereld
Geweldig!
Stop de Docker Flask app:
> dokwerker doodt hellewereld
Controleer of het weg is:
> Dokwerker ps
Samenvatting
We hebben een eenvoudige Flask app gemaakt en deze op onze ISPConfig3 machines ingezet.
In een volgende post zullen we een geavanceerder voorbeeld gebruiken:
- Meerdere pagina's serveren
- Statische bestanden serveren
- Verbinding maken met de ISPConfig3 database
Opmerkingen
1. U kunt de Flask Interactieve Debugger in ontwikkeling
inschakelen met Gunicorn
https://nickjanetakis.com/blog/enabling-the-flask-interactive-debugger-in-development-with-gunicorn Gunicorn altijd gebruiken voor ontwikkeling.
Links / credits
Deploy flask app with nginx using gunicorn and supervisor
https://medium.com/ymedialabs-innovation/deploy-flask-app-with-nginx-using-gunicorn-and-supervisor-d7a93aa07c18
Embedding Python In Apache2 With mod_python (Debian/Ubuntu, Fedora/CentOS, Mandriva, OpenSUSE)
https://www.howtoforge.com/embedding-python-in-apache2-with-mod_python-debian-ubuntu-fedora-centos-mandriva-opensuse
How to Configure NGINX for a Flask Web Application
https://www.patricksoftwareblog.com/how-to-configure-nginx-for-a-flask-web-application/" target="_blank">How to Configure NGINX for a Flask
How to copy Docker images from one host to another without using a repository
https://stackoverflow.com/questions/23935141/how-to-copy-docker-images-from-one-host-to-another-without-using-a-repository
How to deploy a django application on a linux (Debian/Ubuntu) production server running ISPConfig 3
http://blog.yawd.eu/2011/how-to-deploy-django-app-linux-server-ispconfig/
How To Serve Flask Applications with Gunicorn and Nginx on Ubuntu 18.04
https://www.digitalocean.com/community/tutorials/how-to-serve-flask-applications-with-gunicorn-and-nginx-on-ubuntu-18-04
The Flask Mega-Tutorial Part XIX: Deployment on Docker Containers
https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-xix-deployment-on-docker-containers
Recent
- Database UUID primaire sleutels van je webapplicatie verbergen
- Don't Repeat Yourself (DRY) met Jinja2
- SQLAlchemy, PostgreSQL, maximum aantal rijen per user
- Toon de waarden in SQLAlchemy dynamische filters
- Veilige gegevensoverdracht met Public Key versleuteling en pyNaCl
- rqlite: een alternatief voor SQLite met hoge beschikbaarheid en distributed
Meest bekeken
- Met behulp van Python's pyOpenSSL om SSL-certificaten die van een host zijn gedownload te controleren
- Gebruik van UUIDs in plaats van Integer Autoincrement Primary Keys met SQLAlchemy en MariaDb
- Maak verbinding met een dienst op een Docker host vanaf een Docker container
- PyInstaller en Cython gebruiken om een Python executable te maken
- SQLAlchemy: Gebruik van Cascade Deletes om verwante objecten te verwijderen
- Flask RESTful API verzoekparametervalidatie met Marshmallow-schema's