/ html / wiki / tutorials / nginx-tutorials / nginx-cgi / nginx-cgi.html
nginx-cgi.html
  1  <!DOCTYPE html>
  2  <html lang="de">
  3     <head>
  4        <meta charset="UTF-8" />
  5        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6        <meta http-equiv="onion-location" content="http://bopbopl6lohkl2rts3ltesjnag4hzs4jrx2h6k6etgq5xasbpqekzlqd.onion" />
  7        <title>BOP Wiki: Execute BASH Scripts (CGI) & HTMX updates</title>
  8        <link rel="stylesheet" href="/assets/stylesheet.css" />
  9        <link rel="icon" type="image/x-icon" href="/assets/img/favicon.png">
 10     </head>
 11     <body>
 12        <header>
 13           <!-- --------------------------------------------------------------------------------------------------------------------------------- -->
 14           <script src="/assets/js/navbar-OpenClose.js"></script>
 15           <script src="/assets/js/lightbox.js"></script>
 16            <script src="/assets/js/copyCodeButton.js"></script>
 17           <link rel="stylesheet" href="/resources/js-libraries/highlightJS/atom-one-dark.min.css">
 18           <script src="/resources/js-libraries/highlightJS/highlight.min.js"></script>
 19           <script src="/resources/js-libraries/highlightJS/highlightjs-line-numbers.min.js"></script>
 20           <script>hljs.highlightAll();</script>
 21           <script>hljs.initLineNumbersOnLoad();</script>
 22           <!-- --------------------------------------------------------------------------------------------------------------------------------- -->
 23           <div class="branding">
 24              <button class="toggle-btn-navbar" id="navbarOpenButton">☰</button>
 25              <a href="/">
 26              <img class="logo" src="/assets/img/logo.png">
 27              </a>
 28              <div class="typing-animation">BytesOfProgress</div>
 29           </div>
 30        </header>
 31        <div id="navbarContainer" class="navbar-container">
 32           <iframe class="navbar-iframe" src="/assets/navbar/navbar.html" frameBorder= "0"></iframe>
 33        </div>
 34        <main>
 35           <article class="blog-post">
 36              <header class="post-header">
 37                 <h1 class="post-title">Execute BASH Scripts (CGI) & HTMX updates</h1>
 38              </header>
 39           </article>
 40           <nav class="breadcrumb">
 41              <a href="/">Home</a>
 42              <span class="divider">›</span>
 43              <a href="/wiki/">Wiki</a>
 44              <span class="divider">›</span>
 45              <a href="/wiki/tutorials/tutorials.html">Tutorials</a>
 46              <span class="divider">›</span>
 47              <a href="/wiki/tutorials/nginx-tutorials/nginx-tutorials.html">Nginx Tutorials</a>
 48              <span class="divider">›</span>
 49              <span class="current">Execute BASH Scripts (CGI) & HTMX updates</span>
 50           </nav>
 51           <section class="post-content">
 52              <p>In this guide we will set up a way to execute BASH scripts with Nginx &amp; fastcgi. After that we will make it update itself without reloading the page by using HTMX.</p>
 53              <h2>Setting it up</h2>
 54              <p>This method is tested on Debian 12.</p>
 55              <h2>Step 1: Install nginx and fastcgi</h2>
 56              <blockquote>
 57                # apt install nginx fcgiwrap -y
 58              </blockquote>
 59                <h2>Step 2: Modify your server config file</h2>
 60              <p>Usually it is located at <code>/etc/nginx/sites-available/default</code>.</p>
 61              <div class="code-box">
 62                <pre><code>server {
 63      listen 8088;
 64      server_name NAME;
 65  
 66      root /var/www/html;
 67      index index.html;
 68  
 69      location /cgi-bin/ {
 70          alias /usr/lib/cgi-bin/; # Default path for cgi scripts.
 71          fastcgi_pass unix:/var/run/fcgiwrap.socket;
 72          include fastcgi_params;
 73          fastcgi_param SCRIPT_FILENAME /usr/lib$fastcgi_script_name;
 74      }
 75  }</code></pre>
 76              </div>
 77              <p>After that, test the nginx config with:</p>
 78              <blockquote>
 79                # nginx -t
 80              </blockquote>
 81              <p>On success, restart the nginx system service:</p>
 82              <blockquote>
 83                # systemctl restart nginx
 84              </blockquote>
 85              <h2>Step 3: Write your BASH script</h2>
 86              <p>Create a file in <code>/usr/lib/cgi-bin</code>. If the directory does not exist yet, create it with <code>mkdir</code>.</p>
 87              <blockquote>
 88                # nano /usr/lib/cgi-bin/script.sh
 89              </blockquote>
 90              <p>Example BASH script:</p>
 91              <div class="code-box"><pre><code>#!/bin/sh
 92          
 93  echo "Content-Type: text/html"
 94  echo ""
 95  echo "&lt;!DOCTYPE html&gt;"
 96  echo "&lt;html lang=&quot;de&quot;&gt;"
 97  echo "&lt;head&gt;"
 98  echo "  &lt;meta charset=&quot;UTF-8&quot;&gt;"
 99  echo "  &lt;title&gt;Monitoring&lt;/title&gt;"
100  echo "  &lt;link rel=&quot;icon&quot; type=&quot;image/x-icon&quot; href=&quot;/assets/favicon.png&quot;&gt;"
101  echo "  &lt;style&gt;"
102  echo "    body { font-family: Arial, sans-serif; color: #ffffff; background-color: #000000; }"
103  echo "    .section { margin-bottom: 20px; }"
104  echo "    .section h2 { margin: 0; }"
105  echo "    pre { color: #ffffff; font-size: 14px; white-space: pre-wrap; }"
106  echo "  &lt;/style&gt;"
107  echo "&lt;/head&gt;"
108  echo "&lt;body&gt;"
109  
110  # RAM Usage
111  echo "&lt;div class='section'&gt;"
112  echo "&lt;h2&gt;RAM Usage:&lt;/h2&gt;"
113  echo "&lt;pre&gt;"
114  echo "$(awk '/MemTotal/ {total=\$2} /MemAvailable/ {available=\$2} END {usage=((total-available)/total)*100; printf \"Percent: %.2f%%\\n\", usage}' /proc/meminfo)"
115  echo "$(awk '/MemTotal/ {total=\$2} /MemAvailable/ {available=\$2} END {printf \"MiB: %d / %d MiB\\n\", (total-available)/1024, total/1024}' /proc/meminfo)"
116  echo "&lt;/pre&gt;"
117  echo "&lt;/div&gt;"
118  
119  # Uptime
120  echo "&lt;div class='section'&gt;"
121  echo "&lt;h2&gt;Uptime:&lt;/h2&gt;"
122  echo "&lt;pre&gt;$(uptime -p | sed 's/up //')&lt;/pre&gt;"
123  echo "&lt;/div&gt;"
124  
125  echo "&lt;/body&gt;"
126  echo "&lt;/html&gt;"
127  
128  # Removing temporary files.
129  rm /tmp/stat1 /tmp/stat2</code></pre>
130          </div>
131              <h2>Important</h2>
132              <ul>
133                 <li>
134                    Make sure you have these two lines at the beginning of your script:
135                    <div class="code-box">
136                    <pre><code>echo "Content-Type: text/html"
137  echo ""</code></pre>
138                    </div>
139                 </li>
140                 <li>Without them, your script won't work properly.</li>
141              </ul>
142              <h2>Step 4: Start &amp; enable fcgiwrap</h2>
143              <blockquote>
144                # systemctl start fcgiwrap && systemctl enable fcgiwrap
145              </blockquote>
146              <h2>Step 5: Testing</h2>
147              <p>If you now enter the IPv4 address of your webserver into your browser and add <code>/cgi-bin/script.sh</code> at the end, you should see your script output.</p>
148              <h2>Automating live updates with HTMX</h2>
149              <h2>HTMX setup</h2>
150              <p>Edit your <code>/var/www/html/index.html</code> and add the following lines:</p>
151              <blockquote>
152                &lt;script src="https://unpkg.com/htmx.org@2.0.1"&gt;&lt;/script&gt;
153              </blockquote>
154              <h3>Adding the auto-update div</h3>
155              <p>Add this snippet inside your <code>index.html</code>:</p>
156              <div class="code-box">
157                <pre><code>&lt;div hx-get="/cgi-bin/script.sh" hx-swap="innerHTML" hx-trigger="every 1s"&gt;
158  &lt;!-- Script Content --&gt;
159  &lt;/div&gt;</code></pre>
160              </div>
161              <h2>Notes</h2>
162              <p>This will create a <code>div</code> that reloads its content from the CGI script every one second without refreshing the whole page. You can change the interval if you want.</p>
163              <p><strong>Info on CSS, title, etc:</strong> To change the title, favicon and CSS, you might have to edit the CGI script instead of relying solely on your <code>index.html</code> stylesheets.</p>
164           </section>
165           <footer class="post-footer">
166              <a href="/wiki/tutorials/nginx-tutorials/nginx-tutorials.html" class="cta-button">← Back</a>
167           </footer>
168        </main>
169     </body>
170  </html>