Compare commits

..

No commits in common. "1e7531e63270c3b400a4bc40d57c0997c22117a7" and "ee38b2468e1a091241c2460d0e06d40d03ec76ce" have entirely different histories.

6 changed files with 40 additions and 273 deletions

View File

@ -1,18 +1,15 @@
# node-livereload server supporting SSL/TLS
# LiveReload-npm server supporting SSL/TLS
# allow dynamic building by specifying base image elements as build-args
ARG NODE_VERSION=16
ARG ALPINE_VERSION=3.14
FROM node:${NODE_VERSION}-alpine${ALPINE_VERSION}
# create new node user with set id from build-arg and create volume directories
# create new node user with set id from build-arg
ARG NODE_UID=9999
RUN deluser --remove-home node \
&& addgroup -g ${NODE_UID} -S node \
&& adduser -G node -S -u ${NODE_UID} node \
&& mkdir /watch /certs \
&& chown root:node /certs \
&& chmod 770 /certs
&& adduser -G node -S -u ${NODE_UID} node
# create default volumes in-case user forgets, expose default port
VOLUME [ "/watch", "/certs" ]
@ -26,8 +23,8 @@ RUN apk --update --no-cache add \
# labels
LABEL org.opencontainers.image.authors="Asif Bacchus <asif@asifbacchus.dev>"
LABEL org.opencontainers.image.title="node-livereload-tls"
LABEL org.opencontainers.image.description="Dockerized node-livereload supporting TLS and running under limited user account. Environment variables allow specifying files to watch/exclude and notification delay."
LABEL org.opencontainers.image.title="livereload npm"
LABEL org.opencontainers.image.description="Dockerized npm livereload supporting TLS and running under limited user account. Environment variables allow specifying files to watch/exclude and notification delay."
LABEL org.opencontainers.image.url="https://git.asifbacchus.dev/ab-docker/livereload"
LABEL org.opencontainers.image.documentation="https://git.asifbacchus.dev/ab-docker/livereload/raw/branch/master/README.md"
LABEL org.opencontainers.image.source="https://git.asifbacchus.dev/ab-docker/livereload.git"
@ -42,10 +39,8 @@ ENV LR_EXTS="html,xml,css,js,jsx,ts,tsx,php,py"
ENV LR_EXCLUDE=".git/,.svn/,.vscode/,.idea/"
ENV LR_DELAY=500
ENV LR_DEBUG=true
ENV LR_HTTPS=true
ENV CERT_HOSTNAME=""
# install node-livereload as node user then switch back to root user
# install livereload npm as node user then switch back to root user
USER node
WORKDIR /home/node
RUN mkdir -p .npm-global/bin .npm-global/lib \
@ -55,13 +50,11 @@ RUN mkdir -p .npm-global/bin .npm-global/lib \
# copy scripts and fix-up all permissions
USER root
COPY [ "selfsigned.cnf", "/etc/selfsigned.cnf" ]
COPY [ "livereload.js", "/home/node/livereload.js" ]
COPY [ "entrypoint.sh", "/usr/local/bin/entrypoint.sh" ]
RUN chown node:node /home/node/livereload.js \
&& chmod 644 /home/node/livereload.js \
&& chmod 755 /usr/local/bin/entrypoint.sh \
&& chmod 644 /etc/selfsigned.cnf
&& chmod 755 /usr/local/bin/entrypoint.sh
# switch to node user, run entrypoint script by default
USER node
@ -69,12 +62,13 @@ WORKDIR /home/node
ENTRYPOINT [ "/sbin/tini", "--", "/usr/local/bin/entrypoint.sh" ]
# set build timestamp and version labels
ARG INTERNAL_VERSION
ARG BUILD_DATE
LABEL org.opencontainers.image.version="16.5.0, 0.9.3"
LABEL org.opencontainers.image.vendor="NODE.js, node-livereload"
LABEL dev.asifbacchus.image.name="node-livereload-tls"
LABEL dev.asifbacchus.image.version=${INTERNAL_VERSION}
LABEL org.opencontainers.image.created=${BUILD_DATE}
# TODO: uncomment when done testing
#ARG INTERNAL_VERSION
#ARG BUILD_DATE
#LABEL org.opencontainers.image.version="16.5.0, 0.9.3"
#LABEL org.opencontainers.image.vendor="NODE.js, node-livereload"
#LABEL dev.asifbacchus.image.name="livereload-tls-npm"
#LABEL dev.asifbacchus.image.version=${INTERNAL_VERSION}
#LABEL org.opencontainers.image.created=${BUILD_DATE}
#EOF

View File

@ -1,76 +1,33 @@
#!/bin/sh
#
# entrypoint script for node-livereload-tls container
# entrypoint script for livereload-tls-npm container
#
# functions
certificateCheckExist() {
if [ -n "$(find /certs/ -type d -empty -print)" ]; then
printf "noexist"
elif ! [ -r "/certs/fullchain.pem" ]; then
printf "noread_certificate"
elif ! [ -r "/certs/privkey.pem" ]; then
printf "noread_key"
else
printf "ok"
fi
}
certificateGenerateNew() {
# generate self-signed certificate and export as PFX
printf "\nGenerating new self-signed certificate:\n"
# shellcheck disable=SC3028
if [ -z "$CERT_HOSTNAME" ]; then export CERT_HOSTNAME="$HOSTNAME"; fi
if ! openssl req -new -x509 -days 365 -nodes -out /certs/fullchain.pem -keyout /certs/privkey.pem -config /etc/selfsigned.cnf; then
printf "\nUnable to generate certificate. Is your 'certs' directory writable by this container?\n\n"
exit 55
fi
# print message to user
printf "\n\nA self-signed certificate has been generated and saved in the location mounted to '/certs' in this container.\n"
printf "The certificate and private key are PEM formatted with names 'fullchain.pem' and 'privkey.pem', respectively.\n"
printf "Remember to import 'fullchain.pem' to the trusted store on any client machines or you will get warnings.\n\n"
printf "Exporting new certificate:\n"
exit 0
}
certificateShow() {
printf "\nCurrently loaded certificate:\n"
certStatus="$(certificateCheckExist)"
case "$certStatus" in
noexist)
printf "[ERROR]: No certificate is loaded (certificate directory empty).\n\n"
exit 51
;;
noread_certificate)
printf "[ERROR]: Cannot read loaded certificate.\n\n"
exit 52
;;
noread_key)
printf "\n[WARNING]: Cannot find private key associated with certificate!\n\n"
;;
esac
if ! openssl x509 -noout -text -nameopt align,multiline -certopt no_pubkey,no_sigdump -in /certs/fullchain.pem; then
printf "\n[ERROR]: Unable to display loaded certificate.\n\n"
exit 52
fi
exit 0
}
convertCaseLower() {
printf "%s" "$1" | tr "[:upper:]" "[:lower:]"
certificateExport() {
printf "\nExporting currently loaded certificate:\n"
exit 0
}
# default variable values
doCertExport=0
doCertNew=0
doCertShow=0
doServer=0
doShell=0
# clean-up boolean environment variables for this script and JavaScript
enableHTTPS="$(convertCaseLower "$LR_HTTPS")"
enableDebug="$(convertCaseLower "$LR_DEBUG")"
export LR_HTTPS="$enableHTTPS"
export LR_DEBUG="$enableDebug"
# process action parameter
case "$1" in
listen | server | run | start)
@ -85,44 +42,19 @@ new-cert)
show-cert)
doCertShow=1
;;
export-cert)
doCertExport=1
;;
*)
# invalid or unknown option
printf "\nUnknown action requested: %s\n" "$1"
printf "Valid actions: [listen | server | run | start] | shell | new-cert | show-cert\n\n"
printf "Valid actions: [listen | server | run | start] | shell | new-cert | show-cert | export-cert\n\n"
exit 1
;;
esac
# action: run server
if [ "$doServer" -eq 1 ]; then
printf "Starting node-livereload-tls server:\n"
# https pre-flight check
if [ "$enableHTTPS" = "true" ]; then
printf "[SSL/TLS mode enabled]\n"
certStatus="$(certificateCheckExist)"
case "$certStatus" in
noexist)
printf "[Generating certificate]\n"
certificateGenerateNew
;;
noread_certificate)
printf "[Checking mounted certificate]"
printf "\nERROR: SSL/TLS mode selected but unable to read certificate!\n\n"
exit 52
;;
noread_key)
printf "[Checking mounted certificate]"
printf "\nERROR: SSL/TLS mode selected but unable to read private key!\n\n"
exit 53
;;
ok)
printf "[Certificate OK]\n"
;;
esac
else
printf "[HTTP mode enabled]\n"
fi
exec node livereload.js
exit "$?"
fi
@ -141,16 +73,13 @@ if [ "$doShell" -eq 1 ]; then
fi
# action: generate new self-signed certificate
if [ "$doCertNew" -eq 1 ]; then
certificateGenerateNew
exit 0
fi
if [ "$doCertNew" -eq 1 ]; then certificateGenerateNew; fi
# action: show loaded certificate
if [ "$doCertShow" -eq 1 ]; then
certificateShow
exit 0
fi
if [ "$doCertShow" -eq 1 ]; then certificateShow; fi
# action: export loaded certificate
if [ "$doCertExport" -eq 1 ]; then certificateExport; fi
# failsafe exit - terminate with code 99: this code should never be executed!
exit 99
@ -158,12 +87,11 @@ exit 99
# exit codes:
# 0: normal exit, no errors
# 1: invalid or invalid parameter passed to script
# 2: interactive shell required
# 50: certificate errors
# 51: certificate directory empty
# 52: unable to read certificate/chain
# 53: unable to read private key
# 51: unable to read certificate/chain
# 52: unable to read private key
# 55: unable to generate new certificate
# 56: unable to export certificate, likely write error
# 99: code error
#EOF

View File

@ -4,8 +4,13 @@
let livereload = require('livereload');
// set createServer options
const https = require('https');
const fs = require('fs');
const options = {
https: {
cert: fs.readFileSync('/certs/fullchain.pem'),
key: fs.readFileSync('/certs/privkey.pem')
},
port: process.env.LR_PORT,
exts: process.env.LR_EXTS,
exclusions: process.env.LR_EXCLUDE,
@ -14,14 +19,6 @@ const options = {
debug: process.env.LR_DEBUG
};
if (process.env.LR_HTTPS) {
options.https = {
cert: fs.readFileSync('/certs/fullchain.pem'),
key: fs.readFileSync('/certs/privkey.pem')
};
}
// start server
let server = livereload.createServer(options);
server.watch('/watch')

View File

@ -1,16 +0,0 @@
default_bits = 4096
default_md = sha256
distinguished_name = dn
req_extensions = san
x509_extensions = san
prompt = no
[dn]
organizationName = LiveReload WebServer
CN = ${ENV::CERT_HOSTNAME}
[san]
subjectAltName = @alt_names
[alt_names]
DNS.1 = ${ENV::CERT_HOSTNAME}

View File

@ -1,32 +0,0 @@
#
# node-livereload-tls stack
#
version: '2.4'
services:
ab-nginx:
image: docker.asifbacchus.dev/nginx/ab-nginx:latest
container_name: ab-nginx
volumes:
- ./certs/certs:ro
- ${WATCHDIR}:/usr/share/nginx/html:ro
- ./nginx/config:/etc/nginx/config:ro
ports:
- "8080:80"
- "8443:443"
env_file: livereload.params
user: "8080:${GID:-8080}"
livereload:
image: docker.asifbacchus.dev/livereload/livereload:latest
container_name: livereload
volumes:
- ./certs:certs:ro
- ${WATCHDIR}:/watch:ro
ports:
- "35729:35729"
env_file: livereload.params
user: "9999:${GID:-9999}"
command: listen
#EOF

View File

@ -1,104 +0,0 @@
#
# Parameters for node-livereload-tls stack:
# This file makes it easier to customize your node-livereload-tls stack deployment by providing centralized configuration options.
# This file is *not required* since all values have (sane) default settings.
# There is *no* sensitive information in this file.
#
# COMMON PARAMETERS
# TZ:
# Timezone used in logs and console messages. No effect on operation, purely aesthetic.
# REQUIRED: NO
# DEFAULT: Etc/UTC
# VALID OPTIONS: Any valid IANA TZ formatted timezone. Refer to https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.
#TZ=Etc/UTC
# GID:
# You may wish to change the GroupID of the container's user. This allows it access certain resources on the host like certificates or files.
# REQUIRED: NO
# DEFAULT:
# VALID OPTIONS: Any valid UID/GID
#GID=
# WATCHDIR:
# Directory containing files you want to monitor for changes and trigger a browser reload.
# REQUIRED: NO
# DEFAULT:
# VALID OPTIONS: Any valid directory on the host
#WATCHDIR=
#
# AB-NGINX parameters
# refer to https://git.asifbacchus.dev/ab-docker/ab-nginx/wiki for more details
# SERVER_NAMES:
# Space-delimited list of names to which the server should respond. This needs to match any certificates being used.
# REQUIRED: NO
# DEFAULT: _
# VALID OPTIONS: Any valid hostnames for your environment
#SERVER_NAMES=_
# TLS13_ONLY:
# Use and accept only TLS version 1.3 connections. If false, both TLS versions 1.2 and 1.3 will be accepted.
# REQUIRED: NO
# DEFAULT: TRUE
# VALID OPTIONS: TRUE, FALSE
#TLS13_ONLY=TRUE
#
# node-livereload parameters
# LR_PORT:
# Port on which the server should listen. Virtually all clients expect the default setting.
# REQUIRED: NO
# DEFAULT: 35729
# VALID OPTIONS: Any valid TCP port number that does not conflict within your environment
#LR_PORT=35729
# LR_EXTS:
# Comma-delimited list of extensions to watch for changes and trigger a browser reload. This list *must* be quoted.
# REQUIRED: NO
# DEFAULT: "html,xml,css,js,jsx,ts,tsx,php,py"
# VALID OPTIONS: Any valid file extension(s)
#LR_EXTS="html,xml,css,js,jsx,ts,tsx,php,py"
# LR_EXCLUDE:
# Comma-delimited list of files/directories to exclude from monitoring. This list *must* be quoted.
# REQUIRED: NO
# DEFAULT: ".git/,.svn/,.vscode/,.idea/"
# VALID OPTIONS: Any valid files or directories/
#LR_EXCLUDE=".git/,.svn/,.vscode/,.idea/"
# LR_DELAY:
# Amount of time in milliseconds before detecting a change and sending a trigger for a browser reload. Useful if you need to allow time for background recompilation, etc.
# REQUIRED: NO
# DEFAULT: 500
# VALID OPTIONS: Any integer representing a number of milliseconds (ms)
#LR_DELAY=500
# LR_DEBUG:
# Whether or not to print diagnostic debugging messages about the server's operation. Usually a good idea to leave this set to 'true'.
# REQUIRED: NO
# DEFAULT: true
# VALID OPTIONS: true, false
#LR_DEBUG=true
# LR_HTTPS:
# Whether or not to enable SSL/TLS on the server's listening port. This may be required depending on your domain and environment configuration.
# REQUIRED: NO
# DEFAULT: true
# VALID OPTIONS: true, false
#LR_HTTPS=true
# CERT_HOSTNAME:
# Hostname to use if container is auto-generating a self-signed certificate.
# REQUIRED: NO
# DEFAULT: $HOSTNAME
# VALID OPTIONS: Any valid hostname
#CERT_HOSTNAME=$HOSTNAME
#EOF