1
0
Эх сурвалжийг харах

Add details and examples in docs for running apps with https (#3213)

* docs(section_configuration_deployment): add details and examples for https

* chore: run pre-commit

* feat: make the https example 'executable'

* formatting

* formatting

---------

Co-authored-by: Rodja Trappe <rodja@zauberzeug.com>
Thomas Lamant 11 сар өмнө
parent
commit
8eeb8ac634

+ 47 - 0
examples/nginx_https/README.md

@@ -0,0 +1,47 @@
+# Serving an App with HTTPS encryption behind a Reverse Proxy (NGINX)
+
+This example shows how to serve NiceGUI with HTTPS encryption behind NGINX.
+For running the App under a Subpath, have a look at https://github.com/zauberzeug/nicegui/blob/main/examples/nginx_subpath.
+
+## Try Out
+
+1. Create the `certs/` directory:
+
+   ```bash
+   mkdir certs
+   ```
+
+2. Generate and self-sign SSL an certificate for `localhost`
+
+   ```bash
+   openssl req -x509 -out certs/localhost.crt -keyout certs/localhost.key -newkey rsa:2048 -nodes -sha256 -subj '/CN=localhost' -extensions EXT -config <( printf "[dn]\nCN=localhost\n[req]\ndistinguished_name = dn\n[EXT]\nsubjectAltName=DNS:localhost\nkeyUsage=digitalSignature\nextendedKeyUsage=serverAuth")
+   ```
+
+3. Run the containerized app
+
+   ```bash
+   docker compose up
+   ```
+
+4. Try to access http://localhost without the "s".
+   You will be automatically redirected to the https version.
+
+5. Depending on your browser, you should typically receive a warning that the certificate authority is invalid.
+   This is perfectly normal as we issued and self-signed a simple certificate for demo use locally.
+   So proceed anyway, e.g. on Chrome, click on `Advanced` > `Proceed to localhost (unsafe)`
+
+6. Note the Hello World message from the app accessed with encrypted connection
+
+## Deploy in production in your self-hosted NGINX
+
+- For production, you'll need your own domain and a proper SSL certificate issued by a recognized Certificate Authority (CA).
+  You can consider the free CA [Let's Encrypt](https://letsencrypt.org/) provided by the Internal Security Research Group, and use their [Certbox](https://certbot.eff.org/instructions) tool to generate the certicates for your own domain.
+
+- If you already have an NGINX server running and want to add your NiceGUI app, you can reuse a stripped down version of the nginx.conf file, [nginx_site.conf](https://github.com/zauberzeug/nicegui/blob/main/example/nginx_https/nginx_site.conf)
+
+```bash
+sudo cp nginx_site.conf /etc/nginx/sites-available/my_nicegui_app.conf
+sudo nano /etc/nginx/sites-available/my_nicegui_app.conf # customize your domain, certificates, port number, etc.
+sudo ln -s /etc/nginx/sites-available/mynicegui_app.conf /etc/nginx/sites-enabled
+sudo systemctl reload nginx
+```

+ 5 - 0
examples/nginx_https/app/main.py

@@ -0,0 +1,5 @@
+from nicegui import ui
+
+ui.label('Hello HTTPS encrypted world')
+
+ui.run()

+ 13 - 0
examples/nginx_https/docker-compose.yml

@@ -0,0 +1,13 @@
+services:
+  app:
+    image: zauberzeug/nicegui:1.4.27
+    volumes:
+      - ./app:/app # mount local app directory
+  proxy:
+    image: nginx:1.27.0-alpine
+    ports:
+      - "80:80" # map internal port 80 to external port 80
+      - "443:443" # map internal port 443 to external port 443
+    volumes:
+      - ./nginx.conf:/etc/nginx/nginx.conf # use custom nginx config
+      - ./certs:/certs

+ 53 - 0
examples/nginx_https/nginx.conf

@@ -0,0 +1,53 @@
+worker_processes  1;
+
+events {
+    worker_connections  1024;
+}
+
+
+http {
+    include       mime.types;
+    default_type  application/octet-stream;
+
+
+    sendfile        on;
+    keepalive_timeout  65;
+
+    server {
+        listen 80;
+        listen [::]:80;
+        server_name _;
+        resolver 127.0.0.11; # Specific to running nginx proxy in docker
+                             # See https://github.com/docker/compose/issues/3412
+
+        # Redirect all HTTP requests to HTTPS
+        return 301 https://$host$request_uri;
+    }
+
+    server {
+        listen 443 ssl;
+        listen [::]:443 ssl;
+        http2 on;
+        server_name _;
+        resolver 127.0.0.11; # Specific to running nginx proxy in docker
+                             # See https://github.com/docker/compose/issues/3412
+
+        # SSL configuration
+        ssl_certificate /certs/localhost.crt;
+        ssl_certificate_key /certs/localhost.key;
+        ssl_session_timeout 1d;
+
+        # Proxy pass to app:8080
+        location / {
+            proxy_pass http://app:8080;
+            proxy_redirect http://app:8080/ /;
+            proxy_set_header Host $host;
+            proxy_set_header X-Real-IP $remote_addr;
+            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+            proxy_set_header X-Forwarded-Proto $scheme;
+            proxy_http_version 1.1;
+            proxy_set_header Upgrade $http_upgrade;
+            proxy_set_header Connection "Upgrade";
+        }
+    }
+}

+ 32 - 0
examples/nginx_https/nginx_site.conf

@@ -0,0 +1,32 @@
+server {
+    listen 80;
+    listen [::]:80;
+    server_name my-domain.com;
+
+    # Redirect all HTTP requests to HTTPS
+    return 301 https://$host$request_uri;
+}
+
+server {
+    listen 443 ssl;
+    listen [::]:443 ssl;
+    http2 on;
+    server_name my-domain.com;
+
+    # SSL configuration
+    ssl_certificate /etc/letsencrypt/live/my-domain.com/fullchain.pem;
+    ssl_certificate_key /etc/letsencrypt/live/my-domain.com/privkey.pem;
+    ssl_session_timeout 1d;
+
+    # Proxy pass to localhost:8080
+    location / {
+        proxy_pass http://localhost:8080;
+        proxy_set_header Host $host;
+        proxy_set_header X-Real-IP $remote_addr;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Proto $scheme;
+        proxy_http_version 1.1;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection "Upgrade";
+    }
+}

+ 26 - 2
website/documentation/content/section_configuration_deployment.py

@@ -134,9 +134,33 @@ doc.text('', '''
     There are other handy features in the Docker image like non-root user execution and signal pass-through.
     For more details we recommend to have a look at our [Docker example](https://github.com/zauberzeug/nicegui/tree/main/examples/docker_image).
 
-    You can provide SSL certificates directly using [FastAPI](https://fastapi.tiangolo.com/deployment/https/).
+    To serve your application with [HTTPS](https://fastapi.tiangolo.com/deployment/https/) encryption, you can provide SSL certificates in multiple ways.
+    For instance, you can directly provide your certificates to [Uvicorn](https://www.uvicorn.org/), which NiceGUI is based on, by passing the
+    relevant [options](https://www.uvicorn.org/#command-line-options) to `ui.run()`:
+''')
+
+
+@doc.ui
+def uvicorn_ssl():
+    with python_window('main.py', classes='max-w-lg w-full'):
+        ui.markdown('''
+            ```python
+            from nicegui import ui
+
+            ui.run(
+                port=443, 
+                ssl_certfile="<path_to_certfile>", 
+                ssl_keyfile="<path_to_keyfile>",
+            )
+            ```
+        ''')
+
+
+doc.text('', '''
     In production we also like using reverse proxies like [Traefik](https://doc.traefik.io/traefik/) or [NGINX](https://www.nginx.com/) to handle these details for us.
-    See our development [docker-compose.yml](https://github.com/zauberzeug/nicegui/blob/main/docker-compose.yml) as an example.
+    See our development [docker-compose.yml](https://github.com/zauberzeug/nicegui/blob/main/docker-compose.yml) as an example based on traefik or
+    [this example nginx.conf file](https://github.com/zauberzeug/nicegui/blob/main/examples/nginx_https/nginx.conf) showing how NGINX can be used to handle the SSL certificates and
+    reverse proxy to your NiceGUI app.
 
     You may also have a look at [our demo for using a custom FastAPI app](https://github.com/zauberzeug/nicegui/tree/main/examples/fastapi).
     This will allow you to do very flexible deployments as described in the [FastAPI documentation](https://fastapi.tiangolo.com/deployment/).