Skip to content
Snippets Groups Projects
Commit a705cc9a authored by Hahn Axel (hahn)'s avatar Hahn Axel (hahn)
Browse files

Merge branch 'update-readme' into 'master'

Update readme + docs

See merge request !64
parents afed96b1 a8b9b156
No related branches found
No related tags found
1 merge request!64Update readme + docs
Pipeline #4342 passed
...@@ -15,15 +15,36 @@ ...@@ -15,15 +15,36 @@
# 2023-11-13 v1.8 <axel.hahn@unibe.ch> UNDO "docker compose"; update infos # 2023-11-13 v1.8 <axel.hahn@unibe.ch> UNDO "docker compose"; update infos
# 2023-11-15 v1.9 <axel.hahn@unibe.ch> add help; execute multiple actions by params; new menu item: open app # 2023-11-15 v1.9 <axel.hahn@unibe.ch> add help; execute multiple actions by params; new menu item: open app
# 2023-12-07 v1.10 <www.axel-hahn.de> simplyfy console command; add php linter # 2023-12-07 v1.10 <www.axel-hahn.de> simplyfy console command; add php linter
# 2024-07-01 v1.11 <www.axel-hahn.de> diff with colored output; suppress errors on port check
# 2024-07-19 v1.12 <axel.hahn@unibe.ch> apply shell fixes
# 2024-07-22 v1.13 <axel.hahn@unibe.ch> show info if there is no database container; speedup replacements
# 2024-07-22 v1.14 <axel.hahn@unibe.ch> show colored boxes with container status
# 2024-07-24 v1.15 <axel.hahn@unibe.ch> update menu output
# ====================================================================== # ======================================================================
cd $( dirname $0 ) cd "$( dirname "$0" )" || exit 1
. $( basename $0 ).cfg
# init used vars
gittarget=
frontendurl=
_self=$( basename "$0" )
# shellcheck source=/dev/null
. "${_self}.cfg" || exit 1
_version="1.15"
# git@git-repo.iml.unibe.ch:iml-open-source/docker-php-starterkit.git # git@git-repo.iml.unibe.ch:iml-open-source/docker-php-starterkit.git
selfgitrepo="docker-php-starterkit.git" selfgitrepo="docker-php-starterkit.git"
_version="1.10" fgGray="\e[1;30m"
fgRed="\e[31m"
fgGreen="\e[32m"
fgBrown="\e[33m"
fgBlue="\e[34m"
fgReset="\e[0m"
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# FUNCTIONS # FUNCTIONS
...@@ -32,37 +53,39 @@ _version="1.10" ...@@ -32,37 +53,39 @@ _version="1.10"
# draw a headline 2 # draw a headline 2
function h2(){ function h2(){
echo echo
echo -e "\e[33m>>>>> $*\e[0m" echo -e "$fgBrown>>>>> $*$fgReset"
} }
# draw a headline 3 # draw a headline 3
function h3(){ function h3(){
echo echo
echo -e "\e[34m----- $*\e[0m" echo -e "$fgBlue----- $*$fgReset"
} }
# show help for param -h # show help for param -h
function showMenu(){ function showMenu(){
echo " $( _key g ) - remove git data of starterkit" cat <<EOM
echo
echo " $( _key i ) - init application: set permissions" $( _key g ) - remove git data of starterkit
echo " $( _key t ) - generate files from templates"
echo " $( _key T ) - remove generated files" $( _key i ) - init application: set permissions
echo $( _key t ) - generate files from templates
echo " $( _key u ) - startup containers docker-compose ... up -d" $( _key T ) - remove generated files
echo " $( _key U ) - startup containers docker-compose ... up -d --build"
echo " $( _key s ) - shutdown containers docker-compose stop" $( _key u ) - startup containers docker-compose ... up -d
echo " $( _key r ) - remove containers docker-compose rm -f" $( _key U ) - startup containers docker-compose ... up -d --build
echo $( _key s ) - shutdown containers docker-compose stop
echo " $( _key m ) - more infos" $( _key r ) - remove containers docker-compose rm -f
echo " $( _key o ) - open app [${APP_NAME}] $frontendurl"
echo " $( _key c ) - console (bash)" $( _key m ) - more infos
echo " $( _key p ) - console check with php linter" $( _key o ) - open app [${APP_NAME}] $frontendurl
echo $( _key c ) - console (bash)
echo " $( _key q ) - quit" $( _key p ) - console check with php linter
$( _key q ) - quit
EOM
} }
function showHelp(){ function showHelp(){
local _self=$( basename "$0" )
cat <<EOH cat <<EOH
INITIALIZER FOR DOCKER APP v$_version INITIALIZER FOR DOCKER APP v$_version
...@@ -98,20 +121,16 @@ EXAMPLES: ...@@ -98,20 +121,16 @@ EXAMPLES:
EOH EOH
} }
# function _gitinstall(){
# h2 "install/ update app from git repo ${gitrepo} in ${gittarget} ..."
# test -d ${gittarget} && ( cd ${gittarget} && git pull )
# test -d ${gittarget} || git clone -b ${gitbranch} ${gitrepo} ${gittarget}
# }
# set acl on local directory # set acl on local directory
function _setWritepermissions(){ function _setWritepermissions(){
h2 "set write permissions on ${gittarget} ..." h2 "set write permissions on ${gittarget} ..."
local _user=$( id -gn ) local _user; _user=$( id -gn )
typeset -i local _user_uid=0 local _user_uid; typeset -i _user_uid=0
test -f /etc/subuid && _user_uid=$( grep $_user /etc/subuid 2>/dev/null | cut -f 2 -d ':' )-1
typeset -i local DOCKER_USER_OUTSIDE=$_user_uid+$DOCKER_USER_UID test -f /etc/subuid && _user_uid=$( grep "$_user" /etc/subuid 2>/dev/null | cut -f 2 -d ':' )-1
local DOCKER_USER_OUTSIDE; typeset -i DOCKER_USER_OUTSIDE=$_user_uid+$DOCKER_USER_UID
set -vx set -vx
...@@ -123,10 +142,10 @@ function _setWritepermissions(){ ...@@ -123,10 +142,10 @@ function _setWritepermissions(){
sudo setfacl -bR "${mywritedir}" sudo setfacl -bR "${mywritedir}"
# default permissions: both the host user and the user with UID 33 (www-data on many systems) are owners with rwx perms # default permissions: both the host user and the user with UID 33 (www-data on many systems) are owners with rwx perms
sudo setfacl -dRm u:${DOCKER_USER_OUTSIDE}:rwx,${_user}:rwx "${mywritedir}" sudo setfacl -dRm "u:${DOCKER_USER_OUTSIDE}:rwx,${_user}:rwx" "${mywritedir}"
# permissions: make both the host user and the user with UID 33 owner with rwx perms for all existing files/directories # permissions: make both the host user and the user with UID 33 owner with rwx perms for all existing files/directories
sudo setfacl -Rm u:${DOCKER_USER_OUTSIDE}:rwx,${_user}:rwx "${mywritedir}" sudo setfacl -Rm "u:${DOCKER_USER_OUTSIDE}:rwx,${_user}:rwx" "${mywritedir}"
done done
set +vx set +vx
...@@ -137,11 +156,10 @@ function _removeGitdata(){ ...@@ -137,11 +156,10 @@ function _removeGitdata(){
h2 "Remove git data of starterkit" h2 "Remove git data of starterkit"
echo -n "Current git remote url: " echo -n "Current git remote url: "
git config --get remote.origin.url git config --get remote.origin.url
git config --get remote.origin.url 2>/dev/null | grep $selfgitrepo >/dev/null if git config --get remote.origin.url 2>/dev/null | grep $selfgitrepo >/dev/null; then
if [ $? -eq 0 ]; then
echo echo
echo -n "Delete local .git and .gitignore? [y/N] > " echo -n "Delete local .git and .gitignore? [y/N] > "
read answer read -r answer
test "$answer" = "y" && ( echo "Deleting ... " && rm -rf ../.git ../.gitignore ) test "$answer" = "y" && ( echo "Deleting ... " && rm -rf ../.git ../.gitignore )
else else
echo "It was done already - $selfgitrepo was not found." echo "It was done already - $selfgitrepo was not found."
...@@ -153,14 +171,32 @@ function _removeGitdata(){ ...@@ -153,14 +171,32 @@ function _removeGitdata(){
# see _generateFiles() # see _generateFiles()
function _fix_no-db(){ function _fix_no-db(){
local _file=$1 local _file=$1
if [ $DB_ADD = false ]; then if [ "$DB_ADD" = "false" ]; then
typeset -i local iStart=$( cat ${_file} | grep -Fn "$CUTTER_NO_DATABASE" | cut -f 1 -d ':' )-1 local iStart; typeset -i iStart
iStart=$( grep -Fn "$CUTTER_NO_DATABASE" "${_file}" | cut -f 1 -d ':' )-1
if [ $iStart -gt 0 ]; then if [ $iStart -gt 0 ]; then
sed -ni "1,${iStart}p" ${_file} sed -ni "1,${iStart}p" "${_file}"
fi fi
fi fi
} }
# helper functiion to generate replacements using sed
# it loops over all vars in the config file
# used in _generateFiles
function _getreplaces(){
# loop over vars to make the replacement
grep "^[a-zA-Z]" "$_self.cfg" | while read -r line
do
# echo replacement: $line
mykey=$( echo "$line" | cut -f 1 -d '=' )
myvalue="$( eval echo \"\$"$mykey"\" )"
# TODO: multiline values fail here in replacement with sed
echo -e "s#{{$mykey}}#${myvalue}#g"
done
}
# loop over all files in templates subdir make replacements and generate # loop over all files in templates subdir make replacements and generate
# a target file. # a target file.
# It skips if # It skips if
...@@ -168,21 +204,23 @@ function _fix_no-db(){ ...@@ -168,21 +204,23 @@ function _fix_no-db(){
# - target file has no updated lines # - target file has no updated lines
function _generateFiles(){ function _generateFiles(){
# re-read config vars # shellcheck source=/dev/null
. $( basename $0 ).cfg . "${_self}.cfg" || exit 1
params=$( _getreplaces | while read -r line; do echo -n "-e '$line' "; done )
local _tmpfile=/tmp/newfilecontent$$.tmp local _tmpfile=/tmp/newfilecontent$$.tmp
h2 "generate files from templates..." h2 "generate files from templates..."
for mytpl in $( ls -1 ./templates/* ) for mytpl in templates/*
do do
# h3 $mytpl # h3 $mytpl
local _doReplace=1 local _doReplace=1
# fetch traget file from first line # fetch traget file from first line
target=$( head -1 $mytpl | grep "^# TARGET:" | cut -f 2- -d ":" | awk '{ print $1 }' ) target=$( head -1 "$mytpl" | grep "^# TARGET:" | cut -f 2- -d ":" | awk '{ print $1 }' )
if [ -z "$target" ]; then if [ -z "$target" ]; then
echo SKIP: $mytpl - target was not found in 1st line echo "SKIP: $mytpl - target was not found in 1st line"
_doReplace=0 _doReplace=0
fi fi
...@@ -190,39 +228,29 @@ function _generateFiles(){ ...@@ -190,39 +228,29 @@ function _generateFiles(){
if [ $_doReplace -eq 1 ]; then if [ $_doReplace -eq 1 ]; then
# write file from line 2 to a tmp file # write file from line 2 to a tmp file
sed -n '2,$p' $mytpl >$_tmpfile sed -n '2,$p' "$mytpl" >"$_tmpfile"
# add generator # add generator
# sed -i "s#{{generator}}#generated by $0 - template: $mytpl - $( date )#g" $_tmpfile # sed -i "s#{{generator}}#generated by $0 - template: $mytpl - $( date )#g" $_tmpfile
local _md5=$( md5sum $_tmpfile | awk '{ print $1 }' ) local _md5; _md5=$( md5sum $_tmpfile | awk '{ print $1 }' )
sed -i "s#{{generator}}#GENERATED BY $( basename $0 ) - template: $mytpl - $_md5#g" $_tmpfile sed -i "s#{{generator}}#GENERATED BY $_self - template: $mytpl - $_md5#g" $_tmpfile
# loop over vars to make the replacement eval sed -i "$params" "$_tmpfile" || exit
grep "^[a-zA-Z]" $( basename $0 ).cfg | while read line
do
# echo replacement: $line
mykey=$( echo $line | cut -f 1 -d '=' )
myvalue="$( eval echo \"\${$mykey}\" )"
# grep "{{$mykey}}" $_tmpfile
# TODO: multiline values fail here in replacement with sed
sed -i "s#{{$mykey}}#${myvalue}#g" $_tmpfile
done
_fix_no-db $_tmpfile _fix_no-db $_tmpfile
# echo "changes for $target:" # echo "changes for $target:"
diff "../$target" "$_tmpfile" | grep -v "$_md5" | grep -v "^---" | grep . if diff --color=always "../$target" "$_tmpfile" | grep -v "$_md5" | grep -v "^---" | grep . || [ ! -f "../$target" ]; then
if [ $? -eq 0 -o ! -f "../$target" ]; then
echo -n "$mytpl - changes detected - writing [$target] ... " echo -n "$mytpl - changes detected - writing [$target] ... "
mkdir -p $( dirname "../$target" ) || exit 2 mkdir -p "$( dirname ../"$target" )" || exit 2
mv "$_tmpfile" "../$target" || exit 2 mv "$_tmpfile" "../$target" || exit 2
echo OK echo OK
echo
else else
rm -f $_tmpfile rm -f $_tmpfile
echo "SKIP: $mytpl - Nothing to do." echo "SKIP: $mytpl - Nothing to do."
fi fi
fi fi
echo
done done
} }
...@@ -231,20 +259,20 @@ function _generateFiles(){ ...@@ -231,20 +259,20 @@ function _generateFiles(){
# a traget file. # a traget file.
function _removeGeneratedFiles(){ function _removeGeneratedFiles(){
h2 "remove generated files..." h2 "remove generated files..."
for mytpl in $( ls -1 ./templates/* ) for mytpl in templates/*
do do
h3 $mytpl h3 "$mytpl"
# fetch traget file from first line # fetch traget file from first line
target=$( head -1 $mytpl | grep "^# TARGET:" | cut -f 2- -d ":" | awk '{ print $1 }' ) target=$( head -1 "$mytpl" | grep "^# TARGET:" | cut -f 2- -d ":" | awk '{ print $1 }' )
if [ ! -z "$target" -a -f "../$target" ]; then if [ -n "$target" ] && [ -f "../$target" ]; then
echo -n "REMOVING " echo -n "REMOVING "
ls -l "../$target" || exit 2 ls -l "../$target" || exit 2
rm -f "../$target" || exit 2 rm -f "../$target" || exit 2
echo OK echo OK
else else
echo SKIP: $target echo "SKIP: $target"
fi fi
done done
...@@ -253,12 +281,72 @@ function _removeGeneratedFiles(){ ...@@ -253,12 +281,72 @@ function _removeGeneratedFiles(){
# show running containers # show running containers
function _showContainers(){ function _showContainers(){
local bLong=$1 local bLong=$1
h2 CONTAINERS local _out
if [ -z "$bLong" ]; then
local sUp=".. UP"
local sDown=".. down"
local Status=
local StatusWeb="$sDown"
local StatusDb=""
local colWeb=
local colDb=
colDb="$fgRed"
colWeb="$fgRed"
_out=$( if [ -z "$bLong" ]; then
docker-compose -p "$APP_NAME" ps docker-compose -p "$APP_NAME" ps
else else
docker ps | grep $APP_NAME # docker ps | grep "$APP_NAME"
docker-compose -p "$APP_NAME" ps
fi)
h2 CONTAINERS
if [ "$( wc -l <<< "$_out" )" -eq 1 ]; then
if [ "$DB_ADD" = "false" ]; then
colDb="$fgGray"
Status="The web container is not running. This app has no database container."
else
StatusDb="down"
Status="No container is running for <$APP_NAME>."
fi
else
grep -q "${APP_NAME}-server" <<< "$_out" && colWeb="$fgGreen"
grep -q "${APP_NAME}-server" <<< "$_out" && StatusWeb="$sUp"
grep -q "${APP_NAME}-db" <<< "$_out" && colDb="$fgGreen"
StatusDb="$sDown"
grep -q "${APP_NAME}-db" <<< "$_out" && StatusDb="$sUp"
if [ "$DB_ADD" = "false" ]; then
colDb="$fgGray"
StatusDb=""
Status="INFO: This app has no database container."
fi
fi
printf "$colWeb __________________________ $colDb __________________________ $fgReset \n"
printf "$colWeb | %-22s | $colDb | %-22s | $fgReset \n" "" ""
printf "$colWeb | %-22s | $colDb | %-22s | $fgReset \n" "${APP_NAME}-web ${StatusWeb}" "${APP_NAME}-db ${StatusDb}"
printf "$colWeb | %-22s | $colDb | %-22s | $fgReset \n" " PHP ${APP_PHP_VERSION}" " ${MYSQL_IMAGE}"
printf "$colWeb | %-22s | $colDb | %-22s | $fgReset \n" " :${APP_PORT}" " :${DB_PORT}"
printf "$colWeb |__________________________| $colDb |__________________________| $fgReset \n"
if [ -n "$Status" ]; then
echo
echo "$Status"
fi fi
echo
if [ -n "$bLong" ]; then
echo "$_out"
h2 STATS
docker stats --no-stream
echo
fi
} }
...@@ -276,33 +364,44 @@ function _showInfos(){ ...@@ -276,33 +364,44 @@ function _showInfos(){
_showContainers long _showContainers long
h2 INFO h2 INFO
h3 "processes" h3 "processes webserver"
docker-compose top # docker-compose top
docker top "${APP_NAME}-server"
if [ ! "$DB_ADD" = "false" ]; then
h3 "processes database"
docker top "${APP_NAME}-db"
fi
h3 "Check app port" h3 "Check app port"
>/dev/tcp/localhost/${APP_PORT} 2>/dev/null && ( if echo >"/dev/tcp/localhost/${APP_PORT}"; then
echo "OK, app port ${APP_PORT} is reachable" echo "OK, app port ${APP_PORT} is reachable"
echo echo
_showBrowserurl _showBrowserurl
) else
echo "NO, app port ${APP_PORT} is not available"
fi 2>/dev/null
if [ "$DB_ADD" != "false" ]; then if [ "$DB_ADD" != "false" ]; then
h3 "Check database port" h3 "Check database port"
>/dev/tcp/localhost/${DB_PORT} >/dev/null 2>&1 && ( if echo >"/dev/tcp/localhost/${DB_PORT}"; then
echo "OK, db port ${DB_PORT} is reachable" echo "OK, db port ${DB_PORT} is reachable"
echo echo
) echo "In a local DB admin tool you can connect it:"
echo "In a local DB admin tool:"
echo " host : localhost" echo " host : localhost"
echo " port : ${DB_PORT}" echo " port : ${DB_PORT}"
echo " user : root" echo " user : root"
echo " password: ${MYSQL_ROOT_PASS}" echo " password: ${MYSQL_ROOT_PASS}"
else
echo "NO, db port ${DB_PORT} is not available"
fi 2>/dev/null
fi fi
echo echo
} }
# helper for menu: print an inverted key # helper for menu: print an inverted key
function _key(){ function _key(){
printf "\e[4;7m ${1} \e[0m" echo -en "\e[4;7m ${1} \e[0m"
} }
# helper: wait for a return key # helper: wait for a return key
...@@ -321,8 +420,13 @@ while true; do ...@@ -321,8 +420,13 @@ while true; do
if [ -z "$action" ]; then if [ -z "$action" ]; then
echo "_______________________________________________________________________________"
echo
echo
echo " ${APP_NAME^^} :: Initializer for docker"
echo " ______"
echo "________________________________________________________________________/ $_version"
echo echo
echo -e "\e[32m===== INITIALIZER FOR DOCKER APP [$APP_NAME] v$_version ===== \e[0m\n\r"
_showContainers _showContainers
...@@ -336,7 +440,7 @@ while true; do ...@@ -336,7 +440,7 @@ while true; do
case "$action" in case "$action" in
"-h") showHelp; exit 0 ;; "-h") showHelp; exit 0 ;;
"-v") echo $(basename $0) $_version; exit 0 ;; "-v") echo "$_self $_version"; exit 0 ;;
g) g)
_removeGitdata _removeGitdata
;; ;;
...@@ -357,7 +461,7 @@ while true; do ...@@ -357,7 +461,7 @@ while true; do
;; ;;
u|U) u|U)
h2 "Bring up..." h2 "Bring up..."
dockerUp="docker-compose -p "$APP_NAME" --verbose up -d --remove-orphans" dockerUp="docker-compose -p $APP_NAME --verbose up -d --remove-orphans"
if [ "$action" = "U" ]; then if [ "$action" = "U" ]; then
dockerUp+=" --build" dockerUp+=" --build"
fi fi
...@@ -387,14 +491,14 @@ while true; do ...@@ -387,14 +491,14 @@ while true; do
dockerid=$_containers dockerid=$_containers
else else
echo "Select a container:" echo "Select a container:"
echo "$_containers" | sed "s#^# #g" sed "s#^# #g" <<< "$_containers"
echo -n "id or name >" echo -n "id or name >"
read dockerid read -r dockerid
fi fi
test -z "$dockerid" || ( test -z "$dockerid" || (
echo echo
echo "> docker exec -it $dockerid /bin/bash (type 'exit' + Return when finished)" echo "> docker exec -it $dockerid /bin/bash (type 'exit' + Return when finished)"
docker exec -it $dockerid /bin/bash docker exec -it "$dockerid" /bin/bash
) )
;; ;;
p) p)
...@@ -402,14 +506,15 @@ while true; do ...@@ -402,14 +506,15 @@ while true; do
dockerid="${APP_NAME}-server" dockerid="${APP_NAME}-server"
echo -n "Scanning ... " echo -n "Scanning ... "
_iFiles=$( docker exec -it $dockerid /bin/bash -c "find . -name '*.php' " | wc -l ) typeset -i _iFiles
_iFiles=$( docker exec -it "$dockerid" /bin/bash -c "find . -name '*.php' " | wc -l )
if [ $_iFiles -gt 0 ]; then if [ $_iFiles -gt 0 ]; then
echo "found $_iFiles [*.php] files ... errors from PHP $APP_PHP_VERSION linter:" echo "found $_iFiles [*.php] files ... errors from PHP $APP_PHP_VERSION linter:"
time if echo $APP_PHP_VERSION | grep -E "([567]\.|8\.[012])" >/dev/null ; then time if echo "$APP_PHP_VERSION" | grep -E "([567]\.|8\.[012])" >/dev/null ; then
docker exec -it $dockerid /bin/bash -c "find . -name '*.php' -exec php -l {} \; | grep -v '^No syntax errors detected'" docker exec -it "$dockerid" /bin/bash -c "find . -name '*.php' -exec php -l {} \; | grep -v '^No syntax errors detected'"
else else
docker exec -it $dockerid /bin/bash -c "php -l \$( find . -name '*.php' ) | grep -v '^No syntax errors detected' " docker exec -it "$dockerid" /bin/bash -c "php -l \$( find . -name '*.php' ) | grep -v '^No syntax errors detected' "
fi fi
echo echo
_wait _wait
......
# Installation of CISERVER # # Installation of CISERVER
You can install the CISERVER on your own host. You need full access to the system - it won't run on a shared hosting. You can install the CISERVER on your own host. You need full access to the system - it won't run on a shared hosting.
## Apache Httpd + PHP ## ## Apache Httpd + PHP
Install an Apache httpd and enablethese modules. Install an Apache httpd and enablethese modules.
...@@ -10,17 +10,17 @@ Install an Apache httpd and enablethese modules. ...@@ -10,17 +10,17 @@ Install an Apache httpd and enablethese modules.
- proxy + proxy_fcgi (or proxy_http) for a proxy - proxy + proxy_fcgi (or proxy_http) for a proxy
- socache_shmcb (on Debian for ssl connections) - socache_shmcb (on Debian for ssl connections)
For PHP 8.1 we need these packages For PHP 8.x we need these packages
- php-fpm - php-fpm
- php-curl - php-curl
- php-intl - php-intl
- php-mbstring - php-mbstring
- php-ldap - php-ldap (for ldap authentication)
- php-sqlite3 - php-sqlite3
- php-xml - php-xml
## Other required tools ## ## Other required tools
These commandline tools must be installed. These commandline tools must be installed.
...@@ -28,7 +28,7 @@ These commandline tools must be installed. ...@@ -28,7 +28,7 @@ These commandline tools must be installed.
- rsync - rsync
- git - git
## Get sources ## ## Get sources
Extract the repository in `/var/www/ciserver.example.org`. Extract the repository in `/var/www/ciserver.example.org`.
You can download the archive from the git repository or use `git clone`. You can download the archive from the git repository or use `git clone`.
...@@ -41,7 +41,7 @@ mv imldeployment ciserver.example.com ...@@ -41,7 +41,7 @@ mv imldeployment ciserver.example.com
The directory `/var/www/ciserver.example.com` is called approot in further documentation. The directory `/var/www/ciserver.example.com` is called approot in further documentation.
## Update virtual host config ## ## Update virtual host config
Set the document root to the subdir `public_html`. Set the document root to the subdir `public_html`.
We need two rewrite rules to redirect requests. We need two rewrite rules to redirect requests.
...@@ -104,7 +104,7 @@ If you use ansible you can use this snippet. ...@@ -104,7 +104,7 @@ If you use ansible you can use this snippet.
- '/var/imldeployment/packages/_files' - '/var/imldeployment/packages/_files'
``` ```
## Enable shell for Apache service user ## ## Enable shell for Apache service user
The service user of the webservice needs to execute commands with php function exec. By default this user has set nologin as shell - this muust be changed to `bin/bash`. The service user of the webservice needs to execute commands with php function exec. By default this user has set nologin as shell - this muust be changed to `bin/bash`.
......
# Installation with a local Docker service # # Installation with a local Docker service
For development a docker environment is part of the repository data. For development a docker environment is part of the repository data.
## Requirements ## ## Requirements
* Linux system * Linux system
* a running rootless Docker service * a running rootless Docker service
...@@ -14,7 +14,7 @@ For development a docker environment is part of the repository data. ...@@ -14,7 +14,7 @@ For development a docker environment is part of the repository data.
* to set ACL permissions with setfacl * to set ACL permissions with setfacl
* to remove tmp data * to remove tmp data
## Get Sources ## ## Get Sources
As your local user execute the following steps: As your local user execute the following steps:
...@@ -24,7 +24,19 @@ git https://git-repo.iml.unibe.ch/iml-open-source/imldeployment.git ...@@ -24,7 +24,19 @@ git https://git-repo.iml.unibe.ch/iml-open-source/imldeployment.git
cd imldeployment cd imldeployment
``` ```
## Set permissions ## ## Prepare and bring up container
### Quick method
Set permissions, update templates and start the container:
```shell
./docker/init.sh i t u q
```
OR do in step by step like described in the chapters below.
### Set permissions
In the folder `docker` are all configurations and helpers to run a docker container. In the folder `docker` are all configurations and helpers to run a docker container.
In it is an `init.sh` to set environment. In it is an `init.sh` to set environment.
...@@ -85,14 +97,14 @@ You will see something like that: ...@@ -85,14 +97,14 @@ You will see something like that:
+ set +vx + set +vx
``` ```
## Start container ## ### Start container
Then press `u` and `Return` to run `docker-compuse up`. Then press `u` and `Return` to run `docker-compuse up`.
On the 1st run it needs to download the PHP docker image with Apache httpd and takes a few more seconds. On the 1st run it needs to download the PHP docker image with Apache httpd and takes a few more seconds.
If ist is up you can run <http://localhost:8002/> in your webbrowser. If ist is up you can run <http://localhost:8002/> in your webbrowser.
## Change port ## ## Change port
If you need to change the port then stop a running container. If you need to change the port then stop a running container.
Edit `docker/init.sh.cfg` and set a new port Edit `docker/init.sh.cfg` and set a new port
...@@ -107,8 +119,10 @@ APP_PORT=8002 ...@@ -107,8 +119,10 @@ APP_PORT=8002
After any change in init.sh.cfg we update the configs with After any change in init.sh.cfg we update the configs with
```shell ```shell
./docker/init.sh ./docker/init.sh t u q
``` ```
Then press `t` (generate files from templates) + `Return`. Then press `t` (generate files from templates) + `Return`.
If you start the container again the application is available under the new port. If you start the container again the application is available under the new port.
The key `u` brings up the container.
\ No newline at end of file
# File structure # # File structure
* web - ui and api * web - ui and api
* data dir - configuration, database, built archives * data dir - configuration, database, built archives
* temp area - checked out projects to read comit messages * temp area - checked out projects to read comit messages
## Approot and website ## ## Approot and website
Default: /var/www/[YOUR-DOMAIN]/public_html/ Default: /var/www/[YOUR-DOMAIN]/public_html/
...@@ -59,7 +59,7 @@ Default: /var/www/[YOUR-DOMAIN]/public_html/ ...@@ -59,7 +59,7 @@ Default: /var/www/[YOUR-DOMAIN]/public_html/
└── webservice └── webservice
``` ```
## Data ## ## Data
By default: /var/imldeployment By default: /var/imldeployment
...@@ -75,6 +75,6 @@ imldeployment/ ...@@ -75,6 +75,6 @@ imldeployment/
└── _files └── _files
``` ```
## Temp ## ## Temp
By default: /var/tmp/imldeployment By default: /var/tmp/imldeployment
# Dependencies # # Dependencies
Related Components of the CI server Related Components of the CI server
......
...@@ -4,4 +4,3 @@ The configuration is a combination of ...@@ -4,4 +4,3 @@ The configuration is a combination of
* config/config_defaults.php - containing shipped defaults (do not edit) * config/config_defaults.php - containing shipped defaults (do not edit)
* config/config_custom.php - for your overrides of all default settings * config/config_custom.php - for your overrides of all default settings
# Build # # Build
A build process can be started ... A build process can be started ...
...@@ -10,25 +10,25 @@ Among its steps are some builtin, some depend on the project settings and some c ...@@ -10,25 +10,25 @@ Among its steps are some builtin, some depend on the project settings and some c
A build is denied if a project has no activated phase the project settings. A build is denied if a project has no activated phase the project settings.
## Overview ## ## Overview
![Build process](/images/processes-build.png "Build process") ![Build process](/images/processes-build.png "Build process")
## Steps ## ## Steps
### Create working directory ### ### Create working directory
Outdated kept builds will be cleaned up. Outdated kept builds will be cleaned up.
Below `/var/imldeployment/build/` a subdirectory with the id of the project will be created. In that one a uniq directory will be created by using a timestamp. Below `/var/imldeployment/build/` a subdirectory with the id of the project will be created. In that one a uniq directory will be created by using a timestamp.
### Get sources ### ### Get sources
The `git clone` fetches the sources from the Git repository The `git clone` fetches the sources from the Git repository
Remark: at the moment ony Git is suported as version control system. An interface in the classes subdir describes the required method to be implemented. An additional VCS will be available in the project settings if it was added. Remark: at the moment ony Git is suported as version control system. An interface in the classes subdir describes the required method to be implemented. An additional VCS will be available in the project settings if it was added.
### Project specific actions ### ### Project specific actions
An `chmod 755 /hooks/on*` makes hook scripts executable. An `chmod 755 /hooks/on*` makes hook scripts executable.
...@@ -43,7 +43,7 @@ Recommendation: ...@@ -43,7 +43,7 @@ Recommendation:
Use a script named `hooks/onbuild` and put your project specisif actions into it. Use a script named `hooks/onbuild` and put your project specisif actions into it.
Read the next chapters to use given environment and scripts. Read the next chapters to use given environment and scripts.
#### Custom vars #### #### Custom vars
A file named `ci-custom-vars` will be created containing the given data in the project config. Its idea is to be sourced by hook script to set variables in the current shell. A file named `ci-custom-vars` will be created containing the given data in the project config. Its idea is to be sourced by hook script to set variables in the current shell.
...@@ -64,7 +64,7 @@ cd .. ...@@ -64,7 +64,7 @@ cd ..
echo myVar=$myVar echo myVar=$myVar
``` ```
#### Builtin environment #### #### Builtin environment
* $GIT_SSH - full path to git ssh wrapper (CI-Root/shellscripts/gitsshwrapper.sh) * $GIT_SSH - full path to git ssh wrapper (CI-Root/shellscripts/gitsshwrapper.sh)
* $DIR_SSH_KEYS - full path to ssh keys (/var/imldeployment/data/sshkeys) * $DIR_SSH_KEYS - full path to ssh keys (/var/imldeployment/data/sshkeys)
...@@ -103,11 +103,11 @@ Important: at the end of the hook script uninstall it by using `nvmremove`. ...@@ -103,11 +103,11 @@ Important: at the end of the hook script uninstall it by using `nvmremove`.
* CI-Git-Repo .. nvm_init.sh: <https://git-repo.iml.unibe.ch/iml-open-source/imldeployment/-/blob/master/shellscripts/nvm_init.sh> * CI-Git-Repo .. nvm_init.sh: <https://git-repo.iml.unibe.ch/iml-open-source/imldeployment/-/blob/master/shellscripts/nvm_init.sh>
* NVM: <https://github.com/nvm-sh/> * NVM: <https://github.com/nvm-sh/>
### Remove vcs data ### ### Remove vcs data
The version control data (`.git` directory in build root) will be removed. The version control data (`.git` directory in build root) will be removed.
### Build or compress ### ### Build or compress
(1) (1)
A metafile `[Projecd_ID].json` will be created in the build root. It will be used to identify the package or installation. It contains date, branch and commit message. A metafile `[Projecd_ID].json` will be created in the build root. It will be used to identify the package or installation. It contains date, branch and commit message.
...@@ -124,17 +124,17 @@ The output dir is `/var/imldeployment/packages/_files/[Project_ID]/`. Here are s ...@@ -124,17 +124,17 @@ The output dir is `/var/imldeployment/packages/_files/[Project_ID]/`. Here are s
(3) (3)
If there are files in hooks/templates/ the will be copied into the package output directory. They can be used by automation tools like puppet to generate configuration files for different targets and different phases. If there are files in hooks/templates/ the will be copied into the package output directory. They can be used by automation tools like puppet to generate configuration files for different targets and different phases.
### Remove build dir ### ### Remove build dir
If all actions were successful the buld directory will be deleted. If all actions were successful the buld directory will be deleted.
### Add in queue of 1st phase ### ### Add in queue of 1st phase
A successful build triggers the queuing to the first active phase of this project. A successful build triggers the queuing to the first active phase of this project.
A phase can define deploy times to define, when a rollout is allowed. In the special case that the deploy time has no limit it will be installed instantly. Otherwise you will see the package in the queue column of a phase. A phase can define deploy times to define, when a rollout is allowed. In the special case that the deploy time has no limit it will be installed instantly. Otherwise you will see the package in the queue column of a phase.
## If a build fails ## ## If a build fails
The working directory will be kept. In the project config the number of kept projects is set (default: 3). Additionally old failed builds (older 7 days) will be deleted by a cronjob. The working directory will be kept. In the project config the number of kept projects is set (default: 3). Additionally old failed builds (older 7 days) will be deleted by a cronjob.
......
# CI Server # # CI Server
Free software and Open Source from University of Bern :: IML - Institute of Medical Education Free software and Open Source from University of Bern :: IML - Institute of Medical Education
...@@ -8,7 +8,7 @@ Free software and Open Source from University of Bern :: IML - Institute of Medi ...@@ -8,7 +8,7 @@ Free software and Open Source from University of Bern :: IML - Institute of Medi
- - - - - -
## Description ## ## Description
CI node that checks out projects from git repositories and builds an deployable archive. CI node that checks out projects from git repositories and builds an deployable archive.
The archives can be synched to multiple deployment targets e.g. puppet master or a protected software archive. The archives can be synched to multiple deployment targets e.g. puppet master or a protected software archive.
...@@ -40,7 +40,7 @@ This project is related to ...@@ -40,7 +40,7 @@ This project is related to
* CI package server <https://git-repo.iml.unibe.ch/iml-open-source/ci-pkg> * CI package server <https://git-repo.iml.unibe.ch/iml-open-source/ci-pkg>
* Deployment client written in bash <https://git-repo.iml.unibe.ch/iml-open-source/imldeployment-client> * Deployment client written in bash <https://git-repo.iml.unibe.ch/iml-open-source/imldeployment-client>
## Features ## ## Features
* checkout from git via SSH with multiple ssh keys (can be extended with a plugin) * checkout from git via SSH with multiple ssh keys (can be extended with a plugin)
* build has hooks to customize build process * build has hooks to customize build process
...@@ -54,7 +54,7 @@ This project is related to ...@@ -54,7 +54,7 @@ This project is related to
* sends messages (email, Slack) * sends messages (email, Slack)
* API to start a build from somewhere, e.g. from a devops workplace or Gitlab server * API to start a build from somewhere, e.g. from a devops workplace or Gitlab server
## Screenshots ## ## Screenshots
The overview over all projects is the starting page after login. It shows all projects and which build is rolled out to which phase. The overview over all projects is the starting page after login. It shows all projects and which build is rolled out to which phase.
......
docs/images/screenshot_overview_all_projects.png

161 KiB | W: | H:

docs/images/screenshot_overview_all_projects.png

241 KiB | W: | H:

docs/images/screenshot_overview_all_projects.png
docs/images/screenshot_overview_all_projects.png
docs/images/screenshot_overview_all_projects.png
docs/images/screenshot_overview_all_projects.png
  • 2-up
  • Swipe
  • Onion skin
docs/images/screenshot_overview_project.png

109 KiB | W: | H:

docs/images/screenshot_overview_project.png

129 KiB | W: | H:

docs/images/screenshot_overview_project.png
docs/images/screenshot_overview_project.png
docs/images/screenshot_overview_project.png
docs/images/screenshot_overview_project.png
  • 2-up
  • Swipe
  • Onion skin
/* /*
override css elements of daux.io blue theme override css elements of daux.io blue theme
version 2022-11-30 version 2023-11-10
*/ */
:root { :root {
/* Axels Overrides */ /* Axels Overrides */
--color-text: #222; --color-text: #234;
--link-color: #822; --link-color: #228;
--brand-color: var(--color-secondary); --brand-color: var(--color-text);
--brand-background: var(--body-background); --brand-background: var(--body-background);
--code-tag-border-color: #d8d8d8;
--hr-color: none; --hr-color: none;
--search-field-background: none; --search-field-background: none;
--search-field-border-color: none; --search-field-border-color: none;
...@@ -24,29 +25,32 @@ ...@@ -24,29 +25,32 @@
--axel_brand-pre-background-hover: rgb(255, 0, 51); --axel_brand-pre-background-hover: rgb(255, 0, 51);
; ;
--axel_h1_header: none; --axel_h1_header: none;
--axel_h1: #345; --axel_h1: #111;
--axel_h1-bg: none; --axel_h1-bg: none;
--axel_h1-bottom: 3px solid none; --axel_h1-bottom: 3px solid none;
--axel_h2: #156; --axel_h2: #222;
--axel_h2-bg: #f8fafb; --axel_h2-bg: none;
--axel_h2-bottom: 2px solid #467; --axel_h2-bottom: 0px solid #467;
--axel_h2-hero-bottom: 2px solid #912; --axel_h2-hero-bottom: 2px solid #912;
--axel_h3: #278; --axel_h3: #333;
--axel_h3-bottom: 1px solid #ddd; --axel_h3-bottom: 0px solid #ddd;
--axel_h4: #444;
--axel_hero_bg: #f8f8f8; --axel_hero_bg: #f8f8f8;
--axel_img-border: 2px dashed #ccc;
--axel_nav-bg: #fcfcfc; --axel_nav-bg: #fcfcfc;
--axel_nav-buttomborder: #ddd; --axel_nav-buttomborder: #ddd;
--axel_pre-background: #f8f8f8; --axel_pre-background: #f8f8f8;
--axel-th-background: #d0e0e8; --axel-th-background: #e0e4e8;
--axel-article-nav-border-top: 0px dotted #ddd; --axel-article-nav-border-top: 0px dotted #ddd;
} }
.dark { .dark {
/* Axels Overrides */ /* Axels Overrides */
--color-text: #c0c0c0; --color-text: #c0c0c0;
--link-color: #b44; --link-color: #88e;
--brand-color: var(--color-text); --brand-color: var(--color-text);
--brand-background: var(--body-background); --brand-background: var(--body-background);
--body-background: #101418;
--hr-color: none; --hr-color: none;
--code-tag-background-color_: #bcc; --code-tag-background-color_: #bcc;
--search-field-background: none; --search-field-background: none;
...@@ -63,16 +67,17 @@ ...@@ -63,16 +67,17 @@
--axel_brand-pre-background-hover: rgb(255, 0, 51); --axel_brand-pre-background-hover: rgb(255, 0, 51);
; ;
--axel_h1_header: none; --axel_h1_header: none;
--axel_h1: #777; --axel_h1: #578;
--axel_h1-bg: none; --axel_h1-bg: none;
--axel_h1-bottom: none; --axel_h1-bottom: none;
--axel_h2: #467; --axel_h2: #467;
--axel_h2-bg: #202020; --axel_h2-bg: none;
--axel_h2-bottom: 2px solid #256; --axel_h2-bottom: 0px solid #256;
--axel_h2-hero-bottom: 2px solid #712; --axel_h2-hero-bottom: 2px solid #712;
--axel_h3: #589; --axel_h3: #589;
--axel_h3-bottom: 1px solid #333; --axel_h3-bottom: 0px solid #333;
--axel_hero_bg: #242424; --axel_hero_bg: #242424;
--axel_img-border: 2px dashed #555;
--axel_nav-bg: #242424; --axel_nav-bg: #242424;
--axel_nav-buttomborder: #555; --axel_nav-buttomborder: #555;
--axel_pre-background: #bcc; --axel_pre-background: #bcc;
...@@ -133,7 +138,7 @@ a.Brand { ...@@ -133,7 +138,7 @@ a.Brand {
.s-content h2 { .s-content h2 {
background: var(--axel_h2-bg); background: var(--axel_h2-bg);
color: var(--axel_h2); color: var(--axel_h2);
font-size: 180%; font-size: 190%;
font-weight: bold; font-weight: bold;
margin-top: 4em; margin-top: 4em;
border-bottom: var(--axel_h2-bottom); border-bottom: var(--axel_h2-bottom);
...@@ -147,6 +152,12 @@ h2:first-of-type { ...@@ -147,6 +152,12 @@ h2:first-of-type {
margin-top: 0em; margin-top: 0em;
} }
img{
border: var(--axel_img-border);
border-radius: 1.5em;
padding: 0.7em;
}
.s-content h3 { .s-content h3 {
background: var(--axel_h3-bg); background: var(--axel_h3-bg);
color: var(--axel_h3); color: var(--axel_h3);
...@@ -156,14 +167,26 @@ h2:first-of-type { ...@@ -156,14 +167,26 @@ h2:first-of-type {
border-bottom: var(--axel_h3-bottom); border-bottom: var(--axel_h3-bottom);
} }
.s-content h4 {
margin: 0; .s-content > h4 {
font-size: 100%; color: var(--axel_h4);
font-size: 135%;
font-weight: bold;
margin: 2em 0;
}
.s-content .TableOfContentsContainer h4 {
margin: 1em 0;
font-size: 110%;
text-align: center; text-align: center;
background-color: rgba(0, 0, 0, 0.05); background-color: rgba(0, 0, 0, 0.1);
padding: 0.3em; padding: 0.3em;
font-weight: bold;
font-family: Arial;
}
ul.TableOfContents a{
color: var(--color-text);
} }
.s-content pre { .s-content pre {
background: var(--axel_pre-background); background: var(--axel_pre-background);
} }
......
# CI Server # # CI Server
Free software and Open Source from University of Bern :: IML - Institute of Medical Education Free software and Open Source from University of Bern :: IML - Institute of Medical Education
📄 Source: <https://git-repo.iml.unibe.ch/iml-open-source/imldeployment> \ 📄 Source: <https://git-repo.iml.unibe.ch/iml-open-source/imldeployment> \
📜 License: GNU GPL 3.0 \ 📜 License: GNU GPL 3.0 \
📖 Docs: <https://os-docs.iml.unibe.ch/imldeployment/> 📗 Docs: <https://os-docs.iml.unibe.ch/imldeployment/>
- - - - - -
## Description ## ## Description
CI node that checks out projects from git repositories and builds an deployable archive. CI node that checks out projects from git repositories and builds an deployable archive.
The archives can be synched to multiple deployment targets e.g. puppet master or a protected software archive. The archives can be synched to multiple deployment targets e.g. puppet master or a protected software archive.
## Related projects ## ## Related projects
* CI package server <https://git-repo.iml.unibe.ch/iml-open-source/ci-pkg> * CI package server <https://git-repo.iml.unibe.ch/iml-open-source/ci-pkg>
* Deployment client written in bash <https://git-repo.iml.unibe.ch/iml-open-source/imldeployment-client> * Deployment client written in bash <https://git-repo.iml.unibe.ch/iml-open-source/imldeployment-client>
## Features ## ## Features
* API to start a build from somewhere, e.g. from a devops workplace or Gitlab server * API to start a build from somewhere, e.g. from a devops workplace or Gitlab server
* checkout from git via SSH with multiple ssh keys (can be extended with a plugin) * checkout from git via SSH with multiple ssh keys (can be extended with a plugin)
...@@ -32,7 +32,7 @@ The archives can be synched to multiple deployment targets e.g. puppet master or ...@@ -32,7 +32,7 @@ The archives can be synched to multiple deployment targets e.g. puppet master or
* receives install status * receives install status
* sends messages (email, Slack) * sends messages (email, Slack)
## Screenshot ## ## Screenshot
The overview over all projects is the starting page after login. It shows all projects and which build is rolled out to which phase. The overview over all projects is the starting page after login. It shows all projects and which build is rolled out to which phase.
......
...@@ -7,9 +7,10 @@ ...@@ -7,9 +7,10 @@
# #
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# 2024-01-19 v1.0 <axel.hahn@iml.unibe.ch> first lines # 2024-01-19 v1.0 <axel.hahn@iml.unibe.ch> first lines
# 2024-07-25 v1.1 <axel.hahn@iml.unibe.ch> deny root access; shell fixes
# ====================================================================== # ======================================================================
cd $( dirname $0 )/.. cd "$( dirname "$0" )/.." || exit 1
CI_APPROOT=$( pwd ) CI_APPROOT=$( pwd )
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
...@@ -24,6 +25,14 @@ cat <<HEADEREND ...@@ -24,6 +25,14 @@ cat <<HEADEREND
HEADEREND HEADEREND
# ----------------------------------------------------------------------
# deny start as root
# ----------------------------------------------------------------------
if [ "$( id -u )" -eq 0 ]; then
echo "ERROR: do not start this script as root."
exit 1
fi
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# detect workdir # detect workdir
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
...@@ -42,9 +51,9 @@ builddir="$CI_WORKDIR/build/" ...@@ -42,9 +51,9 @@ builddir="$CI_WORKDIR/build/"
# detect builds on error # detect builds on error
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
ls $builddir >/dev/null || exit 1 ls "$builddir" >/dev/null || exit 1
echo "Searching for builds im $builddir..." echo "Searching for builds im $builddir..."
founddirs=$( find $builddir -maxdepth 2 -type d | grep '2[0-1][0-9][0-9][0-1][0-9][0-3][0-9]' | sort ) founddirs=$( find "$builddir" -maxdepth 2 -type d | grep '2[0-1][0-9][0-9][0-1][0-9][0-3][0-9]' | sort )
if [ -z "$founddirs" ]; then if [ -z "$founddirs" ]; then
echo "Good news: No build dirs (builds on error) were found. Aborting." echo "Good news: No build dirs (builds on error) were found. Aborting."
...@@ -69,7 +78,6 @@ echo -n "I want to jump to > " ...@@ -69,7 +78,6 @@ echo -n "I want to jump to > "
read -r DIR_APPROOT read -r DIR_APPROOT
test -z "$DIR_APPROOT" && exit 1 test -z "$DIR_APPROOT" && exit 1
# DIR_APPROOT="/var/imldeployment/build/$DIR_APPROOT"
ls "$DIR_APPROOT" >/dev/null || exit 2 ls "$DIR_APPROOT" >/dev/null || exit 2
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
...@@ -82,7 +90,7 @@ export DIR_SSH_KEYS="$CI_WORKDIR/data/sshkeys" ...@@ -82,7 +90,7 @@ export DIR_SSH_KEYS="$CI_WORKDIR/data/sshkeys"
export NVMINIT="$CI_APPROOT/shellscripts/nvm_init.sh"; export NVMINIT="$CI_APPROOT/shellscripts/nvm_init.sh";
export RVMSCRIPT="/usr/local/rvm/scripts/rvm"; export RVMSCRIPT="/usr/local/rvm/scripts/rvm";
cd "$DIR_APPROOT" cd "$DIR_APPROOT" || exit 1
cat <<EOF cat <<EOF
* Switching now into build dir * Switching now into build dir
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment