From 063c327843c21380ab2e6eb71ad25d098893db2d Mon Sep 17 00:00:00 2001 From: "Hahn Axel (hahn)" <axel.hahn@unibe.ch> Date: Fri, 10 Jan 2025 17:21:04 +0100 Subject: [PATCH] docker dev env: update, Use PHP 8.4 --- docker/containers/web-server/Dockerfile | 2 +- docker/docker-compose.yml | 2 +- docker/init.sh | 208 ++++++++++++++++++++++-- docker/init.sh.cfg | 5 +- 4 files changed, 198 insertions(+), 19 deletions(-) diff --git a/docker/containers/web-server/Dockerfile b/docker/containers/web-server/Dockerfile index 75b0974..db0a24c 100644 --- a/docker/containers/web-server/Dockerfile +++ b/docker/containers/web-server/Dockerfile @@ -1,7 +1,7 @@ # # GENERATED BY init.sh - template: templates/web-server-Dockerfile - 42dce773c83597a7d05af398bdd66d15 # -FROM php:8.3-apache +FROM php:8.4-apache # install packages RUN apt-get update && apt-get install -y git unzip zip diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 4fa133f..951f3e7 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -19,7 +19,7 @@ services: build: context: . dockerfile: ./containers/web-server/Dockerfile - image: "php:8.3-apache" + image: "php:8.4-apache" container_name: 'my_new_app-server' ports: - '${APP_PORT}:80' diff --git a/docker/init.sh b/docker/init.sh index d752235..04fc725 100755 --- a/docker/init.sh +++ b/docker/init.sh @@ -24,20 +24,28 @@ # 2024-07-29 v1.17 <www.axel-hahn.de> hide unnecessary menu items; reorder functions # 2024-08-14 v1.18 <www.axel-hahn.de> update container view # 2024-09-20 v1.19 <www.axel-hahn.de> detect dockerd-rootless (hides menu item to set permissions) +# 2024-10-16 v1.20 <axel.hahn@unibe.ch> add db import and export +# 2024-10-25 v1.21 <axel.hahn@unibe.ch> create missing subdir dbdumps +# 2024-10-30 v1.22 <axel.hahn@unibe.ch> added: Open Mysql client in container +# 2024-10-30 v1.23 <axel.hahn@unibe.ch> added: show menu hints why some menu items are visible +# 2024-11-20 v1.24 <axel.hahn@unibe.ch> fix menu with started database less app; apply template permissions on target file; add $WEBURL; remove $frontendurl +# 2024-11-20 v1.25 <axel.hahn@unibe.ch> fix menu startup containers +# 2024-11-21 v1.26 <axel.hahn@unibe.ch> Reset colors in _checkConfig # ====================================================================== cd "$( dirname "$0" )" || exit 1 +_version="1.26" + # init used vars gittarget= -frontendurl= +WEBURL= _self=$( basename "$0" ) # shellcheck source=/dev/null . "${_self}.cfg" || exit 1 -_version="1.19" # git@git-repo.iml.unibe.ch:iml-open-source/docker-php-starterkit.git selfgitrepo="docker-php-starterkit.git" @@ -55,14 +63,19 @@ fgReset="\e[0m" # running containers DC_WEB_UP=0 DC_DB_UP=0 +DC_ALL_UP=0 # repo of docker-php-starterkit is here? DC_REPO=1 DC_CONFIG_CHANGED=0 +# absolute urls for web app DC_WEB_URL="" +DC_DUMP_DIR=dbdumps +DC_SHOW_MENUHINTS=0 + isDockerRootless=0 ps -ef | grep dockerd-rootless | grep -q $USER && isDockerRootless=1 @@ -70,6 +83,19 @@ ps -ef | grep dockerd-rootless | grep -q $USER && isDockerRootless=1 # FUNCTIONS # ---------------------------------------------------------------------- +# check config for changes in newer versions +function _checkConfig(){ + + # --- v1.24 + if [ -z "$WEBURL" ]; then + echo -e "${fgBrown}INFO: add 'WEBURL=\"/\"' in your ${_self}.cfg. It is a new var since v1.24${fgReset}" + WEBURL="/" + fi + if [ -n "$frontendurl" ]; then + echo -e "${fgBrown}INFO: Remove frontendurl=$frontendurl in your ${_self}.cfg. It is obsolete since v1.24${fgReset}" + fi + +} # ---------------------------------------------------------------------- # STATUS FUNCTIONS @@ -97,13 +123,38 @@ function _getStatus_docker(){ DC_WEB_UP=0 DC_DB_UP=0 + DC_ALL_UP=0 + grep -q "${APP_NAME}-server" <<< "$_out" && DC_WEB_UP=1 grep -q "${APP_NAME}-db" <<< "$_out" && DC_DB_UP=1 + + if [ "$DB_ADD" != "false" ] && [ ! -d "${DC_DUMP_DIR}" ]; then + echo "INFO: creating subdir ${DC_DUMP_DIR} to import/ export databases ..." + mkdir "${DC_DUMP_DIR}" || exit 1 + return + fi + + if [ "${DC_WEB_UP}" = "1" ] && [ "${DC_DB_UP}" = "1" ]; then + DC_ALL_UP=1 + fi + + if [ "$DB_ADD" = "false" ] && [ "${DC_WEB_UP}" = "1" ]; then + DC_ALL_UP=1 + fi + } +# Get web url of the application +# It is for support of Nginx Docker Proxy +# https://github.com/axelhahn/nginx-docker-proxy +# It returns http://localhost:<port> or a https://<appname> plus $WEBURL function _getWebUrl(){ - DC_WEB_URL="$frontendurl" - grep -q "${APP_NAME}-server" /etc/hosts && DC_WEB_URL="https://${APP_NAME}-server/" + if grep -q "^[0-9\.]* ${APP_NAME}-server" /etc/hosts; then + DC_WEB_URL="https://${APP_NAME}-server$WEBURL" + else + DC_WEB_URL=http://localhost:${APP_PORT}$WEBURL + fi + set +vx } # ---------------------------------------------------------------------- @@ -123,7 +174,16 @@ function h3(){ # helper for menu: print an inverted key function _key(){ - echo -en "\e[4;7m ${1} \e[0m" + echo -en "$fgInvert ${1} $fgReset" +} + +# helper for menu: show hint text +# param int FLag _bAll (i true the txt will be hidden) +# param string message to show +function menuhint(){ + local _bAll="$1" + shift 1 + test $DC_SHOW_MENUHINTS -ne 0 && test "$_bAll" -eq "0" && ( echo -e "$fgBlue $*$fgReset" ) } # show menu in interactive mode and list keys in help with param -h @@ -137,38 +197,61 @@ function showMenu(){ echo if [ $DC_REPO -eq 1 ] || [ $_bAll -eq 1 ]; then + menuhint $_bAll "Git data of starterkit were found" echo "${_spacer}$( _key g ) - remove git data of starterkit" echo fi if [ $isDockerRootless -eq 1 ] || [ $_bAll -eq 1 ]; then + menuhint $_bAll "Because rootless docker was found" echo "${_spacer}$( _key i ) - init application: set permissions" + echo fi if [ $DC_CONFIG_CHANGED -eq 1 ] || [ $_bAll -eq 1 ]; then + menuhint $_bAll "Config was changed" echo "${_spacer}$( _key t ) - generate files from templates" + echo fi if [ $DC_CONFIG_CHANGED -eq 0 ] || [ $_bAll -eq 1 ]; then + menuhint $_bAll "Config is unchanged" echo "${_spacer}$( _key T ) - remove generated files" + echo fi - echo - if [ $DC_WEB_UP -eq 0 ] || [ $_bAll -eq 1 ]; then + if [ $DC_ALL_UP -eq 0 ] || [ $_bAll -eq 1 \ + ]; then if [ $DC_CONFIG_CHANGED -eq 0 ] || [ $_bAll -eq 1 ]; then + menuhint $_bAll "A container is down and config is unchanged" echo "${_spacer}$( _key u ) - startup containers docker-compose ... up -d" echo "${_spacer}$( _key U ) - startup containers docker-compose ... up -d --build" echo echo "${_spacer}$( _key r ) - remove containers docker-compose rm -f" + echo fi fi - if [ $DC_WEB_UP -eq 1 ] || [ $_bAll -eq 1 ]; then + if [ $DC_WEB_UP -eq 1 ] || [ $DC_DB_UP -eq 1 ] || [ $_bAll -eq 1 ]; then + menuhint $_bAll "A container is up" echo "${_spacer}$( _key s ) - shutdown containers docker-compose stop" echo echo "${_spacer}$( _key m ) - more infos" echo "${_spacer}$( _key o ) - open app [${APP_NAME}] $DC_WEB_URL" echo "${_spacer}$( _key c ) - console (bash)" + echo + fi + if [ $DC_WEB_UP -eq 1 ] || [ $_bAll -eq 1 ]; then + menuhint $_bAll "Web container is up" echo "${_spacer}$( _key p ) - console check with php linter" + echo fi - echo + if [ $DC_DB_UP -eq 1 ] || [ $_bAll -eq 1 ]; then + echo + menuhint $_bAll "Database container is up" + echo "${_spacer}$( _key d ) - Dump container database" + echo "${_spacer}$( _key D ) - Import Dump into container database" + echo "${_spacer}$( _key M ) - Open Mysql client in database container" + echo + fi + menuhint $_bAll "Always available" echo "${_spacer}$( _key q ) - quit" } @@ -313,7 +396,7 @@ function _fix_no-db(){ local iStart; typeset -i iStart iStart=$( grep -Fn "$CUTTER_NO_DATABASE" "${_file}" | cut -f 1 -d ':' )-1 if [ $iStart -gt 0 ]; then - sed -ni "1,${iStart}p" "${_file}" + sed -n "$sed_no_backup" "1,${iStart}p" "${_file}" fi fi } @@ -375,14 +458,15 @@ function _generateFiles(){ # write file from line 2 to a tmp file sed -n '2,$p' "$mytpl" >"$_tmpfile" + chmod "$( stat -c %a "$mytpl" )" "$_tmpfile" # add generator # sed -i "s#{{generator}}#generated by $0 - template: $mytpl - $( date )#g" $_tmpfile local _md5; _md5=$( md5sum $_tmpfile | awk '{ print $1 }' ) - sed -i "s#{{generator}}#GENERATED BY $_self - template: $mytpl - $_md5#g" $_tmpfile + sed -i "$sed_no_backup" "s#{{generator}}#GENERATED BY $_self - template: $mytpl - $_md5#g" $_tmpfile # apply all replacements to the tmp file - eval sed -i "$params" "$_tmpfile" || exit + eval sed "$sed_no_backup" "$params" "$_tmpfile" || exit _fix_no-db $_tmpfile @@ -395,7 +479,7 @@ function _generateFiles(){ echo -n "$mytpl - changes detected - writing [$target] ... " mkdir -p "$( dirname ../"$target" )" || exit 2 mv "$_tmpfile" "../$target" || exit 2 - echo OK + echo -e "${fgGreen}OK${fgReset}" echo fi else @@ -424,7 +508,7 @@ function _removeGeneratedFiles(){ echo -n "REMOVING " ls -l "../$target" || exit 2 rm -f "../$target" || exit 2 - echo OK + echo -e "${fgGreen}OK${fgReset}" else echo "SKIP: $target" fi @@ -498,10 +582,94 @@ function _wait(){ echo } +# DB TOOL - dump db from container +function _dbDump(){ + local _iKeepDumps; + typeset -i _iKeepDumps=5 + local _iStart; + typeset -i _iStart=$_iKeepDumps+1; + + if [ $DC_DB_UP -eq 0 ]; then + echo "Database container is not running. Aborting." + return + fi + outfile=${DC_DUMP_DIR}/${MYSQL_DB}_$( date +%Y%m%d_%H%M%S ).sql + echo -n "dumping ${MYSQL_DB} ... " + if docker exec -i "${APP_NAME}-db" mysqldump -uroot -p${MYSQL_ROOT_PASS} ${MYSQL_DB} > "$outfile"; then + echo -n "OK ... Gzip ... " + if gzip "${outfile}"; then + echo "OK" + ls -l "$outfile.gz" + + # CLEANUP + echo + echo "--- Cleanup: keep $_iKeepDumps files." + ls -1t ${DC_DUMP_DIR}/* | sed -n "$_iStart,\$p" | while read -r delfile + do + echo "CLEANUP: Deleting $delfile ... " + rm -f "$delfile" + done + echo + echo -n "Size of dump directory: " + du -hs ${DC_DUMP_DIR} | awk '{ print $1 }' + + else + echo "ERROR" + rm -f "$outfile" + fi + else + echo "ERROR" + rm -f "$outfile" + fi +} + +# DB TOOL - import local database dump into container +function _dbImport(){ + echo "--- Available dumps:" + ls -ltr ${DC_DUMP_DIR}/*.gz | sed "s#^# #g" + if [ $DC_DB_UP -eq 0 ]; then + echo "Database container is not running. Aborting." + return + fi + echo -n "Dump file to import into ${MYSQL_DB} > " + read -r dumpfile + if [ -z "$dumpfile" ]; then + echo "Abort - no value was given." + return + fi + if [ ! -f "$dumpfile" ]; then + echo "Abort - wrong filename." + return + fi + + echo -n "Importing $dumpfile ... " + + # Mac OS compatibility + # if zcat "$dumpfile" | docker exec -i "${APP_NAME}-db" mysql -uroot -p${MYSQL_ROOT_PASS} "${MYSQL_DB}" + if cat "$dumpfile" | zcat | docker exec -i "${APP_NAME}-db" mysql -uroot -p${MYSQL_ROOT_PASS} "${MYSQL_DB}" + then + echo "OK" + else + echo "ERROR" + fi +} + # ---------------------------------------------------------------------- # MAIN # ---------------------------------------------------------------------- +_checkConfig + +# Mac OS compatibility +case "$OSTYPE" in + darwin*|bsd*) + sed_no_backup=" -i '' " + ;; + *) + sed_no_backup="-i" + ;; +esac + action=$1; shift 1 while true; do @@ -612,6 +780,18 @@ while true; do echo "Start your docker container first." fi ;; + d) + h2 "DB tools :: dump" + _dbDump + ;; + D) + h2 "DB tools :: import" + _dbImport + ;; + M) + h2 "DB tools :: mysql client" + docker exec -it "${APP_NAME}-db" mysql -uroot -p${MYSQL_ROOT_PASS} "${MYSQL_DB}" + ;; o) h2 "Open app ..." xdg-open "$DC_WEB_URL" diff --git a/docker/init.sh.cfg b/docker/init.sh.cfg index e30c69e..c66e959 100644 --- a/docker/init.sh.cfg +++ b/docker/init.sh.cfg @@ -17,7 +17,7 @@ APP_APT_PACKAGES="git unzip zip" #APP_APACHE_MODULES="rewrite" APP_APACHE_MODULES="" -APP_PHP_VERSION=8.3 +APP_PHP_VERSION=8.4 # APP_PHP_MODULES="curl pdo_mysql mbstring xml zip xdebug" # APP_PHP_MODULES="curl mbstring xml zip xdebug" APP_PHP_MODULES="xdebug" @@ -61,9 +61,8 @@ DOCKER_USER_UID=33 # document root inside web-server container WEBROOT=/var/www/${APP_NAME}/public_html +WEBURL=/admin/ CUTTER_NO_DATABASE="CUT-HERE-FOR-NO-DATABASE" -frontendurl=http://localhost:${APP_PORT}/ - # ---------------------------------------------------------------------- -- GitLab