cskth.kt
Nov 14 2023
4 MIN READ

My custom ghost scripts

import { Image } from 'astro

'; import dckLogsSample from './images/dcklogs-sample.jpg' import checkStatsSample from './images/checkstats-sample.jpg' import deeSample from './images/dee-sample.gif' import IconRocket from '@components/IconRocket.astro'

I promised from my first post that I'll share shell tools, and scripts I wrote that helps me quickly update and review my ghost server.

direnv

This shell tool declutters your shell environment by having environmment variables read only in directories where they make sense.

In this case, I have my .envrc in "/usr/chardskarth/docker-ghost" directory.

If then for example, I'm gonna work on another project, I cd out of ./docker-ghost directory, it unloads the environment variables that I have in that directory.

❗️ But, direnv only works to localize environment variables

Intuitively with direnv, besides environment variables, one would thought they should also be able to localize their shell functions and aliases. Unfortunately, that's not the case. direnv only exports env variables by default.

A better direnv

People are aware of this limitation and figured out a way around it. I copy pasted this guy's export_function and this guy's export_alias function to my ~/.direnv.

~/.direnvrc
export_function() {
13 collapsed lines
local name=$1
local alias_dir=$PWD/.direnv/aliases
mkdir -p "$alias_dir"
PATH_add "$alias_dir"
local target="$alias_dir/$name"
if declare -f "$name" >/dev/null; then
echo "#!$SHELL" > "$target"
declare -f "$name" >> "$target" 2>/dev/null
# Notice that we add shell variables to the function trigger.
echo "$name \$*" >> "$target"
chmod +x "$target"
fi
}
export_alias() {
15 collapsed lines
local name=$1
shift
local alias_dir=$PWD/.direnv/aliases
local target="$alias_dir/$name"
local oldpath="$PATH"
mkdir -p "$alias_dir"
if ! [[ ":$PATH:" == *":$alias_dir:"* ]]; then
PATH_add "$alias_dir"
fi
echo "#!/usr/bin/env bash" > "$target"
echo "PATH=$oldpath" >> "$target"
echo "$@" >> "$target"
chmod +x "$target"
}

I now have localized aliases and shell functions. Magic. ✨

/usr/chardskarth/docker-ghost/.envrc
yarnzip() {
2 collapsed lines
yarn --cwd ghost/installed-themes/dawn/ zip
}
export_function yarnzip
rsyncghost() {
3 collapsed lines
rsync -av --exclude="node_modules" ghost/ root@chardskarth.me:docker-ghost/ghost
rsync -av --exclude="node_modules" root@chardskarth.me:docker-ghost/ghost/ ghost
}
export_function rsyncghost
restartghost() {
2 collapsed lines
ssh root@chardskarth.me "cd ./docker-ghost && docker compose up -d --force-recreate --no-deps ghost && docker compose logs -f ghost"
}
export_function restartghost
dck() {
2 collapsed lines
ssh root@chardskarth.me "cd ./docker-ghost && docker compose $@"
}
export_function dck
checkstats() {
10 collapsed lines
# get top 10 memory consuming applicatins
command="\
echo --- Top Memory Consuming --- &&\
ps -eo pid,ppid,cmd,comm,%mem,%cpu --sort=-%mem | head -10 &&\
echo --- SQL Data --- &&\
du -h ./docker-ghost/data/mysql/ &&\
echo --- RAM Stats --- &&\
free -m"
ssh root@chardskarth.me $command
}
export_function checkstats

Customize and deploy: yarnzip, rsyncghost, restartghost

I'm currently using ghost's dawn theme. I tweaked it a little for the custom tags page. After making changes, I run the yarnzip command to build dawn ghost theme.

After building, I run the rsyncghost command which syncs all files to my server's docker-ghost directory. (excluding the world's heaviest object)

After successfully syncing the files, I need to do a ghost restart, so I run restartghost command.

Easy. (not really)

Checking docker logs and stats: dck

I have a dck function which allows me to quickly check of the logs or processes running from my compose.yaml in my server.

Checking server stats: checkstats

Quick insights about server stats Running checkstats just gives me a quick overview. It gives me 3 things:

  1. The top 10 memory consuming applications
  2. Database storage consumption
  3. Remaining memory from ram and swapfile.

Conclusion

Having discovered direnv was a great turning point. In my years of software development experience, I always had conflicting names of the small utility functions I wrote. If I didn't have conflicts, I always had a hard time searching for them. Having all these scripts in directory where they only make sense helped me a lot to be organized.

Regarding the better direnv, there's almost always someone else out there who has experienced a similar struggle and have found out a way around it. I'll forever be amazed and dazzled about how smart people are always finding out a way to improve upon them. And thankful that they share these knowledge online.

Finally, I realized how much of an essential and basic skill it is to learn scripting. If it wasn't for my versed skill in neovim, I'd be having a little harder time setting all of these up.

Maybe I should write about my neovim config someday huh?

Protip

I also have a dee bash function hooked up in my ~/.zsh/config/aliases.zsh so I can quickly add more shell function if I find a repetitive command.