initial commit - build and deploy working

master
David Kebler 2023-09-15 09:58:32 -07:00
commit 35a8626222
47 changed files with 530 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
logs/
mnt/
archive/
*.env
deploy/doc

6
build/.env.example Normal file
View File

@ -0,0 +1,6 @@
# copy to .env and edit to suit
NAME=doc
BASE_IMAGE="squidfunk/mkdocs-material"
RUSER=ucommandit
BUILD_SRC=../src
APPEND_BUILD_ENV=./build.env

2
build/boot Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
udbuild try -o '-p 8011:8000 -p 8012:8080 -v tempdoc:/doc' -y /opt/bin/boot $@

1
build/build Executable file
View File

@ -0,0 +1 @@
udbuild -p "$@"

3
build/build.env.example Normal file
View File

@ -0,0 +1,3 @@
export USER=doc
# set a password for create login user
# export USER_PW=somepassword

4
build/clean Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
rm -rf ../build/mnt
docker volume rm tempdoc

5
build/devsync Executable file
View File

@ -0,0 +1,5 @@
rsync -r ../src/rootfs/opt/lib/ mnt/opt/lib/
rsync -r ../src/rootfs/opt/bin/ mnt/opt/bin/
rsync -r ../src/rootfs/opt/env/ mnt/opt/env/
rsync -r ../src/rootfs/opt/services/ mnt/opt/services/
rsync -r ../src/rootfs/opt/caddy/conf/ mnt/opt/caddy/conf

1
build/publish Executable file
View File

@ -0,0 +1 @@
udbuild -t publish $@

3
build/shell Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
udbuild try -m doc -k -o '-p 8012:8080 -p 8011:8000' ${@:-shell} $@

3
build/shelldev Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
udbuild try -m opt -k -o '-p 8012:8080 -p 8011:8000' ${@:-shell} $@

1
build/term Executable file
View File

@ -0,0 +1 @@
docker exec -it try-ucommandit-doc /opt/bin/entrypoint ${@:-shell}

25
deploy/docker-compose.yml Normal file
View File

@ -0,0 +1,25 @@
services:
caddy:
container_name: ${NAME:-doc}
image: ${IMAGE:-doc}
entrypoint: /opt/bin/boot
hostname: ${NAME:-doc}
# env_file:
# - $CREDENTIALS
volumes:
- doc:/doc
restart: unless-stopped
ports:
# use 80 if doing reverse proxy inside container
# - 80:80
# map 8080 and 8000 if not doing reverse proxy inside container
- 8901:8080 # editor
- 8900:8000 # docs
# bind doc volume to host for backup or outside container editing
# volumes:
# doc:
# driver: local
# driver_opts:
# type: none
# device: ${PWD}/doc
# o: bind

1
deploy/log Executable file
View File

@ -0,0 +1 @@
docker-compose logs

3
deploy/restart Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
./stop
./start

1
deploy/run Executable file
View File

@ -0,0 +1 @@
docker-compose up

2
deploy/scrub Executable file
View File

@ -0,0 +1,2 @@
docker-compose down -v
rm -rf doc/

1
deploy/start Executable file
View File

@ -0,0 +1 @@
docker-compose up -d

1
deploy/stop Executable file
View File

@ -0,0 +1 @@
docker-compose down

3
deploy/term Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
source .env
docker exec -it ${NAME:-doc} bash -l

4
deploy/upgrade Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
./stop
docker-compose pull
./start

25
readme.md Normal file
View File

@ -0,0 +1,25 @@
# UCI - Live Documetation in a Container
** A self contained live documenation system for editing and displaying documentation via the browser**
This repo will build an alpine image complete with a mkdocs-material and vscode servers.
## Deploy
* Copy the deploy directory from this repo to your machine that has docker and docker-compose installed
* Make a copy of the .env.example file to .env and edit as needed.
* Edit the docker-compose.yml as needed.
* use the ./run script for testing and the ./start to deploy detached.
Run a caddy reverse proxy to use https and to obfuscate the ports of the servers
## Build
* You MUST clone and install the [UCI Docker Build]() repo first
* Then clone this repo
* make a copy of the .env.example file to .env and edit
* make a copy of the build.env.example to build.env and edit
* user the ./build script to build and the ./publish script to publish
additional script in the direcotory are used to facilitate testing and deveopment.

1
src/init/image.info Normal file
View File

@ -0,0 +1 @@
Build Source: uci-docker-base

31
src/init/init.sh Executable file
View File

@ -0,0 +1,31 @@
#!/bin/bash
echo -e "********** Docs Server Initialization ***************"
source $LIB_DIR/verbose.lib
source $LIB_DIR/helpers.lib
source $ENV_DIR/run.env
echo setting up document directory $DOC_HOME with git, making first commit
mkdir -p $DOC_HOME
[[ ! -f $DOC_HOME/mkdocs.yml ]] && echo intializing mkdocs in $DOC_HOME && /usr/local/bin/mkdocs new $DOC_HOME
chown -R $USER:$USER $DOC_HOME
# TODO allow setting up a remote for branch
sudo -u doc /bin/bash << CMD
cd $DOC_HOME
git init
git add .
git config user.email ${USER_EMAIL:-doc@somedomain.com}
git config user.name "${USER_NAME:-doc}"
git commit -m="initial documentation commit"
git log --stat
CMD
echo "done setting up $DOC_HOME"
echo "setting up caddy for password secured access to editor and docs"
source $LIB_DIR/caddy.lib
mkdir -p $CADDY_HOME/bin $CADDY_HOME/settings $CADDY_HOME/data
chown -R $USER:$USER /opt
echo -e "********** Done: initialization ***************"

3
src/packages/caddy.pkgs Executable file
View File

@ -0,0 +1,3 @@
github.com/caddy-dns/route53
# comment lines are ignored thus a way to disable a package on build
# github.com/greenpau/caddy-security

34
src/packages/caddy.sh Normal file
View File

@ -0,0 +1,34 @@
caddy_add_packages () {
local ifile; local bin; local pkgs; local pkg; local ipkgs
clean () {
local tmp;local tmp2; local append
if [[ -f $1 ]]; then
tmp=$(sed '/^[[:space:]]*#[^!]/d; /#$/d' $1)
else
tmp=$1
fi
echo "$tmp $2" | xargs -n1 | sort -u | xargs | sed "s# # #g"
}
[[ -f caddy.pkgs ]] && pkgs=" $(clean caddy.pkgs)"
[[ ! $pkgs ]] && echo "no packages requested, nothing to do" && return 0
echo "-packages requested to install-"
echo $pkgs
bin=/usr/sbin/caddy
[[ ! -x $bin ]] && echo ERROR: can not add packages, no caddy binary found at $bin && return 1
if ! $bin add-package $pkgs >/dev/null 2>&1; then
echo Error: Aborting further package installs and reverting to last good binary
return 2
else
echo packages added successfully
CADDY_HOME=${CADDY_HOME:-/opt/caddy}
mkdir -p $CADDY_HOME/bin/
echo $pkgs >> $CADDY_HOME/bin/installed.pkgs
echo "---"
echo currently installed packages
cat $CADDY_HOME/bin/installed.pkgs
echo installed modules from these packages
$bin list-modules | sed '1,/Standard modules/d;/Non-standard modules/,$d'
fi
}

32
src/packages/packages.sh Normal file
View File

@ -0,0 +1,32 @@
if ! { [ "$VERBOSE" = "packages" ] || [ "$VERBOSE" = "all" ]; }; then unset VERBOSE; fi
source /opt/core_run.env
source $LIB_DIR/verbose.lib
echo "----- Installing python packages ---------------"
while IFS= read -r plug || [ -n "$plug" ]; do
echo installing plugin: $plug
silence pip install $plug
done < ./python.pkgs
echo "----- done, Installing python packages ---------------"
echo "----- Installing caddy packages ---------------"
source caddy.sh
caddy_add_packages
echo "----- done, Installing caddy packages ---------------"
echo "----- Downloading editor $EDITOR ---------------"
source $LIB_DIR/helpers.lib
EDITOR=${EDITOR:-coder/code-server}
ARCH=$(get_arch)
echo downloading $EDITOR version: $(lastversion coder/code-server) for $ARCH
lastversion coder/code-server --assets --filter linux-$ARCH -d /tmp/temp.tar.gz
EDITOR_SRC=${EDITOR_SRC:-/usr/local/lib/code-server}
mkdir -p $EDITOR_SRC
echo unpacking tarball into $EDITOR_SRC
tar xf /tmp/temp.tar.gz -C $EDITOR_SRC --strip-components=1
rm -rf /tmp/temp.tar.gz
ln -s ${EDITOR_BIN:-$EDITOR_SRC/bin/code-server} /usr/local/bin/editor
echo "----- done, downloading editor $EDITOR ---------------"

3
src/packages/python.pkgs Normal file
View File

@ -0,0 +1,3 @@
mkdocs-macros-plugin
mkdocs-glightbox
lastversion

7
src/packages/system.pkgs Normal file
View File

@ -0,0 +1,7 @@
jq
rsync
envsubst
runit
caddy
gcompat
libstdc++

View File

@ -0,0 +1,4 @@
# UCI Live Documentation System
[mkdocs material](https://squidfunk.github.io/mkdocs-material/setup/)

5
src/rootfs/doc/editor/data/.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
/*
!User
!.gitignore

View File

@ -0,0 +1,6 @@
/*
!snippets
!.gitignore
!settings.json

View File

@ -0,0 +1,4 @@
{
"workbench.colorTheme": "Default Dark Modern",
"workbench.startupEditor": "none"
}

View File

@ -0,0 +1,8 @@
port: 8080
host: 0.0.0.0
auth: none
# password: test
cert: false
user-data-dir: $EDITOR_DATA
extensions-dir: $EDITOR_EXTENSIONS
app-name: $DOC_NAME

View File

@ -0,0 +1 @@
[]

View File

@ -0,0 +1,3 @@
site_name: UCI Documentation Docker Instance
theme:
name: material

17
src/rootfs/opt/bin/boot Executable file
View File

@ -0,0 +1,17 @@
#!/bin/sh
source /opt/core_run.env
source $LIB_DIR/runit.lib
startup
# catch shutdown signals
trap shutdown SIGTERM SIGHUP SIGQUIT SIGINT
# RUNIT is runsvdir pid
wait $RUNIT
sleep 3
echo "killing any other processes (zombie) still running in the container"
for _pid in $(ps -eo pid | grep -v PID | tr -d ' ' | grep -v '^1$' | head -n -6); do
timeout 5 /bin/sh -c "kill $_pid && wait $_pid || kill -9 $_pid"
done

31
src/rootfs/opt/bin/doc Executable file
View File

@ -0,0 +1,31 @@
#!/bin/bash
source $LIB_DIR/cmds.lib
doc () {
cmd=$1
case "$cmd" in
idle) ;&
shell) ;&
caddy) ;&
editor) ;&
browser) ;&
run) ;&
startup) ;&
shutdown) ;&
func)
shift 1
$cmd "$@"
;;
*)
echo "no command: $*"
;;
esac
}
# # if script was executed then call the function
(return 0 2>/dev/null) || doc "$@"

View File

@ -0,0 +1,3 @@
:8010 {
reverse_proxy :8011
}

View File

@ -0,0 +1,121 @@
#!/bin/bash
caddy_add_packages () {
local ifile; local bin; local pkgs; local pkg; local ipkgs
clean () {
local tmp;local tmp2; local append
if [[ -f $1 ]]; then
tmp=$(sed '/^[[:space:]]*#[^!]/d; /#$/d' $1)
else
tmp=$1
fi
echo "$tmp $2" | xargs -n1 | sort -u | xargs | sed "s# # #g"
}
[[ -f $1 ]] && pkgs=" $(clean $1)"
[[ $BUILDING && -f $BUILD_DIR/caddy.pkgs ]] && pkgs=$(clean $BUILD_DIR/caddy.pkgs "$pkgs")
# echo pkgs after build
# echo $pkgs
[[ -f $CADDY_CONF/caddy.pkgs ]] && pkgs=$(clean $CADDY_CONF/caddy.pkgs "$pkgs")
# echo pkgs after conf
# echo $pkgs
[[ ! $pkgs ]] && echo "no packages requested, nothing to do" && return 0
echo "--- packages requested to install ----"
echo $pkgs
echo "-----------"
ifile=${CADDY_HOME}/bin/installed.pkgs
# uncomment for testing
# /bin/cp installed.pkgs $ifile
[[ -f $ifile ]] && ipkgs=$(clean $ifile)
echo "--- currently installed packages ----"
[[ $ipkgs ]] && echo $ipkgs || echo NONE
echo "-----------"
for pkg in $ipkgs; do
# echo installed packaged $pkg
pkgs=${pkgs/${pkg}/};
done
[[ ! $(clean $pkgs) ]] && echo "no new packages to add, nothing to do" && return 0
echo "--- packages that need adding ----"
echo $pkgs
echo "-----------"
bin=${2:-$CADDY_BIN}
bin=${bin:-$(command -v caddy)}
# [[ ! $bin ]] && echo no caddy binary found && return 1
[[ ! -x $bin ]] && echo ERROR: can not add packages, no caddy binary found at $bin && return 1
echo "------- ADDING CADDY PACKAGES ------------"
if ! $bin add-package $pkgs >/dev/null 2>&1; then
echo Error: Aborting further package installs and reverting to last good binary
return 2
else
echo packages
echo $pkgs
echo added successfully
echo $pkgs >> $CADDY_HOME/bin/installed.pkgs
echo "---"
echo currently installed packages
cat $CADDY_HOME/bin/installed.pkgs
echo installed modules from these packages
$bin list-modules | sed '1,/Standard modules/d;/Non-standard modules/,$d'
echo "-----------------------------------"
fi
}
caddy_get_conf () {
local conf
cd $CADDY_CONF || { echo could not enter conf directory in container; return 2; }
if [[ $1 ]];then
[[ -f $1 ]] && conf=$1 || conf=$1.conf
else
conf=.Caddyfile
fi
echo "$CADDY_CONF/$conf"
}
caddy () {
if [[ ! $CADDY_HOME ]]; then
echo caddy run environment is NOT set
echo this is an error as the image build should set this
echo attempting to recover by sourcing the environment now
echo at $ENV_DIR/caddy.env
if [[ -f $ENV_DIR/caddy.env ]]; then
source $ENV_DIR/caddy.env
else
echo default environment can not be sourced at $ENV_DIR/caddy.env
return 1
fi
fi
[[ ! $CADDY_BIN ]] && CADDY_BIN is not set unable to find caddy binary
[ ! -f "$CADDY_BIN" ] && echo caddy binary file at $CADDY_BIN does not exist && return 1
[ ! -x "$CADDY_BIN" ] && echo caddy binary file $CADDY_BIN is not executable && return 1
case "$1" in
start)
;&
stop)
;&
validate)
;&
run)
cmd=$1;shift 1
conf=$(caddy_get_conf $1)
if [[ -f $conf ]]; then
# echo checking for any run time packages to add...
# caddy_add_packages
echo running: $CADDY_BIN $cmd --config $conf --adapter caddyfile
$CADDY_BIN $cmd --config $conf --adapter caddyfile
return $?
else
echo no configuration file found at $conf in the container
echo make sure you have mounted one from the host into /opt/caddy/conf
return 1
fi
;;
*)
$CADDY_BIN "$@"
esac
}

View File

@ -0,0 +1,36 @@
#!/bin/bash
source $LIB_DIR/runit.lib
shell () {
/bin/bash -c "cd ${DEFAULT_DIR:-/}; exec bash -l"
}
func () {
local func=$1
shift 1
$func $@
}
editor () {
$SVDIR/editor/run "$@"
}
browser () {
$SVDIR/mkdocs/run "$@"
}
caddy () {
$SVDIR/caddy/run "$@"
}
run() {
if [ "$(id -u)" = 0 ]; then
sudo -u "${USER:-doc}" bash -c "source /opt/core_run.env; $*"
fi
}
idle () {
sleep infinity
}

View File

@ -0,0 +1,48 @@
#!/bin/sh
# runit library
svall () {
for _srv in $(basename -a $(ls -d1 $SVDIR/*/)); do
if [ -z "$1" ]; then
echo $_srv
else
echo $1 for $_srv
sv $1 $_srv
fi
done
}
shutdown() {
# first shutdown any service started by runit
echo first shutting down all services
svall force-stop
# shutdown RUNIT command
RUNIT=${RUNIT:-$(cat ${SVDIR:-/opt/services}/pid)}
echo now killing runit at pid $RUNIT
kill -HUP $RUNIT
echo runit is shutdown
}
startup () {
[ -z $SVDIR ] && echo using default services directory /opt/services
SVDIR=${SVDIR:-/opt/services}
export SVDIR=${1:-$SVDIR}
echo starting up services in $SVDIR
exec runsvdir -P ${1:-$SVDIR} &
RUNIT=$!
echo $RUNIT > $SVDIR/pid
export RUNIT
echo
echo "Started services at $SVDIR, PID is $RUNIT"
echo "waiting for service processes to start...."
sleep 3
svall status
}

View File

@ -0,0 +1,3 @@
#!/bin/bash
echo stopping caddy
source $LIB_DIR/caddy.lib

View File

@ -0,0 +1,4 @@
#!/bin/bash
echo ${1:-run} caddy
source $LIB_DIR/caddy.lib
caddy ${1:-run}

View File

@ -0,0 +1,3 @@
#!/bin/bash
echo code-server run finished with exit code $1
echo "doing any cleanup now"

View File

@ -0,0 +1,14 @@
#!/bin/bash
env | grep EDITOR
echo booting up editor
ls -la $DOC_HOME/editor
if [[ -f $EDITOR_CONFIG_TMPL ]]; then
echo creating editor config from template
envsubst < $EDITOR_CONFIG_TMPL > $EDITOR_CONFIG
fi
[[ ! -f $EDITOR_CONFIG ]] && echo "no editor config file (or template) at $EDITOR_CONFIG, aborting" && exit 1
echo "--- editor config -----"
cat $EDITOR_CONFIG
echo "-----------------------"
echo starting code server editor
sudo -u doc $EDITOR_BIN --config $EDITOR_CONFIG $@ $DOC_HOME

View File

@ -0,0 +1,3 @@
#!/bin/bash
echo mkdocs run finished with exit code $1
echo "doing any cleanup now"

View File

@ -0,0 +1,5 @@
#!/bin/bash
echo starting mkdocs in $DOC_HOME
pushd $DOC_HOME
/usr/local/bin/mkdocs serve --dev-addr=0.0.0.0:8000 --watch-theme
popd