Making a WebApp from a shell script
I've recently written a shellscript for a personal need and thought it would be useful to other people. But how could I make this usable to non-tech people?
I've converted it to a simple web application:
- a form
- the script
Let's go through the steps that make this possible.
Select a light and convenient Web server #
The Web server needs to be lightweight and able to execute code. mini_httpd is the perfect choice for this!
We'll run it as into a Docker container. Let's create a file named Dockerfile
with the following contents:
FROM alpine:latest
RUN apk add --update mini_httpd bash
COPY . /app
EXPOSE 80
CMD [ "mini_httpd", "-h", "0.0.0.0", "-dd", "/app", "-r", "-c", "**.sh", "-D" ]
The CMD
line starts the Web server:
- with document root configured in
/app
folder - in a
chroot
for higher security - that will run
**.sh
files (all files ending with.sh
extension)
You can now build and run this Docker image:
docker build . -t shellscript-cgi
docker run --rm -t -p 8080:80 shellscript-cgi
If you load http://localhost:8080 in your Web browser, you'll see the index of the working dir:
Index of ./
. 29Nov2022 20:39 4096
.. 29Nov2022 20:43 4096
Dockerfile 29Nov2022 20:37 162
mini_httpd/1.30 26Oct2018
Add a simple script #
Let's add a non-interactive script. This script will return the output of a
command (in this example, we'll get the system uptime
).
Create a file named uptime.sh
with the following contents:
#!/usr/bin/env sh
echo "Content-type: text/plain"
echo
uptime
Make it executable:
chmod +x uptime.sh
Then stop the running Docker container (Ctrl-C
), rebuild the image and run the
new container:
docker build . -t shellscript-cgi
docker run --rm -t -p 8080:80 shellscript-cgi
Now if you load http://localhost:8080/uptime.sh you'll get the system uptime:
20:49:47 up 7 days, 13:39, 0 users, load average: 5.09, 2.89, 1.96
Handle input arguments #
Now let's deal with input arguments. We'll only cover GET
arguments in this
article.
Parsing of input arguments will be done through
ColasNahaboo's Cgibashopts.
Download the cgibashopts
into your working directory.
Now create the hello.sh
script with the following contents:
#!/bin/bash
source cgibashopts
echo "Content-type: text/plain; charset=utf-8"
echo
echo "Hello, $FORM_name"
Make it executable:
chmod +x hello.sh
Then stop the running Docker container (Ctrl-C
), rebuild the image and run the
new container:
docker build . -t shellscript-cgi
docker run --rm -t -p 8080:80 shellscript-cgi
Now if you load http://localhost:8080/hello.sh?name=Sébastien you'll get a nice welcome message 🙂 :
Hello, Sébastien!
Going further #
In this article we only went through simple cases. Real-life applications will probably have more advanced needs.
The script I was talking about at the beginning of this article is a PDF watermarking tool. This tool deals with:
POST
request- file upload
- advanced external commands (image & PDF manipulation)
You can look at its code there: https://code.pipoprods.org/web/watermark-pdf.
Let's discuss about this on Mastodon!