├── dup.gif ├── aup ├── dup └── README.md /dup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/seanap/Docker-Update-Script/HEAD/dup.gif -------------------------------------------------------------------------------- /aup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | source $HOME/.bashrc 3 | CYAN='\033[0;36m' 4 | GREEN='\033[0;32m' 5 | NC='\033[0m' # No Color 6 | 7 | echo -e "${CYAN}apt-get update${NC}" 8 | sudo apt-get update 9 | 10 | echo -e "${CYAN}apt-get dist-upgrade -y" 11 | sudo apt-get dist-upgrade -y 12 | 13 | echo -e "${CYAN}apt-get update${NC}" 14 | sudo apt-get update 15 | 16 | echo -e "${CYAN}apt-get upgrade${NC}" 17 | sudo apt-get upgrade -y 18 | 19 | echo -e "${CYAN}apt autoclean${NC}" 20 | sudo apt autoclean -y 21 | 22 | echo -e "${CYAN}apt autoremove${NC}" 23 | sudo apt autoremove -y 24 | 25 | echo -e "${CYAN}apt clean${NC}" 26 | sudo apt clean -y 27 | 28 | echo -e "${GREEN}FINISHED${NC}" 29 | -------------------------------------------------------------------------------- /dup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | . ~/.bashrc 3 | 4 | # Help File 5 | Help() 6 | { 7 | # Display Help 8 | echo 9 | echo " docker compose V2 [ Pull | Down | Up | rmi ]" 10 | echo 11 | echo -e " Syntax: ${GREEN}dup [-h|o|e|i] [SERVICE...]${NC}" 12 | echo " options:" 13 | echo " -h Print this Help." 14 | echo 15 | echo " -i Prints Current image list" 16 | echo 17 | echo " -o Only runs on a specific container" 18 | echo -e " Example: ${GREEN}dup -o plex${NC} #Only update the Plex image" 19 | echo 20 | echo " -e Excludes a specific container" 21 | echo -e " Example: ${GREEN}dup -e plex${NC} #Keeps plex running while shutting down and updating all other containers." 22 | echo 23 | echo -e " Updates ALL containers in ${CYAN}docker-compose.yaml${NC}" 24 | echo -e " Example: ${GREEN}dup${NC}" 25 | echo 26 | } 27 | 28 | # Set Variables 29 | ERROR_FILE="/tmp/docker-update.error" 30 | only='' 31 | exclude='' 32 | service='' 33 | CYAN='\033[0;36m' 34 | GREEN='\033[0;32m' 35 | NC='\033[0m' # No Color 36 | 37 | # Get the options 38 | while getopts "hio:e:" option; do 39 | case $option in 40 | h) # display Help 41 | Help 42 | exit;; 43 | o) service=${OPTARG} 44 | only="True";; 45 | e) service=${OPTARG} 46 | exclude="True";; 47 | i) echo -e "$(docker ps -q | xargs -n 1 docker inspect --format '{{ .Name }}' | sed 's/\///')" 48 | exit;; 49 | \?) # incorrect option 50 | echo "Error: Invalid option" 51 | exit;; 52 | esac 53 | done 54 | 55 | if [[ $only ]] 56 | then 57 | echo -e "${CYAN}Pulling $service container...${NC}" 58 | docker compose pull $service 59 | echo -e "${CYAN}Stopping $service container...${NC}" 60 | docker compose rm -fsv $service 61 | echo -e "${CYAN}Starting $service container...${NC}" 62 | docker compose up -d --force-recreate $service 63 | elif [[ $exclude ]] 64 | then 65 | # get a list of docker images that are currently installed 66 | IMAGES_OUTPUT=$(docker ps -q | xargs -n 1 docker inspect --format '{{ .Name }}' | grep -v $service | grep -v "" | sed 's/\///') 67 | for IMAGE in $IMAGES_OUTPUT; do 68 | echo "*****" 69 | echo -e "Updating $IMAGE" 70 | docker pull $IMAGE 2> $ERROR_FILE 71 | docker compose rm -sfv $IMAGE 72 | docker compose up -d --force-recreate $IMAGE 73 | if [ $? != 0 ]; then 74 | ERROR=$(cat $ERROR_FILE | grep "not found") 75 | if [ "$ERROR" != "" ]; then 76 | echo -e "WARNING: Docker image $IMAGE not found in repository, skipping" 77 | else 78 | echo -e "ERROR: docker pull failed on image - $IMAGE" 79 | exit 2 80 | fi 81 | fi 82 | echo "*****" 83 | echo 84 | done 85 | else 86 | docker compose pull 87 | docker compose down 88 | docker compose up -d --force-recreate 89 | fi 90 | echo -e "${CYAN}Deleting the old unused container images...${NC}" 91 | docker system prune -af 92 | echo -e "${GREEN}Successfully cleaned up${NC}" 93 | echo -e "${GREEN}FINISHED${NC}" 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Docker-Update-Script 2 | Create a script to run the 4 docker commands needed to force pull/upgrade docker apps using docker-compose. Add this to path to make an executable from anywhere command, and automate with CRON. 3 | 4 | This script runs the following commands in this order: pull; down; up; rmi. One of the main benifits of this script is being able to chose to update all containers, or to only update a single container in your docker-compose, or to exclude a specific container from stopping but updating the rest. 5 | 6 | ![](dup.gif) 7 | 8 | ### Prerequisites 9 | * [docker-ce](https://docs.docker.com/engine/install/ubuntu/) installed 10 | * [docker-compose](https://docs.docker.com/compose/install/) installed 11 | * `docker-compose.yml` file in $HOME 12 | * Sample - [pastebin.com/sK9dMeet](https://pastebin.com/sK9dMeet) 13 | 14 | # Install 15 | 16 | 17 | ### Make a userscript directory and add to PATH 18 | 19 | * `mkdir $HOME/bin` 20 | * `nano $HOME/.bashrc` 21 | * `Alt+ /` (Alt+ Forward Slash) Jump to last line. 22 | * Copy and paste the below to the end of the file: 23 | ``` 24 | if [ -d "$HOME/bin" ] ; then 25 | PATH="$HOME/bin:$PATH" 26 | fi 27 | ``` 28 | * Initialize changes: 29 | `. ~/.bashrc` 30 | 31 | --- 32 | 33 | ### Create the `dup` (docker upgrade) script: 34 | 35 | * `nano $HOME/bin/dup` 36 | 37 | Copy the script below: 38 | 39 | ```bash 40 | #!/bin/bash 41 | . ~/.bashrc 42 | 43 | # Help File 44 | Help() 45 | { 46 | # Display Help 47 | echo 48 | echo " docker compose V2 [ Pull | Down | Up | rmi ]" 49 | echo 50 | echo -e " Syntax: ${GREEN}dup [-h|o|e|i] [SERVICE...]${NC}" 51 | echo " options:" 52 | echo " -h Print this Help." 53 | echo 54 | echo " -i Prints Current image list" 55 | echo 56 | echo " -o Only runs on a specific container" 57 | echo -e " Example: ${GREEN}dup -o plex${NC} #Only update the Plex image" 58 | echo 59 | echo " -e Excludes a specific container" 60 | echo -e " Example: ${GREEN}dup -e plex${NC} #Keeps plex running while shutting down and updating all other containers." 61 | echo 62 | echo -e " Updates ALL containers in ${CYAN}docker-compose.yaml${NC}" 63 | echo -e " Example: ${GREEN}dup${NC}" 64 | echo 65 | } 66 | 67 | # Set Variables 68 | ERROR_FILE="/tmp/docker-update.error" 69 | only='' 70 | exclude='' 71 | service='' 72 | CYAN='\033[0;36m' 73 | GREEN='\033[0;32m' 74 | NC='\033[0m' # No Color 75 | 76 | # Get the options 77 | while getopts "hio:e:" option; do 78 | case $option in 79 | h) # display Help 80 | Help 81 | exit;; 82 | o) service=${OPTARG} 83 | only="True";; 84 | e) service=${OPTARG} 85 | exclude="True";; 86 | i) echo -e "$(docker ps -q | xargs -n 1 docker inspect --format '{{ .Name }}' | sed 's/\///')" 87 | exit;; 88 | \?) # incorrect option 89 | echo "Error: Invalid option" 90 | exit;; 91 | esac 92 | done 93 | 94 | if [[ $only ]] 95 | then 96 | echo -e "${CYAN}Pulling $service container...${NC}" 97 | docker compose pull $service 98 | echo -e "${CYAN}Stopping $service container...${NC}" 99 | docker compose rm -fsv $service 100 | echo -e "${CYAN}Starting $service container...${NC}" 101 | docker compose up -d --force-recreate $service 102 | elif [[ $exclude ]] 103 | then 104 | # get a list of docker images that are currently installed 105 | IMAGES_OUTPUT=$(docker ps -q | xargs -n 1 docker inspect --format '{{ .Name }}' | grep -v $service | grep -v "" | sed 's/\///') 106 | for IMAGE in $IMAGES_OUTPUT; do 107 | echo "*****" 108 | echo -e "Updating $IMAGE" 109 | docker pull $IMAGE 2> $ERROR_FILE 110 | docker compose rm -sfv $IMAGE 111 | docker compose up -d --force-recreate $IMAGE 112 | if [ $? != 0 ]; then 113 | ERROR=$(cat $ERROR_FILE | grep "not found") 114 | if [ "$ERROR" != "" ]; then 115 | echo -e "WARNING: Docker image $IMAGE not found in repository, skipping" 116 | else 117 | echo -e "ERROR: docker pull failed on image - $IMAGE" 118 | exit 2 119 | fi 120 | fi 121 | echo "*****" 122 | echo 123 | done 124 | else 125 | docker compose pull 126 | docker compose down 127 | docker compose up -d --force-recreate 128 | fi 129 | echo -e "${CYAN}Deleting the old unused container images...${NC}" 130 | docker system prune -af 131 | echo -e "${GREEN}Successfully cleaned up${NC}" 132 | echo -e "${GREEN}FINISHED${NC}" 133 | ``` 134 | 135 | Make the script executable: 136 | 137 | * `chmod +x $HOME/bin/dup` 138 | 139 | --- 140 | 141 | ### Create the `aup` (apt-get update/upgrade) script: 142 | 143 | * `nano $HOME/bin/aup` 144 | 145 | Copy the script below: 146 | 147 | ```bash 148 | #!/bin/bash 149 | source $HOME/.bashrc 150 | CYAN='\033[0;36m' 151 | GREEN='\033[0;32m' 152 | NC='\033[0m' # No Color 153 | 154 | echo -e "${CYAN}apt-get update${NC}" 155 | sudo apt-get update 156 | 157 | echo -e "${CYAN}apt-get dist-upgrade -y" 158 | sudo apt-get dist-upgrade -y 159 | 160 | echo -e "${CYAN}apt-get update${NC}" 161 | sudo apt-get update 162 | 163 | echo -e "${CYAN}apt-get upgrade${NC}" 164 | sudo apt-get upgrade -y 165 | 166 | echo -e "${CYAN}apt autoclean${NC}" 167 | sudo apt autoclean -y 168 | 169 | echo -e "${CYAN}apt autoremove${NC}" 170 | sudo apt autoremove -y 171 | 172 | echo -e "${CYAN}apt clean${NC}" 173 | sudo apt clean -y 174 | 175 | echo -e "${GREEN}FINISHED${NC}" 176 | ``` 177 | 178 | Make the script executable: 179 | 180 | * `chmod +x $HOME/bin/aup` 181 | 182 | --- 183 | 184 | # Use 185 | 186 | ### Manual 187 | 188 | * To update/upgrade Ubuntu, type `aup` into the terminal 189 | * To update/upgrade ALL docker containers, type `dup` into the terminal 190 | * To update/upgrade a specific container, type `dup -o [SERVICE...]` into the terminal 191 | * Ex. `dup -o plex` will only take plex down and update it. 192 | * To keep a specific container running and update/upgrade all other containers, type `dup -e [SERVICE...]` into the terminal 193 | * Ex. `dup -e plex` will leave plex up and running and take down all other images to update them. 194 | 195 | ### Automated 196 | 197 | * `crontab -e` 198 | * `Alt+ /` (Alt+ Forward Slash) Jump to last line. 199 | * Add the two lines below, in my example it runs `dup` once a week, 6am on sat: 200 | ``` 201 | shell=/bin/bash 202 | 0 6 * * 6 . $HOME/.bashrc; dup 203 | ``` 204 | * Best not to automate aup, if you want automated security upgrades use a package called `unattended-upgrades` 205 | 1. Update the server, run: 206 | `aup` 207 | 2. Install unattended upgrades on Ubuntu: 208 | `sudo apt install unattended-upgrades apt-listchanges bsd-mailx -y` 209 | 3. Turn on unattended security updates, run: 210 | `sudo dpkg-reconfigure -plow unattended-upgrades` 211 | 4. Configure automatic updates, enter: 212 | `sudo nano /etc/apt/apt.conf.d/50unattended-upgrades` 213 | Uncomment or add the following: 214 | `Unattended-Upgrade::Automatic-Reboot "true";` 215 | `Unattended-Upgrade::Automatic-Reboot-WithUsers "true";` 216 | `Unattended-Upgrade::Automatic-Reboot-Time "04:00";` 217 | 5. Verify that it is working by running the following command: 218 | `sudo unattended-upgrades --dry-run --debug` 219 | 220 | # Notes: 221 | 222 | * This script is compatible with pihole, I made sure to pull the new image first before stopping the container and re-creating. Pihole is a little tricky since once you stop the pihole docker you will lose DNS and be unable to pull the :latest image, which is why we pull the image first. 223 | * If there are any docker containers that you do NOT want updated to the latest version, look up the available [TAG's](https://hub.docker.com/r/linuxserver/plex/tags?page=1&ordering=last_updated), then edit `docker-compose.yml` and include the specific TAG name after a `:` when defining the image. 224 | * Example below locks plex to version 1.24.3: 225 | 226 | ``` 227 | nano docker-compose.yml 228 | ... 229 | plex: 230 | image: linuxserver/plex:1.24.3.5033-757abe6b4-ls76 231 | ... 232 | ``` 233 | --------------------------------------------------------------------------------