Skip to content

Instantly share code, notes, and snippets.

@yukal
Last active April 24, 2025 07:25
Show Gist options
  • Save yukal/228bba6c17bcddba18184334bf4a5745 to your computer and use it in GitHub Desktop.
Save yukal/228bba6c17bcddba18184334bf4a5745 to your computer and use it in GitHub Desktop.
utilite to manage planka based on docker
#!/bin/bash
SCRIPT_NAME=$(basename -- "$0")
# Script vars
PROJECT_NAME=planka
DUMP_DIR=data/dump
# Container vars
PRI_DIR=app/private
PUB_DIR=app/public
POSTGRES_DIR=/var/lib/postgresql
RandomHex() {
cat /dev/urandom | tr -cd 'a-f0-9' | head -c $1
}
ColoredText() {
printf "\e[${1}m%s\e[0m" "$2";
}
ContainerStatus() {
read -r -d '' TplDockerContainerInfo << EOM
{{- \$ExposedPorts := .Config.ExposedPorts -}}
{{- \$NETWORK_MODE := .HostConfig.NetworkMode -}}
{{- \$NETWORK_CONF := (index .NetworkSettings.Networks .HostConfig.NetworkMode) -}}
{{- .State.Status }} {{ .Name }}
aliases: {{ \$NETWORK_CONF.Aliases }}
DNSNames: {{ \$NETWORK_CONF.DNSNames }}
Exposed Ports: {{ range \$Key, \$Item := .Config.ExposedPorts }}{{ \$Key }}{{ end }}
{{ range \$PortsConfig := .HostConfig.PortBindings -}}
{{- \$Config := (index \$PortsConfig 0) -}}
network: {{ \$NETWORK_CONF.IPAddress -}}
{{- if \$Config.HostPort }}:{{ \$Config.HostPort }}{{ end -}}
{{- " " -}} {{- \$NETWORK_MODE -}}
{{- end -}}
EOM
docker inspect -f "$TplDockerContainerInfo" $1
}
Confirm() {
printf '\e[1;37m%s\e[0m (y/n) ' "$1"
read -n 1 -rs
if [[ $REPLY =~ ^[Yy]$ ]];
then printf '\e[32m%s\e[0m\n' 'yes'; return 0
else printf '\e[31m%s\e[0m\n' 'no'; return 1
fi
}
read -r -d '' USAGE_HELP << EOM
Usage: ${SCRIPT_NAME} [up|down|purge|status|logs|dump|restore]\n
$ ${SCRIPT_NAME} $(ColoredText "32" up)
$(ColoredText "2;37" "Create and run new containers using docker compose.")
$ ${SCRIPT_NAME} $(ColoredText "32" down)
$(ColoredText "2;37" "Stop and remove the project containers locally with its volumes and networks.")
$ ${SCRIPT_NAME} $(ColoredText "32" purge)
$(ColoredText "2;37" "Stop and remove all the project images, containers, volumes and networks.")
$ ${SCRIPT_NAME} $(ColoredText "32" status)
$(ColoredText "2;37" "Show info about the container status and its configuration")
$(ColoredText "2;37" "eg: port, network, container name.")
$ ${SCRIPT_NAME} $(ColoredText "32" logs)
$(ColoredText "2;37" "Show logs of the containers in attached mode.")
$ ${SCRIPT_NAME} $(ColoredText "32" dump)
$(ColoredText "2;37" "Create Database dump and export data from containers.")
$ ${SCRIPT_NAME} $(ColoredText "32" restore)
$(ColoredText "2;37" "Restore Database from the dump file and import user data to containers.")
\n
EOM
case $1 in
up)
docker compose --file docker-compose.yml --project-name "$PROJECT_NAME" up -d
# --env-file .docker/.env
;;
down)
if Confirm "Backup Database?"; then
$0 dump
echo
fi
docker compose --file docker-compose.yml --project-name "$PROJECT_NAME" down --volumes --rmi local
;;
purge)
if Confirm "Backup Database?"; then
$0 dump
echo
fi
docker compose --file docker-compose.yml --project-name "$PROJECT_NAME" down --volumes --rmi all
;;
status)
if [ -n "$(docker ps -a -q -f name=$PROJECT_NAME)" ];
then
ContainerStatus "${PROJECT_NAME}_app"
echo
ContainerStatus "${PROJECT_NAME}_db"
echo
else
echo "there are no containers with the name \"${PROJECT_NAME}\""
fi
;;
logs)
docker compose --file=docker-compose.yml --project-name="${PROJECT_NAME}" logs --follow
;;
dump)
mkdir -m 755 -p data/$PUB_DIR/{user-avatars,project-background-images}
mkdir -m 755 -p data/$PRI_DIR/attachments
DUMP_FILE="${DUMP_DIR}/${PROJECT_NAME}.dump-$(date +"%Y%m%d-%H%M%S")$(RandomHex 8).gz"
docker exec -t ${PROJECT_NAME}_db \
pg_dumpall -U postgres --clean --if-exist | gzip > "${DUMP_FILE}"
cp "$DUMP_FILE" "${DUMP_DIR}/${PROJECT_NAME}.dump-latest.gz"
# Export user files from container
docker cp ${PROJECT_NAME}_app:/$PUB_DIR/user-avatars/ data/$PUB_DIR
docker cp ${PROJECT_NAME}_app:/$PUB_DIR/project-background-images/ data/$PUB_DIR
docker cp ${PROJECT_NAME}_app:/$PRI_DIR/attachments/ data/$PRI_DIR
;;
restore)
gunzip -c "${DUMP_DIR}/${PROJECT_NAME}.dump-latest.gz" | \
docker exec -i "${PROJECT_NAME}_db" psql -U postgres
echo
# Import user files to container
docker cp data/$PUB_DIR/user-avatars/ ${PROJECT_NAME}_app:/$PUB_DIR
docker cp data/$PUB_DIR/project-background-images/ ${PROJECT_NAME}_app:/$PUB_DIR
docker cp data/$PRI_DIR/attachments/ ${PROJECT_NAME}_app:/$PRI_DIR
;;
*)
printf "$USAGE_HELP";
;;
esac
# ADDITIONAL TRICKS
#
# APP_CONTAINER_ID = $(docker ps -a -q -f name=${PROJECT_NAME}_app)
# DB_CONTAINER_ID = $(docker ps -a -q -f name=${PROJECT_NAME}_db)
#
# CONTAINER_STATE = $(docker inspect -f {{.State.Running}} $APP_CONTAINER_ID)
#
# ContainersList = $(docker ps -a -q -f name="Your_Container_Or_Project_Name")
# ContainerIP = $(docker inspect -f '{{(index .NetworkSettings.Networks .HostConfig.NetworkMode).IPAddress}}' $1)
# ContainerPort = $(docker inspect -f '{{range $Key, $Item := .Config.ExposedPorts}}{{$Key}}{{end}}' $1 | tr -d -c 0-9)
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment