bionic upgrade, make image more generic

This commit is contained in:
dave 2018-10-07 13:50:47 -07:00
parent 0cf409047c
commit 5d50ccedf4
9 changed files with 171 additions and 26 deletions

View File

@ -1,17 +1,19 @@
FROM ubuntu:trusty
FROM ubuntu:bionic
# Create nexus user
# Nexus user for application usage
RUN useradd --create-home nexus && \
echo "nexus:nexus" | chpasswd && \
apt-get update && \
apt-get install -y nginx-light fcgiwrap supervisor openssh-server cron rsync && \
mkdir /start.d /nexus /var/run/sshd && \
echo "nexus:nexus" | chpasswd
# Packages
RUN apt-get update && \
apt-get install -y nginx-light fcgiwrap supervisor openssh-server cron rsync python3-pip
# Misc conf
RUN mkdir /start.d /nexus /var/run/sshd && \
chown nexus /nexus && \
cp /usr/share/doc/fcgiwrap/examples/nginx.conf /etc/nginx/fcgiwrap.conf && \
rm /etc/ssh/ssh_host_* && \
mkdir /etc/ssh/keys && \
sed -i -E 's/HostKey \/etc\/ssh\//HostKey \/etc\/ssh\/keys\//' /etc/ssh/sshd_config && \
sed -i -E 's/#?HostKey \/etc\/ssh\//HostKey \/data\/keys\//' /etc/ssh/sshd_config && \
rm -rf /var/lib/apt/lists/*
# Supervisor confs
@ -23,16 +25,25 @@ ADD supervisor-cron.conf /etc/supervisor/conf.d/cron.conf
# nginx confs
ADD nginx.conf /etc/nginx/nginx.conf
ADD nginx-default /etc/nginx/sites-available/default
ADD default /etc/nginx/sites-available/default
ADD fastcgi_params /etc/nginx/fastcgi_params
# scripts
ADD scripts/nexus /tmp/nexus
RUN cd /tmp/nexus && python3 install && rm -rf /tmp/nexus
# Startup tasks
ADD clear-sockets /start.d/clear-sockets
ADD gen-ssh /start.d/gen-ssh
ADD dir-setup /start.d/dir-setup
ADD start /start
RUN chmod +x /start.d/clear-sockets /start
RUN chmod +x /start.d/clear-sockets /start.d/gen-ssh /start.d/dir-setup /start
ENTRYPOINT ["/start"]
RUN sed -i -E 's/error_log .+/error_log \/var\/log\/nginx\/error.log debug;/' /etc/nginx/nginx.conf

View File

@ -1,10 +1,11 @@
# docker-nexus
**A nginx/cgi/sshd server for prototyping services or data hubs.**
**A nginx + cgi + sshd server for prototyping services or data hubs.**
## Quick start
* Clone: `git clone ssh://`
* Clone: `git clone ssh://`
* Build: `cd docker-nexus ; docker build -t nexus .`
* Run: `docker run nexus`
@ -13,28 +14,47 @@
Nexus offers a couple services:
### SSHD
For shell related activities, an sshd daemon runs on the standard port. Username and password, by default, is `nexus`.
Mount `/data/keys` to persist host keys.
### Nginx
For accessing data or calling CGI scripts, nginx runs on the standard port. The document root is `/nexus/`.
For accessing data or calling CGI scripts via nginx on port 80.
The document root is `/data/data/`.
### CGI
Standard CGI scripts can be placed in `/nexus/cgi-bin/`. Some sample scripts exist in `./examples/cgi-scripts/`.
CGI scripts can be placed in `/data/scripts/`. Some sample scripts exist in `./examples/cgi-scripts/`.
The library in `scripts/nexus/` can be imported like:
>>> from nexus.cgi import *
>>> start_response()
Status: 200 OK
Content-Type: text/html
### Cron
Cron is present in the container.
Cron is present in the container. Place tabs in `/etc/cron.d`.
## Protips
* Drop executable scripts into `/startup.d/` for effortless startup tasks
* Persistance? You want to mount these files/dirs outside the container:
* `/nexus/` - webroot and recommended data store
* `/etc/ssh/keys/` - sshd key file directory
* Drop executable scripts into `/startup.d/` for startup tasks
* Persistance - mount `/data/` somewhere persistent.

View File

@ -1,26 +1,33 @@
server {
listen 80 default_server;
#listen [::]:80 default_server ipv6only=on;
listen [::]:80 default_server ipv6only=on;
root /nexus/;
root /data/data/;
index index.html index.htm;
server_name localhost;
#client_body_temp_path /data/tmp/;
#auth_basic "Restricted";
#auth_basic_user_file /etc/nginx/htpasswd;
#auth_basic_user_file /data/htpasswd;
location / {
autoindex on;
try_files $uri $uri/ =404;
location /cgi-bin/ {
alias /data/scripts/;
gzip off;
fastcgi_pass unix:/tmp/fcgiwrap.socket;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /nexus$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME /data/scripts$fastcgi_script_name;
fastcgi_read_timeout 600s;
fastcgi_send_timeout 600s;
client_max_body_size 4096m;
client_max_body_size 0;
location /api/ {
rewrite ^/api/(.*) /cgi-bin/$1;

dir-setup Normal file
View File

@ -0,0 +1,6 @@
# Make /data/ dirs
mkdir -p /data/data
mkdir -p /data/scripts

fastcgi_params Normal file
View File

@ -0,0 +1,25 @@
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param HTTPS $https if_not_empty;
# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param REDIRECT_STATUS 200;

View File

@ -7,7 +7,8 @@ if [ ! -f "/etc/ssh/keys/ssh_host_rsa_key" ]; then
ssh-keygen -A
# Move keys to keys dir
mv /etc/ssh/ssh_host_* /etc/ssh/keys/
mkdir -p /data/keys/
mv /etc/ssh/ssh_host_* /data/keys/
rm /start.d/gen-ssh

View File

scripts/nexus/nexus/ Executable file
View File

@ -0,0 +1,54 @@
#!/usr/bin/env python3
import os
import sys
from urllib.parse import parse_qs as _parse_qs
from base64 import b64decode
def start_response(content_type="text/html", status_code=("200", "OK",), extra_headers=[], flush=True):
Begin the response by sending the beginning of an http response
print('Status: %s %s' % (status_code))
print("Content-Type: %s" % content_type)
for line in extra_headers:
if flush:
def parse_qs():
Parse the request's query string into a dict
TODO parse arrays
GET = {}
if "QUERY_STRING" in os.environ:
GET = _parse_qs(os.environ["QUERY_STRING"])
GET = {k: v[0] for k, v in GET.items()}
return GET
class HTTPBasicAuth:
username = None
password = None
def __str__(self):
return "<HTTPBasicAuth object username='%s' password='%s'>" % (self.username, self.password)
def parse_auth():
Parse the basic auth information from http headers. Returns None if not present
:return HTTPBasicAuth:
if "HTTP_AUTHORIZATION" in os.environ:
authtype, value = os.environ["HTTP_AUTHORIZATION"].split(' ')
if authtype == "Basic":
auth = HTTPBasicAuth()
auth.username, auth.password = b64decode(value).decode().split(":")
return auth
# cgi.print_environ()

scripts/nexus/ Normal file
View File

@ -0,0 +1,21 @@
#!/usr/bin/env python3
from setuptools import setup
__version__ = "0.0.0"
description='Helper function library for python cgi scripts',
# include_package_data=True,
# package_data={'photoapp': ['../templates/*.html',
# '../templates/fragments/*.html',
# '../styles/dist/*']},