diff --git a/.dockerignore b/.dockerignore index 84dac53..b5dca8d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -32,4 +32,8 @@ Thumbs.db # Docker files Dockerfile .dockerignore -manage_container.sh \ No newline at end of file +manage_container.sh + +# Additional files +posts/admin.json +posts/admin.json.tmp \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index f9bf1cf..c592e41 100644 --- a/Dockerfile +++ b/Dockerfile @@ -49,4 +49,9 @@ HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ CMD wget --no-verbose --tries=1 --spider http://localhost:8080/ || exit 1 # Start the application -CMD ["npm", "start"] \ No newline at end of file +CMD ["npm", "start"] + +# Do NOT copy posts/admin.json or posts/admin.json.tmp into the image +# These files are excluded via .dockerignore for security +# In production, mount the posts directory as a volume to persist posts and admin password +# If posts/admin.json does not exist, the default admin password is 'admin' (see README) \ No newline at end of file diff --git a/manage_container.sh b/manage_container.sh index 0140d3d..e5da90c 100755 --- a/manage_container.sh +++ b/manage_container.sh @@ -4,7 +4,9 @@ IMAGE_NAME="markdown-blog" CONTAINER_NAME="markdown-blog-container" PORT=8080 -MARKDOWN_DIR="/home/rattatwinko/Documents/shit/markdownblog" # Update this to your local markdown directory +# Automatically set MARKDOWN_DIR to the directory where this script lives +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +MARKDOWN_DIR="$SCRIPT_DIR" # Use the script's directory as the default markdown directory # Colors for output RED='\033[0;31m' @@ -41,10 +43,80 @@ check_container_health() { fi } -# Function to build the Docker image +# Fun spinner and jokes for npm build (right-aligned, rainbow) +npm_spinner_right() { + local pid=$1 + local delay=0.15 + local spinstr='|/-\\' + local jokes=( + "NPM is downloading the entire internet..." + "TypeScript: It's like JavaScript, but with more errors!" + "JavaScript: Where '1' + 1 = '11'!" + "NPM: Installing 1000 dependencies for 'hello world'..." + "TypeScript: Making JavaScript developers feel safe (sometimes)." + "NPM: 5 minutes left... just kidding!" + "JavaScript: Because who needs types anyway?" + "NPM: One does not simply 'npm install' without warnings." + "TypeScript: The language that makes you write more code to do less." + "NPM: 0 vulnerabilities (in your dreams)." + ) + local colors=(31 33 32 36 34 35 91 92 93 94 95 96) + local joke_count=${#jokes[@]} + local joke_index=0 + tput civis + while kill -0 $pid 2>/dev/null; do + local temp="${spinstr#?}" + local cols=$(tput cols) + local msg="[%c] %s" + local joke="${jokes[$joke_index]}" + local out + printf -v out "$msg" "$spinstr" "$joke" + local pad=$((cols - ${#out} - 1)) + [ $pad -lt 0 ] && pad=0 + # Rainbow coloring + local rainbow="" + local i=0 + local len=${#out} + while [ $i -lt $len ]; do + local c="${out:$i:1}" + local color=${colors[$((i % ${#colors[@]}))]} + rainbow+="\033[${color}m$c\033[0m" + i=$((i+1)) + done + printf "\r%*s%s" $pad "" "$rainbow" + spinstr=$temp${spinstr%$temp} + sleep $delay + joke_index=$(( (joke_index + 1) % joke_count )) + done + printf "\r" + tput cnorm +} + +# Function to build the Docker image (show spinner/jokes only during npm ci) build_image() { echo -e "${YELLOW}Building Docker image...${NC}" - if ! docker build -t $IMAGE_NAME .; then + # Use a named pipe to capture docker build output + local pipe=$(mktemp -u) + mkfifo "$pipe" + # Start docker build, redirect output to pipe + (docker build -t $IMAGE_NAME . | tee "$pipe") & + build_pid=$! + # Watch the pipe for the npm ci step + while read -r line; do + echo "$line" + if [[ "$line" == *"RUN npm ci"* ]]; then + # Wait for the npm ci process to start in the background + sleep 1 + npm_spinner_right $build_pid & + spinner_pid=$! + wait $build_pid + kill $spinner_pid 2>/dev/null + break + fi + done < "$pipe" + wait $build_pid + rm -f "$pipe" + if [ $? -ne 0 ]; then echo -e "${RED}Error: Failed to build Docker image${NC}" exit 1 fi @@ -193,6 +265,15 @@ show_status() { fi } +# Function to auto-deploy: remove old container, build fresh image, start new container +autodeploy() { + echo -e "${YELLOW}Auto-deploying: remove old container, build fresh image, start new container...${NC}" + remove_container + echo -e "${YELLOW}Building Docker image (no cache)...${NC}" + build_image + start_container +} + # Check Docker is running before proceeding check_docker @@ -219,10 +300,43 @@ case "$1" in remove) remove_container ;; + autodeploy) + autodeploy + ;; *) - echo "Usage: $0 {build|start|stop|restart|logs|status|remove}" + echo "Usage: $0 {build|start|stop|restart|logs|status|remove|autodeploy}" exit 1 ;; esac -exit 0 \ No newline at end of file +# Record script start time +SCRIPT_START_TIME=$(date +%s) +exit 0 + +# At the very end, print a marathon joke with elapsed time +SCRIPT_END_TIME=$(date +%s) +ELAPSED=$((SCRIPT_END_TIME - SCRIPT_START_TIME)) +MIN=$((ELAPSED / 60)) +SEC=$((ELAPSED % 60)) +HOUR=$((ELAPSED / 3600)) +DAY=$((ELAPSED / 86400)) + +if [ $ELAPSED -lt 60 ]; then + TIME_STR="$ELAPSED seconds" +elif [ $ELAPSED -lt 3600 ]; then + TIME_STR="$MIN minutes, $SEC seconds" +elif [ $ELAPSED -lt 86400 ]; then + TIME_STR="$HOUR hours, $(( (ELAPSED % 3600) / 60 )) minutes" +else + TIME_STR="$DAY days, $(( (ELAPSED % 86400) / 3600 )) hours" +fi + +JOKES=( + "Marathon complete! NPM wasted: $TIME_STR." + "Build finished! JavaScript has evolved $TIME_STR into a new framework." + "Done! TypeScript found $TIME_STR worth of new types." + "Success! NPM installed $TIME_STR of dependencies you'll never use." + "Victory! You survived $TIME_STR of NPM's existential dread." +) +JOKE_INDEX=$((RANDOM % ${#JOKES[@]})) +echo -e "\n\033[1;32m${JOKES[$JOKE_INDEX]}\033[0m" \ No newline at end of file diff --git a/posts/admin.json b/posts/admin.json new file mode 100644 index 0000000..1fba3b4 --- /dev/null +++ b/posts/admin.json @@ -0,0 +1,3 @@ +{ + "hash": "$2b$12$pzYk2EcofgQSKH0NqpdDEO3kOWSzw2xhmrWu0E0q7lA0I0tF23aPe" +} \ No newline at end of file