🎉 Initial Version

This commit is contained in:
2023-03-01 21:55:32 +01:00
commit a1b823c61f
5 changed files with 173 additions and 0 deletions

23
Dockerfile Normal file
View File

@ -0,0 +1,23 @@
FROM alpine
RUN apk add --update --no-cache lighttpd python3 py3-pip nodejs php-cgi
RUN apk add --update --no-cache vim nano curl wget sed
RUN apk add --update --no-cache php81-bcmath php81-calendar php81-common php81-ctype php81-curl php81-dom php81-embed php81-exif php81-fileinfo php81-ftp php81-gd php81-gettext php81-gmp php81-iconv php81-imap php81-intl php81-json php81-mbstring php81-openssl php81-pcntl php81-pdo php81-pdo_sqlite php81-pear php81-session php81-simplexml php81-sockets php81-sodium php81-sqlite3 php81-sysvmsg php81-sysvsem php81-sysvshm php81-tidy php81-tokenizer php81-xml php81-xmlreader php81-xmlwriter php81-xsl php81-zip php81-pecl-xhprof php81-pecl-xhprof-assets php81-pecl-uuid php81-pecl-protobuf php81-pecl-xdebug php81-pecl-memcached php81-pecl-ssh2 php81-pecl-imagick php81-pecl-imagick-dev php81-pecl-vips php81-pecl-ast php81-pecl-event php81-pecl-redis php81-pecl-apcu php81-pecl-mailparse php81-pecl-msgpack php81-pecl-yaml php81-brotli php81-pecl-amqp php81-pecl-couchbase php81-pecl-igbinary php81-pecl-lzf
RUN pip3 install requests scrapy beautifulsoup4
COPY lighttpd.conf /etc/lighttpd/lighttpd.conf
RUN rm -r /var/www/localhost && mkdir /var/www/html && chown -R lighttpd:lighttpd /var/www/html
RUN touch /run/lighttpd.pid && chown lighttpd:lighttpd /run/lighttpd.pid
# Generate error pages
WORKDIR /tmp
COPY generate_errorpages.py ./
COPY errorpage_template.html ./
RUN mkdir /var/www/error_pages
RUN python3 /tmp/generate_errorpages.py /var/www/error_pages
RUN rm -rf /tmp
WORKDIR /
USER lighttpd
CMD ["/usr/sbin/lighttpd", "-D", "-f", "/etc/lighttpd/lighttpd.conf"]

30
README.md Normal file
View File

@ -0,0 +1,30 @@
# Scripted CGI Server
This Repository contains a Dockerfile to build a lighttpd cgi webserver that can not only run php, but also nodejs or python scripts on request. It may be useful for quickly deploying and updating small scripts and being able to trigger them via your browser or curl.
## Usage
Build the docker image
```
docker build -t cgi-server .
```
Run the container
```
docker run --restart unless-stopped -p 8080:80 -v /path/to/data:/var/www/html
```
Place either static .html files or script files (.py, .njs for nodejs or .php) in the data directory (mounted at `/var/www/html`)
## Custom error pages
To customize the error pages you could ...
1. Change the template file `errorpage_template.html` before building the docker image
2. Mount a volume at `/var/www/error_pages/`, for example:
```
-v /path/to/error_pages:/var/www/error_pages
```

39
errorpage_template.html Normal file
View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{title}}</title>
<style>
html,
body {
height: 100%;
margin: 0;
}
body {
background-color: #212121;
color: #eeeeee;
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
font-size: 28px;
font-family: Arial, Helvetica, sans-serif;
font-weight: lighter;
gap: 10px;
}
div.border {
width: 3px;
height: 30px;
background-color: #eeeeee;
}
</style>
</head>
<body>
<span>{{code}}</span>
<div class="border"></div>
<span>{{description}}</span>
</body>
</html>

25
generate_errorpages.py Normal file
View File

@ -0,0 +1,25 @@
import sys
file = open("errorpage_template.html", "r")
template_html = file.read()
error_pages = {
"400": "Bad Request",
"401": "Unauthorized",
"403": "Forbidden",
"404": "Not Found",
"405": "Method Not Allowed",
"413": "Payload Too Large",
"418": "I'm a teapot",
"429": "Too Many Requests",
"500": "Internal Server Error",
"503": "Service Unavailable",
"522": "Connection Timed Out",
"599": "Network Connect Timeout Error"
}
for error, description in error_pages.items():
f = open(f"{sys.argv[1]}/{error}.html", "w")
html = template_html.replace("{{code}}", error).replace("{{description}}", description).replace("{{title}}", f"{error} {description}")
f.write(html)
f.close()

56
lighttpd.conf Normal file
View File

@ -0,0 +1,56 @@
server.modules = (
"mod_indexfile",
"mod_access",
"mod_alias",
"mod_redirect",
"mod_rewrite",
"mod_cgi"
)
server.document-root = "/var/www/html"
server.errorfile-prefix = "/var/www/error_pages/"
server.errorlog = "/var/log/lighttpd/error.log"
server.pid-file = "/run/lighttpd.pid"
server.username = "lighttpd"
server.groupname = "lighttpd"
server.port = 80
# features
#https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_feature-flagsDetails
server.feature-flags += ("server.h2proto" => "enable")
server.feature-flags += ("server.h2c" => "enable")
server.feature-flags += ("server.graceful-shutdown-timeout" => 5)
#server.feature-flags += ("server.graceful-restart-bg" => "enable")
# strict parsing and normalization of URL for consistency and security
# https://redmine.lighttpd.net/projects/lighttpd/wiki/Server_http-parseoptsDetails
# (might need to explicitly set "url-path-2f-decode" = "disable"
# if a specific application is encoding URLs inside url-path)
server.http-parseopts = (
"header-strict" => "enable",# default
"host-strict" => "enable",# default
"host-normalize" => "enable",# default
"url-normalize-unreserved"=> "enable",# recommended highly
"url-normalize-required" => "enable",# recommended
"url-ctrls-reject" => "enable",# recommended
"url-path-2f-decode" => "enable",# recommended highly (unless breaks app)
"url-path-dotseg-remove" => "enable",# recommended highly (unless breaks app)
)
index-file.names = ( "index.html", "index.php", "index.py", "index.njs" )
static-file.exclude-extensions = (".php", ".py", ".njs")
cgi.assign = (".php" => "/usr/bin/php-cgi", ".py" => "/usr/bin/python3" , ".njs" => "/usr/bin/node")
$HTTP["url"] =~ "^/\.git/" {
url.access-deny = ("")
}
url.access-deny = ( "~", ".inc", ".env")
include "mime-types.conf"
#server.compat-module-load = "disable"
server.modules += (
"mod_dirlisting",
"mod_staticfile",
)