├── .color_codes.conf
├── .gitattributes
├── .gitignore
├── .vars_docker.example
├── README.md
├── docker_commands_list.sh
├── docker_compose_bounce.sh
├── docker_compose_folders.sh
├── docker_compose_function.sh
├── docker_compose_logs.sh
├── docker_compose_networks.sh
├── docker_compose_start.sh
├── docker_compose_stop.sh
├── docker_compose_test.sh
├── docker_folders_create.sh
├── docker_functions.sh
├── docker_list_configs.sh
├── docker_list_container.sh
├── docker_list_stack.sh
├── docker_scripts_setup.sh
├── docker_service_error.sh
├── docker_service_logs.sh
├── docker_stack_bounce.sh
├── docker_stack_folders.sh
├── docker_stack_start.sh
├── docker_stack_stop.sh
├── docker_swarm_init.sh
├── docker_swarm_leave.sh
├── docker_system_backup.sh
├── docker_system_clean.sh
├── docker_system_image.sh
├── docker_system_network.sh
├── docker_system_prune.sh
├── docker_system_stats.sh
└── docker_system_volume.sh
/.color_codes.conf:
--------------------------------------------------------------------------------
1 | ## Color picker, syntax: echo $BLD$CUR$RED$BBLU'Hello World!'$DEF
2 | #
3 | ## to display a grid of colors in your specific terminal, run this function:
4 | # for x in 0 1 4 5 7 8; do for i in {30..37}; do for a in {40..47}; do echo -ne "\e[$x;$i;$a""m\\\e[$x;$i;$a""m\e[0;37;40m "; done; echo; done; done; echo "";
5 | #
6 | ## or this function:
7 | # for colour in {1..225}; do echo -en "\033[38;5;${colour}m38;5;${colour} \n"; done | column -x;
8 | #
9 | red=$'\033[38;2;255;000;000m'
10 | orn=$'\033[38;2;255;075;075m'
11 | ylw=$'\033[38;2;255;255;000m'
12 | grn=$'\033[38;2;000;170;000m'
13 | cyn=$'\033[38;2;085;255;255m'
14 | blu=$'\033[38;2;000;120;255m'
15 | prp=$'\033[38;2;085;085;255m'
16 | mgn=$'\033[38;2;255;085;255m'
17 | wht=$'\033[38;2;255;255;255m'
18 | blk=$'\033[38;2;025;025;025m'
19 | def=$'\033[m'
20 | # ## Text color
21 | # BLK=$'\e[30m' # Black
22 | # blk=$'\e[90m' #
23 | # RED=$'\e[31m' # Red
24 | # red=$'\e[91m' #
25 | # GRN=$'\e[32m' # Green
26 | # grn=$'\e[92m' #
27 | # YLW=$'\e[33m' # Yellow
28 | # ylw=$'\e[93m' #
29 | # BLU=$'\e[34m' # Blue
30 | # blu=$'\e[94m' #
31 | # MGN=$'\e[35m' # Magenta
32 | # mgn=$'\e[95m' #
33 | # CYN=$'\e[36m' # Cyan
34 | # cyn=$'\e[96m' #
35 | # WHT=$'\e[37m' # White
36 | # wht=$'\e[97m' #
37 | #
38 | ## Background color
39 | BBLK=$'\e[40m' # Black background
40 | bblk=$'\e[100m' #
41 | BRED=$'\e[41m' # Red background
42 | bred=$'\e[101m' #
43 | BGRN=$'\e[42m' # Green background
44 | bgrn=$'\e[102m' #
45 | BYLW=$'\e[43m' # Yellow background
46 | bylw=$'\e[103m' #
47 | BBLU=$'\e[44m' # Blue background
48 | bblu=$'\e[104m' #
49 | BMGN=$'\e[45m' # Magenta background
50 | bmgn=$'\e[105m' #
51 | BCYN=$'\e[46m' # Cyan background
52 | bcyn=$'\e[106m' #
53 | BWHT=$'\e[47m' # White background
54 | bwht=$'\e[107m' #
55 | #
56 | # Text Effect
57 | DEF=$'\e[0m' # Default color (reset)
58 | def=$'\e[0m' #
59 | BLD=$'\e[1m' # Bold\brighter
60 | bld=$'\e[1m' #
61 | DIM=$'\e[2m' # Dim\darker
62 | dim=$'\e[2m' #
63 | CUR=$'\e[3m' # Italic font
64 | cur=$'\e[3m' #
65 | UND=$'\e[4m' # Underline
66 | und=$'\e[4m' #
67 | INV=$'\e[7m' # Inverted
68 | inv=$'\e[7m' #
69 | STK=$'\e[9m' # Strikethrough
70 | stk=$'\e[9m' #
71 | COF=$'\e[?25l' # Cursor OFF
72 | cof=$'\e[?25l' #
73 | CON=$'\e[?25h' # Cursor ON
74 | con=$'\e[?25h' #
75 | #
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto eol=lf
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.env
2 | *profile*
3 | *shellcheck*
4 | *template*
--------------------------------------------------------------------------------
/.vars_docker.example:
--------------------------------------------------------------------------------
1 | #### Variables list for Docker helper-scripts by Drauku.
2 | #
3 | #### These variables must be filled in with your network, architecture, etc.
4 | # Search for "REDACTED" and insert your own information for each variable found.
5 | #
6 | ## IMPORTANT! -- DO NOT LEAVE EMPTY LINES IN THIS CONFIG FILE, OR THE '.env' REDIRECT WILL BREAK
7 | ## NOTE: values inside '' (single quotes) are not expanded, use "" (double quotes) to include variable expansion
8 | #
9 | ## UserID and GroupID for the 'docker' username on the NAS
10 | # TIP: UID/GID are obtained from the terminal by executing the command: 'id docker'
11 | var_uid=1000
12 | var_gid=1000
13 | ## Timezone Region and City, according to 'TZ database name' column here:
14 | # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
15 | var_tz="America/Chicago"
16 | #
17 | var_email="redacted"
18 | #
19 | ## Internal network and docker system variables
20 | var_host_name="redacted" # NOTE: This variable cannot be used to create a 'service' name in traefik-dynamic.yml
21 | var_host_ip="192.168.1.redacted" # change to your NAS local area network IP
22 | var_public_ip="" # OPTIONAL. Be careful using this unless you have a static ip, if it changes it could break routing.
23 | #
24 | ## SUPER secret squirrel "admin:password" htpasswd basic auth (just kidding, make sure you change this)
25 | # TIP: make your own with the command: 'htpasswd -n username_changeme password_changeme'
26 | # NOTE: after using the `htpasswd` command, add a 2nd `$` for each generated `$` as shown in the below example:
27 | var_basic_auth="admin:$$apr1$$a0m8c2x6$$NoASfJAKF6lVquLYx0Urh/"
28 | #
29 | ## Media storage directory
30 | data_dir=/mnt/data
31 | media_folder="/share/Multimedia" # the `/share` prefix is QTS specific for all Shared Folders
32 | media_audio_books="${media_folder}/audio/books"
33 | media_audio_music="${media_folder}/audio/music"
34 | media_print_books="${media_folder}/print/books"
35 | media_video_series="${media_folder}/video/series"
36 | media_video_movies="${media_folder}/video/movies"
37 | #
38 | ## These entries must be domains at which you have dns nameserver permissions
39 | var_domain1="redacted"
40 | var_domain2="redacted"
41 | var_domain3="redacted"
42 | #
43 | ## External network resolution and access variables (cloudflare, namecheap, afraid.org, etc.)
44 | # If your 'certresolver' and 'dns' services are not through cloudflare, check this link for setup requirements:
45 | # https://docs.traefik.io/v2.0/https/acme/#providers
46 | var_certresolver="cloudflare"
47 | #
48 | ## DNS provider information
49 | var_dns_provider="cloudflare"
50 | var_dns1="9.9.9.9:53" # quad9 DNS
51 | var_dns2="1.1.1.1:53" # cloudflare DNS1
52 | var_dns3="1.0.0.1:53" # cloudflare DNS2
53 | var_dns4="208.67.222.222:53" # OpenDNS
54 | #
55 | ####################################################################################################
56 | #################### VARIABLES AFTER THIS LINE PROBABLY SHOULD NOT BE CHANGED ####################
57 | ####################################################################################################
58 | #
59 | ## This is the internal docker socket network, powered by "tecnativa/docker-socket-network"
60 | var_net_socket="docker_socket"
61 | var_subnet_socket="172.20.0.0/"
62 | var_gateway_socket="172.20.0.254"
63 | ## This is the edge network for connections outside of docker
64 | var_net_exedge="external_edge"
65 | var_subnet_exedge="172.21.0.0/16"
66 | var_gateway_exedge="172.21.0.254"
67 | ## This is the internal only bridge network
68 | var_net_rproxy="internal_only"
69 | var_subnet_rproxy="172.22.0.0/16"
70 | var_gateway_rproxy="172.22.0.254"
71 | ## This is the external bridge reverse proxy network
72 | var_net_rproxy="reverse_proxy"
73 | var_subnet_rproxy="172.23.0.0/16"
74 | var_gateway_rproxy="172.23.0.254"
75 | ## This is the docker-swarm only 'overlay' network for external pointing swarm traffic
76 | var_net_overlay="overlay"
77 | var_subnet_overlay="10.20.0.0/16"
78 | var_gateway_overlay="10.20.0.254"
79 | ## This is the docker-swarm only 'ingress' network for swarm management traffic
80 | var_net_ingress="ingress"
81 | var_subnet_ingress="10.21.0.0/16"
82 | var_gateway_ingress="10.21.0.254"
83 | #
84 | ## Folder heirarchy for Drauku's folder structure, modified from gkoerk's famously awesome folder structure for stacks.
85 | docker_dir=/opt/docker
86 | docker_folder="$HOME/docker"
87 | docker_appdata="${docker_folder}/appdata"
88 | docker_compose="${docker_folder}/compose"
89 | docker_secrets="${docker_folder}/secrets"
90 | docker_dkswarm="${docker_folder}/dkswarm"
91 | # these last two folders can be mapped to a different location, update accordingly
92 | docker_runtime="${docker_folder}/runtime" # map this to fast storage on your NAS, such as an SSD cache volume
93 | docker_scripts="${docker_folder}/scripts" # map this to wherever you store the qnaphomelab-docker-scripts repository
94 | #
95 | ## Ensure the 'var_script_vars' variable contents exactly references the copy of '.vars_docker.example' file. Default: '.vars_docker.env'
96 | var_script_vars="${docker_scripts}/.vars_docker.env"
97 | #
98 | ## This is the common name for all your docker compose config files. Default: 'compose.yml'
99 | ## WARNING: Do not change this unless you also change all your docker compose config file names.
100 | var_configs_file="compose.yml"
101 | #
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # QNAP HomeLAB Using Docker Containers
4 |
5 | #### A Guide for Docker Container management via SSH Terminal
6 |
7 |
WARNING: Unfinished Project
8 |

9 |
10 |
11 | Getting this HomeLAB enviornment working in your QNAP will probably require tweaking and troubleshooting.
12 |
13 | Consider joining and contributing to the [QNAP Unofficial Discord](https://discord.gg/NaxEB4sz7G), a community built around advice on everything QNAP. We have helpful members, FAQs, community Docker images, and cookies (well, maybe not cookies).
14 |
15 | I am quite active in the Discord, and will help when and if I can, but I can not be held responsible for issues created while following this guide or performing any suggestions I make.
16 |
17 | **WARNING:** This guide is incomplete, and as such **will *probably*** contain errors.
18 |
19 | Please read the [disclaimer](#disclaimer) at the end of this document.
20 |
21 | ##### PRE-REQUISITES
22 |
23 | A desire to learn Docker and some basic Terminal commands.
24 |
25 | A desktop with a Terminal application (e.g. Termius), and a text editor (e.g. VSCodium)
26 |
27 | A QNAP device that supports the Container Station application and therefore Docker.
28 |
29 | A Debian based Linux distribution with Docker installed via https://get.docker.com
30 |
31 | Thanks for checking out this guide. If it ends up being useful for your setup, please consider donating!
32 |
33 |

34 |
35 |
36 |
37 | ---
38 | ---
39 |
40 | ### Contents
41 | [QNAP HomeLAB Using Docker Containers](#qnap-homelab-using-docker-containers)
42 |
43 | - [I. QNAP GUI Steps](#i-qnap-gui-steps)
44 | - [1. Network Port Configuration](#1-network-port-configuration)
45 | - [2. Docker user account](#2-docker-user-account)
46 | - [3. Entware-std installation](#3-entware-std-installation)
47 | - [4. Container Station Setup](#4-container-station-setup)
48 | - [5. Docker Shared Folder](#5-docker-shared-folder)
49 | - [II. Terminal Steps](#ii-terminal-steps)
50 | - [1. SSH Terminal Connection](#1-ssh-terminal-connection)
51 | - [2. Docker folder creation](#2-docker-folder-creation)
52 | - [3. Entware-std profile setup](#3-entware-std-profile-setup)
53 | - [4. Docker Scripts Reference](#4-docker-scripts-reference)
54 | - [III. Docker general config steps](#iii-docker-general-config-steps)
55 | - [1. Environment Variables](#1-environment-variables)
56 | - [2. Docker Container Creation](#2-docker-container-creation)
57 | - [Contributors](#contributors)
58 | - [DISCLAIMER](#disclaimer)
59 |
60 | ---
61 | ---
62 |
63 |
64 | ## QNAP GUI Steps
65 |
66 |
67 | All actions in this section will be performed in the QNAP QTS Web UI.
68 |
69 | If following this guide on a Debian based OS, QNAP specific steps are unnecessary.
70 |
71 | ### 1. Network Port Configuration
72 |
73 | ##### New Ports Settings Overview
74 |
75 | **QTS System UI**
76 | `HTTP: 8480 | HTTPS: 8443`
77 |
78 | **Web Server**
79 | `HTTP: 9480 | HTTPS: 9443`
80 |
81 | **SSH Terminal**
82 | `example: 54545`
83 |
84 | 1. For ease of configuration, ports 80, 443, and 8080 **must be _unused_ by your NAS.**
85 | - ***NOTE:*** This step may be unnecessary if you can get 'chained' port-forwards to work when configuring Traefik to recognize your domain and register a certificate. YMMV.
86 | - **EXPLANATION:** QTS assigns ports 8080 and 443 as the default HTTP and HTTPS ports for the QNAP Web UI, and assigns 80 as the default HTTP port for the native "Web Server" application. A reverse proxy requires 80 and 443 in order to obtain certificates and properly route traffic. Unless you decide not to use a reverse proxy, these must be changed to successfully complete this guide.
87 | - **RECOMMENDATION:** Even if you do not use a reverse proxy, I ***HIGHLY*** recommend that you change the default ports for the Web UI, Web Server, and SSH connections to increase the security of your NAS. Also disable UPnP.
88 |
89 | 1. Modify the default ports as follows to ensure there will be no port conflicts with docker stacks:
90 | - **Change default *System* ports:** In QNAP Web GUI
91 | - `Control Panel >> System >> General Settings`
92 | - Change the default HTTP port to `8480`, and the default HTTPS port to `8443`.
93 | - **NOTE:** This *will* change the LAN address from which you access your QTS web-gui, requiring you to add the port at the end of your NAS LAN IP (e.g. https://192.168.1.100:8443)
94 | - **Change default *Web Application* ports:** In QNAP Web GUI
95 | - `Control Panel >> Applications >> Web Server`
96 | - Change the default HTTP port to `9480`, and the default HTTPS port to `9443`.
97 | - **TIP:** Unless currently in use, consider disabling the MySQL application in the QNAP GUI Settings.
98 | - **NOTE:** Prior to version 5.x it is required to keep the **Web Server** application enabled with the modified ports, otherwise the QTS Web Server would re-acquire the default port when disabled.
99 | - **Change default *SSH* port:** In QNAP Web UI
100 | - `Control Panel >> Network & File Services >> Telent / SSH`
101 | - Change the default to a random number somewhere between `49152 - 65535`.
102 | - See this [list of port numbers](https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers#Dynamic,_private_or_ephemeral_ports) to make sure the one you choose is not already assigned.
103 |
104 | 1. In order to use a reverse proxy, ports 80 and 443 must be forwarded from your router to your NAS.
105 | - **WARNING:** Only configure this port forward if you are using a reverse proxy such as [Traefik](https://traefik.io/traefik/), [Caddy](https://caddyserver.com/docs/quick-starts/reverse-proxy), or [NXPM](https://nginxproxymanager.com/setup/).
106 | - *Disable UPnP on you router and manually forward ports 80 and 443 to your NAS.*
107 | - **NOTE:** There are too many possible routers to cover how to forward ports on each, but there are some good guides here if you don't know how to do it for your router:
108 |
109 | - https://www.howtogeek.com/66214/how-to-forward-ports-on-your-router
110 |
111 | - https://portforward.com/router.htm
112 | - **WARNING:** Do not purchase the port-forwarding program offered from this website, it will not work for this and is a waste of money.
113 |
114 | ### 2. Docker User Account Creation
115 |
116 | - **TIP:** During QTS initialization, if the first user created is the `dockeruser` user account, all the container configs shared here will be pre-configured to use the correct `UID: 1000` and `GID: 1000`.
117 |
118 | - **NOTE:** If you do not create the `docker` user as the first user account, you will need to update each container config to reflect your particular `UID` and `GID`, obtained by the terminal command: `id dockeruser`.
119 |
120 | 1. Ensure the `docker` user account is created.
121 | - `Control Panel >> Privilege >> Users`
122 | - Click the `Create` dropdown button and select `Create User`.
123 | **TIP:** Create the user with all lowercase letters so Linux case sensitivity is never an issue.
124 |
125 | 1. Create a new group called `docker`.
126 | **NOTE:** This step can be performed after creation of the `/docker` Shared Folder below in the `5. Docker Folder Creation` section.
127 | - `Control Panel >> Privilege >> User Groups`
128 | - Click the `Create` button and type in the `docker` name.
129 | **TIP:** Create the user with all lowercase letters so Linux case sensitivity is never an issue.
130 | - Assign the `docker` user account to this group by clicking the `Edit` button on the right.
131 | - If the `/docker` Shared Folder has been created, assign `read/write` folder permissions for this group to the folder.
132 |
133 | ### 3. Entware-std Installation
134 |
135 | 1. Install the `entware-std` package from the third-party QNAP Club repository appstore. This is necessary in order to set up the shortcuts/aliases used when controlling docker via command line by editing a permanent profile.
136 |
137 | - The preferred way to do this is to add the My QNAP (formerly QNAP Club) Repository to the App Center. Follow the [walkthrough instructions here](https://www.myqnap.org/install-the-repo/).
138 |
139 | Note, I use the English translation of the My QNAP website, but you may change languages (and urls) in the upper right language dropdown.
140 |
141 | - If you don't need the walkthrough, add the repository.
142 | For English, go to App Center, Settings, App Repository, paste in
143 | `https://www.myqnap.org/repo.xml`.
144 |
145 | - If you **cannot** add the QNAP Club store to the App Center, you may manually download the qpkg file from that link and use it to manually install via the App Center, "Install Manually" button. This is **not preferred** as QNAP cannot check for and notify you of updates to the package.
146 |
147 | - Search for `entware-std` and install the package.
148 |
149 | **TIP:** If you have trouble locating the correct package, the description begins with
150 | `entware-3x and entware-ng merged to become entware.`
151 | The working link (as of publication) is here: https://www.myqnap.org/product/entware-std/
152 |
153 | - **IMPORTANT:** ***DO NOT*** install the `entware-ng` or `entware-3x-std` packages. These have merged and been superceded by `entware-std`.
154 |
155 | ### 4. Container Station Setup
156 |
157 | 1. Backup what you have running now (if you don't have anything running yet, skip to Step 3. If you have also never used Container Station, skip to Step 5).
158 |
159 | 1. Shutdown and remove all docker containers and networks. This can be accomplished using Container Station, but connecting via SSH terminal allows you to complete this quickly with only three commands.
160 |
161 | - Stop all running containers:
162 | ```bash
163 | docker stop $(docker container ls --all --quiet)
164 | ```
165 |
166 | - Remove all stopped containers, unused networks, images, and build cache:
167 | ```bash
168 | docker system prune
169 | ```
170 |
171 | - Ensure you are not a part of a Docker Swarm:
172 | ```bash
173 | docker swarm leave --force
174 | ```
175 |
176 | 1. Remove Container Station:
177 | - In App Center, click the dropdown for Container Station and choose `Remove`.
178 | - In `Control Panel >> Shared Folders`, check the box next to the `container` shared folder and click "Remove"
179 | 
180 | - In the pop-up box, check "Also delete the data" and click "Yes"
181 | 
182 |
183 | 1. Reboot the NAS
184 | 
185 |
186 | 1. Once the reboot is complete, install Container Station from the QNAP Appstore.
187 | - Launch CS after installed.
188 | - Create the `container/` folder when prompted during the first launch of CS.
189 |
190 | ### 5. Docker Shared Folder
191 |
192 | 1. Create the `docker/` folder share **using the QTS Web UI**
193 |
194 | - `ControlPanel >> Privilege >> Shared Folders`
195 |
196 | - Click the 'Create' dropdown button and select `Shared Folder`.
197 |
198 | - Name the folder `docker` using **all lowercase letters**.
199 |
200 | ***WARNING:*** An all lowercase `docker` folder is required so the helper scripts work correctly.
201 |
202 | - Give `dockeruser` Read/Write permissions for the newly created `/docker` shared folder:
203 |
204 | - **INFO:** This is the main "docker" folder inside which we will place swarm and compose config files in their own subfolders, as well as helper scripts and secrets. The remaining folders listed below should be created using the Terminal while logged in using the default QTS `admin` account.
205 |
206 | - **NOTE:** The `appdata`, `compose`, `secrets`, and `swarm` sub-folders can be created using QTS File Station, but that is entirely unnecessary considering you can create them all with a single terminal command shown below. They should *not* be created as Shared Folders in the same way as the parent `docker/` folder.
207 |
208 | ---
209 |
210 |
211 | ## Terminal Steps
212 |
213 |
214 | All actions in this section will be accomplished via SSH terminal connection to your QNAP NAS.
215 |
216 | ### 1. SSH Terminal Connection
217 |
218 | 1. Open/Connect an SSH terminal session to your QNAP NAS.
219 | * You can use [PuTTY](https://putty.org/), the `Windows Subsystem for Linux`, [Cmder](https://cmder.net/) or any terminal utility with SSH.
220 | - **NOTE:** Alternatively you can use [BitVise](https://www.bitvise.com/ssh-client-download) because this also has an SFTP remote file browser interface.
221 | - **TIP:** I switched to using [WinSCP](https://winscp.net/eng/download.php) and [Cmder](https://cmder.net/) because they have dark themes. [Windows Terminal Preview](https://docs.microsoft.com/en-us/windows/terminal/get-started) is turning out to be a good Terminal as well.
222 | - **TIP:** Connecting to the NAS using SFTP allows me to edit the docker config files using `Notepad++` or `VSCodium` (open source Visual Studio Code clone).
223 | - **TIP:** I also map the `/share/docker/` folder as a Network drive on my Windows desktop, which makes viewing and editing Docker config files very easy.
224 |
225 | 2. Install `nano` so you can edit text files in the terminal:
226 | ***NOTE:*** You must have installed `entware-std` as detailed in [Section 1.4](#4-container-station-setup) and rebooted to be able to use the "opkg" installer command.
227 | - **RUN:** `opkg install nano`
228 |
229 | ### 2. Docker folder creation
230 |
231 | 1. This section is a continuation of the QNAP QTS folder creation steps from the previous section. Here we will create required sub-folders in the `docker/` Shared Folder.
232 |
233 | 1. Before creating the folders, these descriptions will familiarize you with the structure.
234 |
235 | `/share/docker/appdata`
236 | - This is where `application` data and internal config files will reside.
237 | - Each docker `container` will have its own named subfolder.
238 |
239 | `/share/docker/compose`
240 | - This is where `Docker stack` files will be stored using the docker compose format.
241 | - Each `compose` file can have multiple apps or containers included in the stack.
242 | - A git repository can provide versioning and backup for this folder.
243 | - **Do not save sensitive data** in compose.yml files if this is a git repository.
244 |
245 | `/share/docker/runtime`
246 | - OPTIONAL. `Temporary` DB files and `transcode` files will go here.
247 | - This folder should reside on a volume that does not get backed up.
248 | - Link this folder to a fast storage volume or Qtier cache if possible.
249 | - If used, create with `ln -s /target/volume/path /share/docker/runtime`
250 |
251 | `/share/docker/scripts`
252 | - Docker helper scripts for convenient container management are stored here.
253 | - Read and update the `.vars_docker.env` file with your configuration info.
254 | - These scripts are why folder paths and compose files have strict naming requirements.
255 |
256 | `/share/docker/secrets`
257 | - This folder contains `secret` or `sensitive` configuration data such as passwords.
258 | - Do **not** store this folder in a public git repository.
259 | - Non-sensitive, `common` configuration settings can also be stored here.
260 |
261 | `/share/docker/swarm`
262 | - This is where `Swarm stack` files will be stored using the docker compose format.
263 | - Each `compose` file can have *multiple* apps or containers included in the stack.
264 | - A git repository can provide versioning and backup for this folder.
265 | - **Do not save sensitive data** in compose.yml files if this is a git repository.
266 |
267 | 1. The required subfolders should be created using this terminal command:
268 | - QNAP ONLY: A link from `/opt/docker` to `/share/docker` is required for script operations.
269 | ```bash
270 | ln -s /share/docker /opt/docker
271 | ```
272 |
273 | **TIP:** Change `-o 1000` to your docker user `UID` and `-g 1000` to your docker group `GUID`.
274 | ```bash
275 | install -o 1000 -g 1000 -m 755 -d /share/docker/{appdata,compose,scripts,secrets,swarm}
276 | ```
277 |
278 | - Once required folders are created, make sure all files and sub-folders inside `docker/` are owned by the `dockeruser` and have the proper permissions:
279 | ```bash
280 | chown dockeruser:dockergroup -cR /opt/docker && chmod 755 -cR /opt/docker
281 | ```
282 |
283 | - This is what your folder heirarchy should show after creating the required folders:
284 | ```bash
285 | # Docker folder heirarchy
286 | /share
287 | └── docker
288 | ├── appdata
289 | │ ├── appname
290 | │ └── ...
291 | ├── compose
292 | │ ├── appname
293 | │ └── ...
294 | ├── runtime
295 | ├── scripts
296 | ├── secrets
297 | └── swarm
298 | ├── appname
299 | └── ...
300 | ```
301 | - Viewed through WinSCP, which shows the volume designation:
302 | 
303 |
The `CECACHEDEV2_DATA` volume tag may be different on your NAS.
304 |
305 | 1. Next you need to download the `docker helper scripts` from this [QNAP HomeLAB Docker Scripts](https://gitlab.com/qnap-homelab/docker-scripts) repository to your `/share/docker/scripts/` directory.
306 |
307 |
308 |
309 | **WARNING:**
310 | The automatic install script is not working, please download and install the scripts manually.
311 |
312 |
313 |
314 | - ~~Alternatively, if you trust my installation script to run as root on your system, you can run this `curl` command that will automatically download and install the scripts for you:~~
315 |
316 | - ***TIP:*** Read through and understand what a script does before executing possibly malicious code on any device.
317 |
318 | ```bash
319 | # install the docker_scripts_setup.sh using wget without downloading the file
320 | wget -qO - https://raw.githubusercontent.com/qnap-homelab/docker-scripts/master/docker_scripts_setup.sh | sh
321 | ```
322 |
323 | ***OR***
324 | ```bash
325 | # download and install the docker_scripts_setup.sh using cURL
326 | curl -fs https://gitlab.com/qnap-homelab/docker-scripts/docker_scripts_setup.sh | sh
327 | ```
328 |
329 | ### 3. Entware-std profile setup
330 |
331 | 1. Type the below lines into the QNAP command line. These commands will add a shortcut to reload the `profile` and make the docker scripts load each time you connect via SSH terminal.
332 | ```bash
333 | printf "\nalias profile='source /opt/etc/profile'" >> /opt/etc/profile
334 | ```
335 | ```bash
336 | printf "\nsource /opt/docker/scripts/docker_commands_list.sh -c" >> /opt/etc/profile
337 | ```
338 | - ***NOTE:*** If you prefer to enter the text manually, these are the lines that need to go at the bottom of the `profile` file:
339 | ```bash
340 | alias profile='source /opt/etc/profile'
341 | source /opt/docker/scripts/docker_commands_list.sh -c
342 | ```
343 |
344 | - ***OPTIONAL:*** The below steps accomplish the same thing as above, but add notification messages whenever you reload or log into the qnap cli.
345 |
346 | - **EDIT** the `profile` file via `nano /opt/etc/profile` or `vi /opt/etc/profile`
347 | - **NOTE:** I prefer to use VSCodium to edit this file as it provides syntax highlighting.
348 | ```bash
349 | source /opt/docker/scripts/docker_commands_list.sh -c && echo " >> '.../docker_commands_list.sh' successfully loaded" || echo " -- ERROR: could not import '.../docker_commands_list.sh'"
350 | ```
351 | - ***NOTE:*** You will need to restart your ssh terminal session, or execute the `profile` alias (a shortcut to reload `profile`), in order to make the changes effective.
352 |
353 |
354 |
355 |
356 | **WARNING:**
357 | If you use a Windows client to save the profile (or the scripts below),
358 | by default the files will be saved with the `CR LF` end of line sequence,
359 | and will error when executed.
360 |
361 | **You MUST set the end of line sequence to UNIX `LF`.**
362 | **Windows `CR LF` style EoL will result in failed scripts with no error.**
363 |
364 |
VSCodium EoL Settings
365 |

366 |
(click on the "CRLF" text on the right of the bottom status bar)
367 |
368 |
369 |
370 | ### 4. Docker Scripts Reference
371 |
372 | 1. Once the `profile` and `/share/docker/scripts` are set up, use the below section as a reference for Docker shortcut commands.
373 |
374 | - In general, this is the scheme for how the shortcut acronyms are composed:
375 |
376 | - `dc...` refers to "**D**ocker **C**ompose" commands, for use outside of a swarm setup
377 | - `dl...` refers to "**D**ocker **L**ist" commands (i.e. docker processes, docker networks, etc)
378 | - `ds...` refers to "**D**ocker **S**tack" commands (groups of containers in a swarm setup)
379 | - `dv...` refers to "**D**ocker ser**V**ice" commands (mostly error and logs related)
380 | - `dw...` refers to "**D**ocker s**W**arm" initialization/removal commands (the whole swarm)
381 | - `dy...` refers to "**D**ocker s**Y**stem" commands for showing info and cleaning remnants
382 |
383 |
384 | - ***NOTE:*** Individual script descriptions have been removed from this `readme.md`. Please refer to the [docker_commands_list.sh](https://github.com/QNAP-HomeLAB/Docker-Scripts/blob/master/docker_commands_list.sh) file for an updated list with descriptions.
385 |
386 | ---
387 |
388 |
389 | ## Docker general config steps
390 |
391 |
392 | All instructions in this section will apply to your chosen Docker environment.
393 |
394 | ### 1. Environment Variables
395 |
396 | 1. The Docker helper scripts require several environment variable to be properly configured.
397 |
398 | - The `.vars_docker.env` file has variables used by both Swarm and Compose containers.
399 |
400 | - Ensure this file is located here: `/share/docker/scripts/.vars_docker.env`
401 |
402 | - Read through this file, and fill in ***YOUR* NETWORK, NAS, OR PERSONAL INFORMATION**.
403 |
404 | - Pay special attention to these variables, as they are ***REQUIRED:***
405 |
406 | - `var_host_ip` - this is the Local Area Network IP address of your QNAP
407 |
408 | - `var_uid` - userid from command `id dockeruser`
409 |
410 | - `var_gid` - groupid from command `id dockeruser`
411 |
412 | - `var_tz` - time zone in standard `Region/City` format
413 |
414 | - `var_domain0` - main, or only, domain name used by Traefik
415 |
416 | - `var_dns_provider` - DNS provider (e.g. Cloudflare, Namecheap, etc)
417 |
418 | - `var_certresolver` - Certificate Resolver (e.g. Cloudflare, Namecheap, etc)
419 |
420 | - There are many more variables, but not all will be used for each new container created.
421 |
422 | ### 2. Docker Container Creation
423 |
424 | 1. The basic setup is now complete. Continue in one of the two (or a combination of both!) linked repositories below to further customize your Docker environment.
425 |
426 | I recommend the `Docker Swarm` setup, as it is considered a production environment. Docker Compose files can still be used in a Docker Swarm, but not all features of a Swarm can be used in the basic Compose setup.
427 |
428 | Once these environment specific steps are completed, you will be ready to customize `Traefik` and other Docker container configuration files also found in the repositories below.
429 |
430 | Download and modify the desired Docker container config files, or write your own.
431 |
432 |
433 | 2. Final required steps and example application configuration files from QNAP HomeLAB:
434 | - [QNAP HomeLAB Docker Compose Configs](https://www.github.com/QNAP-HomeLAB/Docker-Compose) - No further system configuration required. `docker-compose.yml` files can be used to immediately run containerized applications.
435 | - [QNAP HomeLAB Docker Swarm Configs](https://www.github.com/QNAP-HomeLAB/Docker-Swarm) - Several more system configuration steps are required before you can run containerized applications using a Swarm setup.
436 |
437 | If you have questions or issues, please join the community here: [QNAP Unofficial Discord](https://discord.gg/NaxEB4sz7G).
438 |
439 | ---
440 | ---
441 |
442 | # Contributors
443 |
444 | * Thanks to the late `gkoerk` (RIP) for starting this community and project. Without his efforts, none of this would have been possible.
445 | * Funky Penguin at funkypenguin.co.nz provided a lot of the inspiration and docker config examples which started this QNAP specific project.
446 | * Several articles from smarthomebeginner.com were used as reference for the Traefik and Cloudflare configuration steps contained in the next two sections of this guide.
447 | * The many helpers and members in the [QNAP Unofficial Discord](https://discord.gg/NaxEB4sz7G) community.
448 |
449 | ---
450 |
451 | # DISCLAIMER
452 |
453 | - **WARNING:** This guide is incomplete, and as such ***will probably contain errors***.
454 |
455 | * **NOTE:** Effort has been made to provide accurate instructions tailored for QNAP NAS devices, but no guarantee can be made that this guide will work on your specific device.
456 |
457 | - I find it unfortunate that I have to say this, but you must accept all liability for any loss or damage or inconvenience resulting from your use of the information contained in these guides.
458 |
459 | - All responsibility and risk for properly verifying the validity of anything written in this guide lies with the user.
460 |
461 | - Contributors have composed the steps contained herin to the best of their ability, but nobody is infallible nor can all situations be accounted for.
462 |
463 | - If you have questions or concerns, please join us on the [QNAP Unofficial Discord](https://discord.gg/NaxEB4sz7G) community and request help.
464 |
--------------------------------------------------------------------------------
/docker_commands_list.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | ## Folder hierarchy for Drauku's directory structure, modified from gkoerk's famously awesome folder structure for stacks.
4 | export docker_folder="/opt/docker"
5 | export docker_appdata="${docker_folder}/appdata"
6 | export docker_compose="${docker_folder}/compose"
7 | export docker_runtime="${docker_folder}/runtime"
8 | export docker_scripts="${docker_folder}/scripts"
9 | export docker_secrets="${docker_folder}/secrets"
10 | export docker_swarm="${docker_folder}/swarm"
11 |
12 | ## external variable sources
13 | source /opt/docker/scripts/.color_codes.conf
14 | source /opt/docker/scripts/.vars_docker.env
15 |
16 | # function definitions
17 | fnc_help_docker_commands() {
18 | echo -e " ┌────────────────────────────────────────────────────────────────────────"
19 | echo -e " │ ${blu:?}Bash scripts and Docker aliases created to increase Docker command execution speed.${def:?}"
20 | echo -e " │ "
21 | echo -e " │ SYNTAX: # dlist | dlist ${cyn:?}-option${def:?}"
22 | echo -e " │ VALID OPTIONS:"
23 | echo -e " │ ${cyn:?} -a ${def:?}│${cyn:?} --aliases ${def:?}│ Displays the list of Docker Aliases."
24 | echo -e " │ ${cyn:?} -s ${def:?}│${cyn:?} --scripts ${def:?}│ Displays the list of Docker Scripts."
25 | echo -e " │ ${cyn:?} -f ${def:?}│${cyn:?} --functions ${def:?}│ Displays both the list of Docker Scripts and Aliases."
26 | echo -e " │ ${cyn:?} -c ${def:?}│${cyn:?} --create ${def:?}│ Register and create docker aliases and custom commands."
27 | echo -e " │ ${cyn:?} -h ${def:?}│${cyn:?} --help ${def:?}│ Displays this help message."
28 | echo -e " └────────────────────────────────────────────────────────────────────────"
29 | echo
30 | exit 1 # Exit script after printing help
31 | }
32 | case "${1}" in ("-h"|*"help"*) fnc_help_docker_commands ;; esac
33 |
34 | # echo -e " ┌────────────────────────────────────────────────────────────────────────"
35 | # echo -e " │ "
36 | # echo -e " └────────────────────────────────────────────────────────────────────────"
37 | # echo -e " ┌─────────┬──────────────────┬───────────────────────────────────────────"
38 | # echo -e " ├─────────┼──────────────────┼───────────────────────────────────────────"
39 | # echo -e " └─────────┴──────────────────┴───────────────────────────────────────────"
40 | # ┌ ─ ┬ ─ ┐
41 | # │ │ │
42 | # ├ ─ ┼ ─ ┤
43 | # │ │ │
44 | # └ ─ ┴ ─ ┘
45 |
46 | # docker_commands_list -- function and alias for this script file
47 | fnc_docker_commands(){ sh "${docker_scripts}/docker_commands_list.sh" "${@}"; }
48 | alias dcmd="fnc_docker_commands"
49 | alias dlist="fnc_docker_commands -f";
50 | # alias dscripts='source /opt/docker/scripts/docker_commands_list.sh --create'
51 |
52 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE ${cyn:?}-help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; }
53 |
54 | ## docker script definitions
55 | # src="/opt/docker/scripts/docker_commands_list.sh"
56 | # . $src && echo " >> '$src' successfully loaded" || echo " -- ERROR: could not import '$src'"
57 | # [ -e $src ] && . $src || echo " -- ERROR: '$src' does not exist"
58 |
59 | fnc_list_aliases() {
60 | echo -e " ┌─────────┬──────────────────┬───────────────────────────────────────────"
61 | echo -e " │ ${blu:?}ALIAS${def:?} │ ${blu:?}TARGET COMMAND${def:?} │ ${blu:?}ALIAS DESCRIPTION${def:?}"
62 | echo -e " ├─────────┼──────────────────┼───────────────────────────────────────────"
63 | echo -e " │${cyn:?} dk ${def:?}│${ylw:?} docker ${def:?}│ '${cyn:?}docker${def:?}' command alias"
64 | echo -e " │${cyn:?} dki ${def:?}│${ylw:?} docker images ${def:?}│ '${cyn:?}docker ${grn:?}images${def:?}' command alias"
65 | echo -e " │${cyn:?} dkn ${def:?}│${ylw:?} docker network ${def:?}│ '${cyn:?}docker ${grn:?}network${def:?}' command alias"
66 | echo -e " │${cyn:?} dkv ${def:?}│${ylw:?} docker service ${def:?}│ '${cyn:?}docker ${grn:?}service${def:?}' command alias"
67 | echo -e " │${cyn:?} dkl ${def:?}│${ylw:?} docker logs ${def:?}│ '${cyn:?}docker ${grn:?}logs${def:?}' command alias"
68 | echo -e " │${cyn:?} dklf ${def:?}│${ylw:?} docker logs -f ${def:?}│ '${cyn:?}docker ${grn:?}logs -f${def:?}' command alias"
69 | echo -e " │${cyn:?} dkrm ${def:?}│${ylw:?} docker rm ${def:?}│ '${cyn:?}docker ${grn:?}rm${def:?}' (removes no-trunc list) shortcut"
70 | echo -e " │${cyn:?} dkrmi ${def:?}│${ylw:?} docker rmi ... ${def:?}│ '${cyn:?}docker ${grn:?}rmi${def:?}' (removes dangling images) shortcut"
71 | echo -e " │${cyn:?} dkt ${def:?}│${ylw:?} docker stats ... ${def:?}│ '${cyn:?}docker ${grn:?}stats${def:?}' (lists stats using custom columns) shortcut"
72 | echo -e " │${cyn:?} dkps ${def:?}│${ylw:?} docker ps ... ${def:?}│ '${cyn:?}docker ${grn:?}ps${def:?}' (lists processes using custom columns) shortcut"
73 | echo -e " │${cyn:?} dc ${def:?}│${ylw:?} docker compose ${def:?}│ '${cyn:?}docker compose${def:?}' command alias"
74 | # echo -e " │${cyn:?} dm ${def:?}│${ylw:?} docker-machine ${def:?}│ '${cyn:?}docker-machine${def:?}' command alias"
75 | echo -e " │${cyn:?} dccfg ${def:?}│${ylw:?} dlg --compose ${def:?}│ '${cyn:?}docker ${grn:?}logs${def:?}' custom command alias"
76 | echo -e " │${cyn:?} dwcfg ${def:?}│${ylw:?} dlg --swarm ${def:?}│ '${cyn:?}docker ${grn:?}logs${def:?}' custom command alias"
77 | echo -e " │${cyn:?} bounce ${def:?}│${ylw:?} dsb --all ${def:?}│ ${cyn:?}stop${def:?} and ${cyn:?}restart${def:?} swarm stacks custom command alias"
78 | echo -e " │${cyn:?} dsup ${def:?}│${ylw:?} dsd --all ${def:?}│ ${cyn:?}start${def:?} ${grn:?}swarm stack${def:?} custom command alias"
79 | echo -e " │${cyn:?} dsrm ${def:?}│${ylw:?} dsr --all ${def:?}│ ${cyn:?}remove${def:?} ${grn:?}swarm stack${def:?} custom command alias"
80 | echo -e " │${cyn:?} dverror ${def:?}│${ylw:?} dve ${def:?}│ ${cyn:?}display${def:?} ${grn:?}container${def:?} errors custom command alias"
81 | echo -e " │${cyn:?} dvlogs ${def:?}│${ylw:?} dvl ${def:?}│ ${cyn:?}display${def:?} ${grn:?}container${def:?} logs custom command alias"
82 | echo -e " │${cyn:?} dwinit ${def:?}│${ylw:?} dwin traefik ${def:?}│ ${cyn:?}initialize${def:?} ${grn:?}swarm${def:?} custom command alias"
83 | echo -e " │${cyn:?} dwclr ${def:?}│${ylw:?} dwlv --all ${def:?}│ ${cyn:?}leave${def:?} and ${cyn:?}remove${def:?} ${grn:?}swarm${def:?} custom command alias"
84 | echo -e " │${cyn:?} dcmd ${def:?}│${ylw:?} dlist ${def:?}│ ${cyn:?}list${def:?} available custom Docker function aliases for use in terminal."
85 | echo -e " └─────────┴──────────────────┴───────────────────────────────────────────"
86 | echo -e " NOTE: Aliases do not have options, and are only shortcuts for the target command."
87 | echo
88 | }
89 | fnc_list_scripts() {
90 | echo -e " ┌────────────────────┬─────────────────────────┬──────────────────────────"
91 | echo -e " │ ${blu:?}COMMAND${def:?} │ ${blu:?}SCRIPT FILE NAME${def:?} │ ${blu:?}COMMAND DESCRIPTION${def:?}"
92 | echo -e " ├────────────────────┼─────────────────────────┼──────────────────────────"
93 | echo -e " │${cyn:?} dcmd / dlist ${def:?}│ ${ylw:?}docker_commands_list ${def:?}│ ${cyn:?}lists${def:?} available custom Docker function aliases for use in terminal."
94 | echo -e " ├──${blu:?} docker list ${def:?}─────┼─────────────────────────┼──────────────────────────"
95 | echo -e " │${cyn:?} dlc ${def:?}│ ${ylw:?}docker_list_container ${def:?}│ ${cyn:?}lists${def:?} currently deployed ${grn:?}docker containers${def:?} and/or services"
96 | echo -e " │${cyn:?} dlg / dcg / dsg ${def:?}│ ${ylw:?}docker_list_configs ${def:?}│ ${cyn:?}lists${def:?} ${grn:?}config files${def:?} in the custom QNAP Docker folder structure"
97 | echo -e " │${cyn:?} dli / dlimg ${def:?}│ ${ylw:?}docker_system_image ${def:?}│ ${cyn:?}lists${def:?} ${grn:?}docker images${def:?} currently stored on this system"
98 | echo -e " │${cyn:?} dln ${def:?}│ ${ylw:?}docker_system_network ${def:?}│ ${cyn:?}lists${def:?} currently created docker ${grn:?}networks${def:?}"
99 | echo -e " │${cyn:?} dls ${def:?}│ ${ylw:?}docker_list_stack ${def:?}│ ${cyn:?}lists${def:?} currently deployed ${grn:?}docker swarm stacks${def:?} and services"
100 | echo -e " │${cyn:?} dlv ${def:?}│ ${ylw:?}docker_system_volume ${def:?}│ ${cyn:?}lists${def:?} currently created docker ${grn:?}volumes${def:?}"
101 | echo -e " ├──${blu:?} docker compose ${def:?}──┼─────────────────────────┼──────────────────────────"
102 | echo -e " │${cyn:?} dcf / dcfolders ${def:?}│ ${ylw:?}docker_compose_folders ${def:?}│ ${cyn:?}creates ${grn:?}compose folder structure${def:?}" # for (1 - 9 listed) stacks"
103 | echo -e " │${cyn:?} dcb / dcbounce ${def:?}│ ${ylw:?}docker_compose_bounce ${def:?}│ ${cyn:?}removes${def:?} then ${cyn:?}recreates${def:?} a docker compose container "
104 | echo -e " │${cyn:?} dcl / dclogs ${def:?}│ ${ylw:?}docker_compose_logs ${def:?}│ ${cyn:?}lists${def:?} docker compose ${grn:?}logs${def:?}"
105 | echo -e " │${cyn:?} dcn / dcnet ${def:?}│ ${ylw:?}docker_compose_networks ${def:?}│ ${cyn:?}creates${def:?} docker compose ${grn:?}networks${def:?}"
106 | echo -e " │${cyn:?} dcs / dcstart ${def:?}│ ${ylw:?}docker_compose_start ${def:?}│ ${cyn:?}starts${def:?} (brings 'up') a docker compose container"
107 | echo -e " │${cyn:?} dcp / dcstop ${def:?}│ ${ylw:?}docker_compose_stop ${def:?}│ ${cyn:?}stops${def:?} (brings 'down') a docker compose container"
108 | echo -e " │${cyn:?} dct / dctest ${def:?}│ ${ylw:?}docker_compose_test ${def:?}│ ${cyn:?}tests${def:?} a docker compose file config by displaying all variables villed in"
109 | echo -e " ├──${blu:?} docker service ${def:?}──┼─────────────────────────┼──────────────────────────"
110 | echo -e " │${cyn:?} dve / dverror ${def:?}│ ${ylw:?}docker_service_error ${def:?}│ ${cyn:?}lists${def:?} docker services with ${grn:?}last error${def:?}"
111 | echo -e " │${cyn:?} dvl / dvlogs ${def:?}│ ${ylw:?}docker_service_logs ${def:?}│ ${cyn:?}lists${def:?} docker service and container ${grn:?}logs${def:?}"
112 | echo -e " ├──${blu:?} docker stack ${def:?}────┼─────────────────────────┼──────────────────────────"
113 | echo -e " │${cyn:?} dsf / dwfolder ${def:?}│ ${ylw:?}docker_stack_folders ${def:?}│ ${cyn:?}creates ${grn:?}stack folder structure${def:?}" # for (1 - 9 listed) stacks"
114 | echo -e " │${cyn:?} dsb / dsbounce ${def:?}│ ${ylw:?}docker_stack_bounce ${def:?}│ ${cyn:?}removes${def:?} then ${cyn:?}recreates${def:?} a docker stack container"
115 | echo -e " │${cyn:?} dss / dsstart ${def:?}│ ${ylw:?}docker_stack_start ${def:?}│ ${cyn:?}deploys ${grn:?}stack${def:?}, or a list of stacks in '${ylw:?}.../${cyn:?}swarm_stacks.conf${def:?}'"
116 | echo -e " │${cyn:?} dsp / dsstop ${def:?}│ ${ylw:?}docker_stack_stop ${def:?}│ ${cyn:?}removes ${grn:?}stack${def:?}, or ${cyn:?}-all${def:?} stacks listed via 'docker stack ls'"
117 | echo -e " ├──${blu:?} docker swarm ${def:?}────┼─────────────────────────┼──────────────────────────"
118 | echo -e " │${cyn:?} dwin / dwinit ${def:?}│ ${ylw:?}docker_swarm_init ${def:?}│ ${grn:?}swarm initialization script${def:?}, does ${ylw:?}NOT${def:?} download new scripts"
119 | echo -e " │${cyn:?} dwup / dwsup ${def:?}│ ${ylw:?}docker_swarm_setup ${def:?}│ ${grn:?}swarm setup script${def:?}, ${ylw:?}DOES${def:?} download new install scripts"
120 | echo -e " │${cyn:?} dwlv / dwclr ${def:?}│ ${ylw:?}docker_swarm_leave ${def:?}│ ${red:?}USE WITH CAUTION!${def:?} prunes & clears all docker stacks, ${grn:?}leaves swarm${def:?}"
121 | echo -e " ├──${blu:?} docker system ${def:?}───┼─────────────────────────┼──────────────────────────"
122 | echo -e " │${cyn:?} dcln / dclean ${def:?}│ ${ylw:?}docker_system_clean ${def:?}│ ${cyn:?}stops${def:?} and ${cyn:?}removes ${grn:?}ALL containers${def:?}, images, networks, and volumes"
123 | echo -e " │${cyn:?} dprn / dprune ${def:?}│ ${ylw:?}docker_system_prune ${def:?}│ ${cyn:?}prunes${def:?} ${grn:?}UNUSED containers${def:?}, images, networks, and volumes"
124 | echo -e " └────────────────────┴─────────────────────────┴──────────────────────────"
125 | echo -e " NOTE: Commands accept '${cyn:?}options${def:?}' which can be listed using the '${cyn:?}--help${def:?}' flag after the command, e.g. ${cyn:?}dls --${cyn:?}help${def:?} "
126 | echo
127 | }
128 | fnc_create_aliases(){
129 | # docker alias list
130 | alias dk='docker'
131 | alias dki='docker images'
132 | alias dkn='docker network'
133 | alias dkv='docker service'
134 | alias dkrm='docker rm'
135 | alias dkl='docker logs'
136 | alias dklf='docker logs -f'
137 | alias dkrm='docker rm `docker ps --no-trunc -aq`'
138 | alias dkrmi='docker rmi $(docker images --filter "dangling=true" -q --no-trunc)'
139 | alias dkt='docker stats --format "table {{.Name}}\t{{.CPUPerc}} {{.MemPerc}}\t{{.MemUsage}}\t{{.NetIO}}"'
140 | alias dkps='docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Image}}"'
141 | alias dkc='docker compose'
142 | # alias dkm='docker-machine'
143 | # alias dkmssh='docker-machine ssh'
144 |
145 | docker_version(){ docker --version && docker compose version; }
146 | alias dkver="docker_version"
147 |
148 | docker_compose_info(){ docker ps -f name="${1}"; }
149 | alias dcinfo="docker_compose_info"
150 |
151 | docker_exec(){ docker exec -it "$(docker ps -f name="${1}" --format "{{.ID}}")" /bin/sh; }
152 | alias dkex="docker_exec"
153 | alias dkx="docker_exec"
154 |
155 | ipcheck(){ echo "Container IP: $(docker container exec -it "${*}" curl ipinfo.io)"; }
156 | alias checkip='ipcheck'
157 | # portcheck(){ curl -sq -b cookies.txt "http://${QIP}:${QPORT}/container-station/api/v1/system/port/tcp/${1}"; }
158 | # alias checkport='portcheck'
159 | vpncheck(){ echo " Host IP: $(wget -qO- ifconfig.me)" && echo "Container IP: $(docker container exec -it "${*}" wget -qO- ipinfo.io/ip)"; }
160 | alias checkvpn='vpncheck'
161 |
162 | ## folder and file permissions
163 | export perms_cert="a-rwx,u=rwX,g=,o=" # 600 # -rw-rw----
164 | export perms_conf="a-rwx,u+rwX,g=rwX,o=rX" # 664 # -rw-rw-r--
165 | export perms_data="a-rwx,u+rwX,g=rwX,o=" # 660 # -rw-rw----
166 | # export docker_dir="a=rwx,o-w" # 775 # -rwxrwxr-x
167 |
168 | docker_file_permissions(){
169 | case "${1}" in
170 | ("-a"|"--all") files_dir="${docker_folder}" ;;
171 | ("-l"|"--local") files_dir="${docker_compose}/${1}" ;;
172 | ("-w"|"--swarm") files_dir="${docker_swarm}/${1}" ;;
173 | (*)
174 | echo "invalid syntax"
175 | esac
176 | # update restricted access file permissions to 600
177 | files_restricted=("acme.json" "*.crt" "*.key" "*.pub" "*.ppk" "*.pem");
178 | for file in "${files_restricted[@]}"; do
179 | ${var_sudo:-} find "$files_dir" -iname "$file" -type f -exec chmod "$perms_cert" {} +
180 | done
181 | # update limited access file permissions to 660
182 | files_limited=(".conf" "*.env" ".log" "*.secret");
183 | for file in "${files_limited[@]}"; do
184 | ${var_sudo:-} find "$files_dir" -iname "$file" -type f -exec chmod "$perms_data" {} +
185 | done
186 | # # update general access file permissions to 664
187 | # files_general=("*.yml" "*.yaml" "*.toml");
188 | # for file in "${files_general[@]}"; do
189 | # ${var_sudo}find "$docker_dir" -iname "$file" -type f -exec chmod "$perms_conf" {} +
190 | # done
191 | }
192 |
193 |
194 | appdata(){ cd "${docker_appdata}/${1}" || return; }
195 | compose(){ cd "${docker_compose}/${1}" || return; }
196 | secrets(){ cd "${docker_secrets}/${1}" || return; }
197 | swarm(){ cd "${docker_swarm}/${1}" || return; }
198 |
199 | # docker_compose_bounce -- stops then re-creates the listed containers or '-all' container-stacks with config files in the folder structure
200 | docker_compose_bounce(){ sh "${docker_scripts}/docker_compose_bounce.sh" "${@}"; }
201 | alias dcb="docker_compose_bounce";
202 | # alias dcbounce="docker_compose_bounce --all";
203 |
204 | # docker_compose_folders -- creates the folder structure required for each listed compose stack name (up to 9 per command)
205 | docker_compose_folders(){ sh "${docker_scripts}/docker_compose_folders.sh" "${@}"; }
206 | alias dcf="docker_compose_folders";
207 |
208 | # docker_compose_edit -- opens a ../compose.yml file in nano text editor
209 | docker_compose_edit(){ nano "${docker_compose}/$1/compose.yml"; }
210 | alias dce="docker_compose_edit"
211 |
212 | # docker_compose_start -- starts the entered container using preconfigured docker_compose files
213 | docker_compose_start(){ sh "${docker_scripts}/docker_compose_start.sh" "${@}"; }
214 | alias dcu="docker_compose_start"; # "Up"
215 | alias dcs="docker_compose_start"; # "Start"
216 |
217 | # docker_compose_stop -- stops the entered container
218 | docker_compose_stop(){ sh "${docker_scripts}/docker_compose_stop.sh" "${@}"; }
219 | alias dcd="docker_compose_stop"; # "Down"
220 | alias dcp="docker_compose_stop -p"; # "stoP"
221 | alias dcr="docker_compose_stop -r"; # "Remove"
222 |
223 | # docker_compose_test -- displays the indicated compose file with variables/secrets filled in
224 | docker_compose_test(){ sh "${docker_scripts}/docker_compose_test.sh" "${@}"; }
225 | alias dcc="docker_compose_test";
226 | alias dct="docker_compose_test";
227 | alias dctest="docker_compose_test";
228 |
229 | # docker_compose_logs -- displays 50 log entries for the indicated docker compose container
230 | docker_compose_logs(){ sh "${docker_scripts}/docker_compose_logs.sh" "${@}"; }
231 | alias dcl="docker_compose_logs";
232 |
233 | # docker_compose_networks -- creates required networks for docker compose container manipulation via scripts
234 | docker_compose_networks(){ sh "${docker_scripts}/docker_compose_networks.sh" "${@}"; }
235 | alias dcn="docker_compose_networks";
236 |
237 | # # docker_folders_create -- creates the folder structure required for each listed docker container
238 | # dkfolders(){ sh "${docker_scripts}/docker_folders_create.sh" "${@}"; }
239 | # alias dcf="dkfolders -c";
240 | # alias dsf="dkfolders -w";
241 | # alias dwf="dkfolders -w";
242 | # # alias dcf='dkfolders -c "$1"';
243 | # # alias dsf='dkfolders -w "$1"';
244 | # # alias dwf='dkfolders -w "$1"';
245 |
246 | # docker_list_configs -- lists existing stack config files for either swarm or compose filepaths
247 | docker_list_configs(){ sh "${docker_scripts}/docker_list_configs.sh" "${1}"; }
248 | alias dlg="docker_list_configs";
249 | alias dccfg="docker_list_configs --compose";
250 | alias dcg="docker_list_configs --compose";
251 | alias dscfg="docker_list_configs --swarm";
252 | alias dsg="docker_list_configs --swarm";
253 | alias dwcfg="docker_list_configs --swarm";
254 | alias dwg="docker_list_configs --swarm";
255 |
256 | # docker_list_container -- lists all currently deployed containers and/or services
257 | docker_list_container(){ sh "${docker_scripts}/docker_list_container.sh" "${1}" "${2}"; }
258 | alias dlc="docker_list_container";
259 |
260 | # docker_list_stack -- lists all stacks and number of services inside each stack
261 | docker_list_stack(){ sh "${docker_scripts}/docker_list_stack.sh" "${1}" "${2}"; }
262 | alias dls="docker_list_stack";
263 | alias dlw="docker_list_stack";
264 |
265 | bounce(){
266 | if [[ $1 = "-all" ]]; then
267 | IFS=$'\n';
268 | list=( "$(docker stack ls --format '{{.Name}}')" );
269 | else
270 | list=("$*")
271 | fi
272 | for i in "${list[@]}"; do
273 | docker stack rm "$i"
274 | done
275 | for i in "${list[@]}"; do
276 | while [ "$(docker service ls --filter label=com.docker.stack.namespace="$i" -q)" ] || [ "$(docker network ls --filter label=com.docker.stack.namespace="$i" -q)" ]; do sleep 1; done
277 | done
278 | for i in "${list[@]}"; do
279 | docker stack deploy "$i" -c /share/docker/swarm/"$i"/compose.yml
280 | done
281 | unset list IFS
282 | }
283 | # docker_stack_bounce -- removes then re-deploys the listed stacks or '-all' stacks with config files in the folder structure
284 | # docker_stack_bounce(){ sh "${docker_scripts}/docker_stack_bounce.sh" "${@}"; }
285 | docker_stack_bounce(){
286 | limit=15
287 | docker stack rm "${1}"
288 | until [ -z "$(docker service ls --filter label=com.docker.stack.namespace="$1" -q)" ] || [ "$limit" -lt 0 ]; do
289 | sleep 1;
290 | ((limit--))
291 | done
292 | limit=15
293 | until [ -z "$(docker network ls --filter label=com.docker.stack.namespace="$1" -q)" ] || [ "$limit" -lt 0 ]; do
294 | sleep 1;
295 | ((limit--))
296 | done
297 | docker stack deploy "${1}" -c "${docker_swarm}/${1}/compose.yml"
298 | }
299 | alias dsb="docker_stack_bounce";
300 | alias dwb="docker_stack_bounce";
301 | # alias dwbounce="docker_stack_bounce --all";
302 |
303 | # # docker_stack_folders -- creates the folder structure required for each listed stack name (up to 9 per command)
304 | # docker_stack_folders(){ sh "${docker_scripts}/docker_stack_folders.sh" "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"; }
305 | # docker_stack_folders -- creates the folder structure required for each listed stack name
306 | docker_stack_folders(){ sh "${docker_scripts}/docker_stack_folders.sh" "${@}"; }
307 | alias dsf="docker_stack_folders";
308 | alias dwf="docker_stack_folders";
309 | alias dwdir="docker_stack_folders";
310 | alias dwfolder="docker_stack_folders";
311 |
312 | # docker_stack_deploy -- deploys a single stack as defind in the configs folder structure
313 | # docker_stack_start(){ sh "${docker_scripts}/docker_stack_start.sh" "${@}"; }
314 | # docker_stack_start(){ docker stack deploy "${1}" -c "${docker_swarm}/${1}/compose.yml"; }
315 | docker_stack_start(){ docker stack deploy "${1}" -c "${docker_swarm}/${1}/compose.yml"; }
316 | alias dsd="docker_stack_start"; # "Deploy"
317 | alias dss="docker_stack_start"; # "Start"
318 | alias dsu="docker_stack_start"; # "Up"
319 | alias dsup="docker_stack_start --all";
320 | alias dwd="docker_stack_start"; # "Deploy"
321 | alias dws="docker_stack_start"; # "Start"
322 | alias dwu="docker_stack_start"; # "Up"
323 | alias dwup="docker_stack_start --all";
324 |
325 | # docker_stack_remove -- removes a single stack
326 | # docker_stack_stop(){ sh "${docker_scripts}/docker_stack_stop.sh" "${@}"; }
327 | docker_stack_stop(){ docker stack rm "${1}"; }
328 | alias dsr="docker_stack_stop"; # "Remove"
329 | alias dsp="docker_stack_stop"; # "stoP"
330 | alias dsrm="docker_stack_stop --all";
331 | alias dwr="docker_stack_stop"; # "Remove"
332 | alias dwp="docker_stack_stop"; # "stoP"
333 | alias dwrm="docker_stack_stop --all";
334 |
335 | # docker_service_errors -- displays 'docker ps --no-trunk ' command output
336 | docker_service_error(){ sh "${docker_scripts}/docker_service_error.sh" "${1}" "${2}"; }
337 | alias dse="docker_service_error";
338 | alias dwe="docker_service_error";
339 | alias dve="docker_service_error";
340 | alias dverror="docker_service_error";
341 |
342 | # docker_service_logs -- displays 'docker service logs ' command output
343 | docker_service_logs(){ sh "${docker_scripts}/docker_service_logs.sh" "${1}" "${2}"; }
344 | alias dsl="docker_service_logs";
345 | alias dwl="docker_service_logs";
346 | alias dvl="docker_service_logs";
347 | alias dvlogs="docker_service_logs";
348 |
349 | # docker_swarm_init -- Initializes a Docker Swarm using the docker_swarm_init.sh script
350 | docker_swarm_init(){ sh "${docker_scripts}/docker_swarm_init.sh" "${1}"; }
351 | alias dsin="docker_swarm_init traefik";
352 | alias dwin="docker_swarm_init traefik";
353 | alias dwinit="docker_swarm_init traefik";
354 | # alias docker_swarm_setup="docker_swarm_init -setup"; # Downloads and executes the docker_swarm_setup.sh script (NOT YET WORKING)
355 |
356 | # docker_swarm_setup -- Downloads and executes the docker_swarm_setup.sh script (NOT YET WORKING)
357 | docker_swarm_setup(){ sh "${docker_scripts}/docker_swarm_setup.sh" "${@}"; }
358 | alias dssup="docker_swarm_setup traefik";
359 | alias dwsup="docker_swarm_setup traefik";
360 | # sh mkdir -pm 766 ${docker_scripts} && curl -fsSL https://raw.githubusercontent.com/Drauku/QNAP-Docker-Swarm-Setup/master/scripts/docker_swarm_setup.sh > "${docker_scripts}/docker_swarm_setup.sh" && . "${docker_scripts}/docker_swarm_setup.sh";
361 |
362 | # docker_swarm_leave -- LEAVES the docker swarm. USE WITH CAUTION!
363 | docker_swarm_leave(){ sh "${docker_scripts}/docker_swarm_leave.sh" "${@}"; }
364 | alias dslv="docker_swarm_leave"
365 | alias dwlv="docker_swarm_leave"
366 | alias dsclr="docker_swarm_leave --all";
367 | alias dwclr="docker_swarm_leave --all";
368 |
369 | docker_backup(){ sh "${docker_scripts}/docker_system_backup.sh"; }
370 | alias dbk="docker_backup";
371 | alias dkbk="docker_backup";
372 | alias dback="docker_backup";
373 |
374 | # docker_system_clean -- similar to prune, but performs more in-depth removal functions
375 | docker_system_clean(){ sh "${docker_scripts}/docker_system_clean.sh" "${1}"; }
376 | alias dkc="docker_system_clean";
377 | alias dyc="docker_system_clean";
378 | alias dclean="docker_system_clean";
379 |
380 | # docker_system_image -- manage docker container images from the docker repository
381 | docker_system_images(){ sh "${docker_scripts}/docker_system_image.sh" "${1}"; }
382 | alias dli="docker_system_images -l";
383 | alias dki="docker_system_images";
384 | alias dyi="docker_system_images";
385 | alias dimage="docker_system_images";
386 |
387 | # docker_system_network -- lists current docker networks
388 | docker_system_network(){ sh "${docker_scripts}/docker_system_network.sh" "${1}" "${2}"; }
389 | alias dln="docker_system_network";
390 | alias dyn="docker_system_network";
391 |
392 | # docker_system_prune -- prunes the docker system (removes unused images and containers and networks and volumes)
393 | docker_system_prune(){ sh "${docker_scripts}/docker_system_prune.sh" "${1}"; }
394 | alias dprn="docker_system_prune";
395 | alias dyp="docker_system_prune";
396 |
397 | # docker_system_stats -- displays resources used by current docker stacks/containers
398 | docker_system_stats(){ sh "${docker_scripts}/docker_system_stats.sh" "${1}"; }
399 | alias dks="docker_system_stats";
400 | alias dys="docker_system_stats";
401 | alias dtop="docker_system_stats --live";
402 | alias dstat="docker_system_stats --live";
403 |
404 | # docker_system_volume -- lists unused docker volumes
405 | docker_system_volume(){ sh "${docker_scripts}/docker_system_volume.sh" "${1}" "${2}"; }
406 | alias dlv="docker_system_volume";
407 | alias dyv="docker_system_volume";
408 |
409 | echo -e "${blu:?} >> Docker terminal aliases and functions ${grn:?}created${blu:?}. Type 'dlist' to display defined commands.${def:?}\n";
410 | }
411 |
412 | # logical action check
413 | case "${1}" in
414 | ("-a"|"--aliases")
415 | fnc_list_aliases;
416 | ;;
417 | ("-s"|"--scripts")
418 | fnc_list_scripts;
419 | ;;
420 | ("-f"|"--functions")
421 | fnc_list_aliases;
422 | fnc_list_scripts;
423 | ;;
424 | (""|"-c"|"--create")
425 | fnc_create_aliases ""; # register docker aliases and custom commands
426 | # [ ! -e "${docker_scripts}/.profile" ] && ln -s /opt/etc/profile "${docker_scripts}/.profile" # create link to 'entware-std' profile
427 | ;;
428 | (*)
429 | fnc_invalid_syntax;
430 | ;;
431 | esac
432 |
--------------------------------------------------------------------------------
/docker_compose_bounce.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # external variable sources
4 | source /opt/docker/scripts/.color_codes.conf
5 | source /opt/docker/scripts/.vars_docker.env
6 | # source /opt/docker/compose/stackslist-compose.conf
7 |
8 | # script variable definitions
9 | unset bounce_list IFS
10 |
11 | # function definitions
12 | fnc_help_compose_bounce(){
13 | echo -e "${blu:?}[-> This script bounces (removes then re-deploys) a single or pre-defined list of Docker Swarm stack <-]${def:?}"
14 | echo -e " -"
15 | echo -e " - SYNTAX: # dsb ${cyn:?}stack_name${def:?}"
16 | echo -e " - SYNTAX: # dsb ${cyn:?}-option${def:?}"
17 | echo -e " - VALID OPTIONS:"
18 | echo -e " - ${cyn:?}-a | --all ${def:?}│ Bounces all containers with a corresponding folder inside the '${ylw:?}${docker_compose}/${def:?}' path."
19 | echo -e " - ${cyn:?}-p | --preset ${def:?}│ Bounces the 'preset' array of containers defined in '${ylw:?}${docker_vars}/${cyn:?}compose_stacks.env${def:?}'"
20 | echo -e " - ${cyn:?}-d | --default ${def:?}│ Bounces the 'default' array of containers defined in '${ylw:?}${docker_vars}/${cyn:?}compose_stacks.env${def:?}'"
21 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message."
22 | echo
23 | exit 1 # Exit script after printing help
24 | }
25 | case "$1" in ("-h"|*"help"*) fnc_help_compose_bounce ;; esac
26 |
27 | fnc_intro_compose_bounce(){ echo -e "${blu:?}[-> STOPS THEN RESTARTS LISTED CONTAINERS <-]${def:?}"; echo -e "${cyn:?} -> ${bounce_list[*]} ${def:?}"; echo; }
28 | fnc_outro_compose_bounce(){ echo -e "[-- ${grn:?}BOUNCE (REMOVE & REDEPLOY) STACK SCRIPT COMPLETE${def:?} --]"; echo; }
29 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> no containers exist to bounce${def:?}"; }
30 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
31 | fnc_list_all(){ IFS=$'\n'; bounce_list=( "$(docker container list --format "{{.Names}}")" ); }
32 | fnc_list_default(){ IFS=$'\n'; bounce_list=( "${stacks_default[@]}" ); }
33 | fnc_list_preset(){ IFS=$'\n'; bounce_list=( "${stacks_preset[@]}" ); }
34 | fnc_docker_compose_stop(){ bash "${docker_scripts}/docker_compose_stop.sh" "${bounce_list[@]}"; }
35 | fnc_docker_compose_start(){ bash "${docker_scripts}/docker_compose_start.sh" "${bounce_list[@]}"; }
36 |
37 | # determine script output according to option entered
38 | case "${1}" in
39 | (-*)
40 | case "${1}" in
41 | ("-a"|"--all") fnc_list_all ;;
42 | ("-d"|"--default") fnc_list_default ;;
43 | ("-p"|"--preset") fnc_list_preset ;;
44 | (*) fnc_invalid_syntax ;;
45 | esac
46 | ;;
47 | (*)
48 | # container_list=("$(docker container list --format {{.Names}})")
49 | # for name in ${!container_list}; do
50 |
51 | # # case "${bounce_list[@]}" in
52 | # # (*${name}*)
53 | # # echo "present"
54 | # # ;;
55 | # # (*)
56 | # # echo "not present"
57 | # # ;;
58 | # # esac
59 |
60 | # if [[ " ${bounce_list[*]} " == *"${name}"* ]]; then
61 | # break
62 | # fi
63 |
64 | # done
65 | IFS=' '; bounce_list=("$@")
66 | ;;
67 | esac
68 |
69 | # # display script intro
70 | # fnc_intro_compose_bounce
71 | # remove all stacks in list defined above
72 | fnc_docker_compose_stop "${bounce_list[@]}"
73 | # (re)deploy all stacks in list defined above
74 | fnc_docker_compose_start "${bounce_list[@]}"
75 | # # display script outro
76 | # fnc_outro_compose_bounce
--------------------------------------------------------------------------------
/docker_compose_folders.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # script variable definitions
7 | unset folder_list IFS; folder_list=("${@}");
8 | # unset args_list IFS; args_list=("${@}");
9 | ## chmod -R a-rwx,u=rwX,g+rX,o=rX # drwxr-x---
10 | appdata_permissions="660" # a-x,ug=rwX,o-rwx # -rw-rw----
11 | compose_permissions="664" # a-x,ug=rwX,o=rX # -rw-rw-r--
12 | folders_permissions="775" # a-x,ug=rwX,o=rX # drwxrwxr-x
13 | cert_permissions="600" # a-rwx,u=rw # -rw-------
14 |
15 | # install -o 1000 -g 1000 -m 775 -d /share/docker/{appdata,compose,secrets}/${1}
16 | # install -o 1000 -g 1000 -m 664 /dev/null /share/docker/compose/${1}/compose.yml
17 | # install -o 1000 -g 1000 -m 664 /dev/null /opt/docker/compose/$1/.env
18 | # ln -sf /share/docker/compose/${1}/.env /share/docker/.docker.env
19 |
20 | # find /opt/docker -type d -exec chmod 0755 {} \;
21 | # find /opt/docker/compose -type f -exec chmod 0644 {} \;
22 |
23 | # function definitions
24 | fnc_help_compose_folders(){
25 | echo -e "${blu:?}[-> This script creates Docker configuration folders using the schema created by ${cyn:?}Drauku${blu:?} <-]${def:?}"
26 | echo -e " - ${blu:?}(modified from ${cyn:?}gkoerk's (RIP)${blu:?} famously awesome folder structure for stacks)${def:?}"
27 | echo -e " -"
28 | echo -e " - Enter up to nine(9) container_names in a single command, separated by a 'space' character: "
29 | echo -e " - SYNTAX: dcf ${cyn:?}appname1${def:?} ${cyn:?}appname2${def:?} ... ${cyn:?}appname9${def:?}"
30 | echo -e " - SYNTAX: dcf ${cyn:?}-option${def:?}"
31 | echo -e " - VALID OPTIONS:"
32 | echo -e " - ${cyn:?}-c │ --create ${def:?}│ ${grn:?}Creates${def:?} ${cyn:?}{docker_appdata,docker_compose}/${mgn:?}appname${def:?}"
33 | echo -e " - ${cyn:?}-d │ --delete ${def:?}│ ${red:?}Deletes${def:?} all sub-folders and files in ${cyn:?}{docker_appdata,docker_compose}/${mgn:?}appname${def:?}"
34 | # echo -e " - ${cyn:?}-r │ --replace ${def:?}│ ${ylw:?}Replace${def:?} all folders and files in ${cyn:?}{docker_appdata,docker_compose}/${mgn:?}appname${def:?}"
35 | echo -e " - ${cyn:?}-p │ --permissions ${def:?}│ ${blu:?}Updates${def:?} all folder permissions for listed ${mgn:?}appname(s)${def:?}"
36 | echo -e " - ${cyn:?}-h │ --help ${def:?}| Displays this help message."
37 | echo -e " -"
38 | echo -e " - NOTE: The below folder structure is created for each 'appname' entered with this command:"
39 | echo -e " - ${cyn:?}${docker_appdata:?}/${mgn:?}appname${def:?}"
40 | echo -e " - ${cyn:?}${docker_compose:?}/${mgn:?}appname${def:?}"
41 | # echo -e " - ${mgn:?}${compose_runtime}/${cyn:?}appname${def:?}"
42 | # echo -e " - ${mgn:?}/share/compose/secrets/${cyn:?}appname${def:?}"
43 | echo
44 | exit 1 # Exit script after printing help
45 | }
46 | case "$1" in ("-h"|*"help"*) fnc_help_compose_folders ;; esac
47 |
48 | fnc_script_intro(){ echo; } # echo -e "${blu:?}[- CREATE DOCKER COMPOSE FOLDER STRUCTURE FOR LISTED STACKS -]${def:?}"; }
49 | fnc_script_outro(){ echo; exit 1; }
50 | fnc_nothing_to_do(){ echo -e "${ylw:?} >> A valid option and container name must be entered for this command to work (use ${cyn:?}--help ${ylw:?}for info) <<${def:?}"; }
51 | fnc_invalid_input(){ echo -e "${ylw:?} >> INVALID INPUT${def:?}: Must be any case-insensitive variation of '(Y)es' or '(N)o'."; }
52 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE ${cyn:?}-help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}" && fnc_script_outro; }
53 | # fnc_compose_comment(){ echo "# '${stack}' docker config file created for a homelab environment - https://github.com/qnap-homelab\n\n"; }
54 | fnc_compose_comment(){ printf "# '%s' docker config file created for a homelab environment - https://github.com/qnap-homelab\n\n" "${stack}"; }
55 | fnc_confirm_remove(){ echo -e "${ylw:?}Are you sure you want to ${red:?}DELETE / REMOVE${ylw:?} files and folders for the ${blu:?}\"${1}\"${ylw:?} container?\n ${mgn:?}WARNING: ${red:?}THIS ACTION CANNOT BE UNDONE!${def:?}"; }
56 | # fnc_array_cleanup(){ folder_list=( $(for index in "${!args_list[@]}"; do echo -e "${args_list[$index + 1]}"; done) ); }
57 | # fnc_array_cleanup(){ while IFS=$'\n' read -r line; do folder_list+=("${line}"); done < <(for index in "${!args_list[@]}"; do echo -e "${args_list[${index} + 1]}"; done); }
58 | # fnc_file_search() { [[ $(find ./"${@}" -type f) ]]; }
59 | fnc_action_message(){ # call syntax: fnc_action_message "action" "color"
60 | echo -e " -> ${blu:?}${docker_appdata:?}/${mgn:?}${stack}${def:?} AND ${blu:?}${docker_compose:?}/${mgn:?}${stack}${def:?} FOLDERS AND FILES ${2:?} ${1:?}${def:?}";
61 | }
62 | fnc_check_env(){
63 | if [[ ! -f "${docker_scripts}/.vars_docker.env" ]];
64 | then install -o $var_uid -g $var_gid -m $appdata_permissions "${docker_scripts}/.vars_docker.example" "${docker_scripts}/.vars_docker.env";
65 | fi;
66 | }
67 | fnc_check_sudo(){
68 | if [[ $(id -u) -ne 0 ]];
69 | then var_sudo="$(command -v sudo 2>/dev/null) ";
70 | else unset var_sudo;
71 | fi; }
72 | fnc_permissions_update(){
73 | fnc_check_sudo;
74 | for stack in "${folder_list[@]}"; do
75 | if [[ "${1}" = "--all" ]]; then
76 | # ${var_sudo}find "${docker_appdata}" -type f -exec chmod ${appdata_permissions} {} + -o -type d -exec chmod ${folders_permissions} {} +
77 | # ${var_sudo}find "${docker_compose}" -type f -exec chmod ${compose_permissions} {} + -o -type d -exec chmod ${folders_permissions} {} +
78 | ${var_sudo}chmod -R a-rwx,ug=rwX "${docker_appdata:?}/${stack}";
79 | ${var_sudo}chmod -R a-rwx,ug=rwX,o=rX "${docker_compose:?}/${stack}";
80 | else
81 | ## appdata folder and file permissions
82 | # ${var_sudo}chmod -R "${appdata_permissions}" "${docker_appdata:?}/${stack}";
83 | # ${var_sudo}chmod "${folders_permissions}" "${docker_appdata:?}/${stack}";
84 | ${var_sudo}chown -R "${var_uid:-1000}:${var_gid:-1000}" "${docker_appdata:?}/${stack}";
85 | ${var_sudo}chmod -R a-x,ug=rwX,o= "${docker_appdata:?}/${stack}";
86 |
87 | ## compose folder and file permissions
88 | # ${var_sudo}chmod -R "${compose_permissions}" "${docker_compose:?}/${stack}";
89 | # ${var_sudo}chmod "${folders_permissions}" "${docker_compose:?}/${stack}";
90 | ${var_sudo}chown -R "${var_uid:-1000}:${var_gid:-1000}" "${docker_compose:?}/${stack}";
91 | ${var_sudo}chmod -R a-x,ug=rwX,o=rX "${docker_compose:?}/${stack}";
92 | fi
93 | if [[ "${stack}" = "[tT][rR][aA][eE][fF][iI][kK]" ]]; then ${var_sudo}chmod "${cert_permissions}" "${docker_appdata:?}/${stack}/certs/acme.json"; fi;
94 | done;
95 | # echo -e "\n ${ylw:?}UPDATED ${blu:?}${docker_appdata:?}/${mgn:?}${stack}${def:?} AND ${blu:?}${docker_compose:?}/${mgn:?}${stack}${def:?} FOLDERS AND FILE PERMISSIONS ${def:?}";
96 | fnc_action_message "FILE AND FOLDER PERMISSIONS UPDATED" "${ylw:?}"
97 | }
98 | fnc_folder_create(){
99 | exist=0;
100 | # echo;
101 | fnc_check_sudo;
102 | for stack in "${folder_list[@]}"; do
103 | if [ ! -d "${docker_appdata:?}/${stack}/" ];
104 | then ${var_sudo}install -o "${var_uid:-1000}" -g "${var_gid:-1000}" -m "${folders_permissions}" -d "${docker_appdata:?}/${stack}";
105 | else fnc_permissions_update "${folder_list[@]}"; fnc_action_message "ALREADY EXISTS" "${blu:?}${docker_appdata:?}/${mgn:?}${stack}${def:?}"; exist=1; # ((++exist));
106 | fi;
107 | if [ ! -f "${docker_appdata:?}/${stack}/${stack}.log" ];
108 | then ${var_sudo}install -m "${appdata_permissions}" /dev/null "${docker_appdata:?}/${stack}/${stack}-logs.yml";
109 | else fnc_action_message "ALREADY EXISTS" "${blu:?}${docker_appdata:?}/${mgn:?}${stack}${cyn:?}/${stack}-logs.yml${def:?}";
110 | fi;
111 | if [[ "${stack}" = "[tT][rR][aA][eE][fF][iI][kK]" ]] && [ ! -f "${docker_appdata:?}/${stack}/certs/acme.json" ];
112 | then ${var_sudo}install -m "${cert_permissions}" /dev/null "${docker_appdata:?}/${stack}/certs/acme.json";
113 | # then touch "${docker_appdata:?}/${stack}/certs/acme.json" && ${var_sudo}chmod "${cert_permissions}" "${docker_appdata:?}/${stack}/certs/acme.json";
114 | # else echo -e " ${ylw:?}ALREADY EXISTS${def:?} > ${blu:?}${docker_appdata:?}/${mgn:?}${stack}${cyn:?}/certs/acme.json${def:?}";
115 | fi;
116 | if [ ! -d "${docker_compose:?}/${stack}/" ];
117 | then ${var_sudo}install -o "${var_uid:-1000}" -g "${var_gid:-1000}" -m "${folders_permissions}" -d "${docker_compose:?}/${stack}";
118 | if [ ! -f "${docker_compose:?}/${stack}/.env" ]; then ln -s "${var_script_vars:?}" "${docker_compose:?}/${stack}/.env"; fi;
119 | else fnc_permissions_update "${folder_list[@]}";
120 | echo -e " ${ylw:?}ALREADY EXISTS ${def:?}-> ${blu:?}${docker_compose:?}${mgn:?}/${stack}${def:?}"; exist=1; # ((++exist));
121 | fi;
122 | if [ ! -f "${docker_compose:?}/${stack}/compose.yml" ];
123 | then ${var_sudo}install -o "${var_uid:-1000}" -g "${var_gid:-1000}" -m "${compose_permissions}" /dev/null "${docker_compose:?}/${stack}/compose.yml";
124 | # then touch "${docker_compose:?}/${stack}/compose.yml" && ${var_sudo}chmod "${compose_permissions}" "${docker_compose:?}/${stack}/compose.yml";
125 | # { printf "# '%s' docker config file created for a homelab environment - https://github.com/qnap-homelab\n\n" "${stack}";
126 | { fnc_compose_comment; } >> "${docker_compose:?}/${stack}/compose.yml";
127 | else echo -e " ${ylw:?}ALREADY EXISTS ${def:?}-> ${blu:?}${docker_compose:?}/${mgn:?}${stack}${cyn:?}/compose.yml${def:?}";
128 | fi;
129 | [ "${exist}" == "0" ] && fnc_action_message "CREATED" "${grn:?}";
130 | # echo "UID:${var_uid} GID:${var_gid}"; echo;
131 | # ${var_sudo}chown -R "${var_uid:-1000}:${var_gid:-1000}" "${docker_compose:?}/${stack}"
132 | # ${var_sudo}chown -R "${var_uid:-1000}:${var_gid:-1000}" "${docker_appdata:?}/${stack}"
133 | done
134 | }
135 | # fnc_folder_remove_message(){ echo -e " > ${red:?}REMOVED ${blu:?}${docker_compose:?}/${stack}${def:?} AND ${blu:?}${docker_appdata:?}/${mgn:?}${stack}${def:?} FOLDERS AND FILES ${def:?}"; }
136 | fnc_folder_remove(){
137 | exist=1; fnc_confirm_remove "${*}" ;
138 | while read -r -p " [(Y)es/(N)o] " input; do
139 | case "${input}" in
140 | ([yY]|[yY][eE][sS])
141 | echo;
142 | for stack in "${folder_list[@]}"; do
143 | if [ -d "${docker_appdata:?}/${stack}" ]; then
144 | ${var_sudo}rm -rf "${docker_appdata:?}/${stack:?}" #&& echo -e " > ${red:?}REMOVED ${mgn:?}${stack} ${def:?}APPDATA FOLDER AND FILES ${def:?}";
145 | else echo -e " -> ${ylw:?} INFO: ${blu:?}${docker_appdata:?}${mgn:?}/${stack} ${ylw:?}NOT FOUND ${def:?}"; exist=0;
146 | fi
147 | if [ -d "${docker_compose:?}/${stack}" ]; then
148 | ${var_sudo}rm -rf "${docker_compose:?}/${stack:?}" #&& echo -e " > ${red:?}REMOVED ${mgn:?}${stack} ${def:?}COMPOSE FOLDER AND FILES ${def:?}";
149 | else echo -e " -> ${ylw:?} INFO: ${blu:?}${docker_compose:?}${mgn:?}/${stack} ${ylw:?}NOT FOUND ${def:?}"; exist=0;
150 | fi
151 | [ "${exist}" == "1" ] && fnc_action_message "REMOVED" "${red:?}";
152 | done
153 | break
154 | ;;
155 | ([nN]|[nN][oO]) break ;;
156 | (*) fnc_invalid_input ;;
157 | esac
158 | done
159 | }
160 | # fnc_folder_clean_message(){ echo -e " > ${ylw:?}CLEANED ${mgn:?}${stack} ${def:?}${content} ${def:?}"; }
161 | # fnc_folder_clean(){
162 | # unset content IFS;
163 | # fnc_confirm_remove;
164 | # while read -r -p " [(Y)es/(N)o] " input; do
165 | # case "${input}" in
166 | # ([yY]|[yY][eE][sS])
167 | # echo;
168 | # case "${folder_list[0]}" in
169 | # ("-a") ${var_sudo}rm -rf "${docker_appdata:?}/${stack:?}"/* && content="CONTAINER APPDATA" ;;
170 | # ("-g") ${var_sudo}rm -rf "${docker_compose:?}/${stack:?}"/* && content="CONTAINER CONFIGS" ;;
171 | # ("-w") ${var_sudo}rm -rf "${docker_swarm:?}/${stack:?}"/* && content="SWARM CONFIGS" ;;
172 | # esac
173 | # [ ! "${content}" == "" ] && fnc_folder_clean_message;
174 | # ;;
175 | # ([nN]|[nN][oO]) break ;;
176 | # (*) fnc_invalid_input ;;
177 | # esac
178 | # done
179 | # }
180 |
181 | # script startup checks
182 | fnc_script_intro
183 | fnc_check_sudo
184 | fnc_check_env
185 |
186 | # output determination logic
187 | case "${1}" in
188 | ("") fnc_nothing_to_do ;;
189 | (-*) # validate and perform option
190 | case "${1}" in
191 | ("-c"|"--create")
192 | unset "folder_list[0]";
193 | fnc_folder_create "${folder_list[*]}";
194 | ;;
195 | ("-d"|"--delete"|"-r"|"--remove")
196 | unset "folder_list[0]";
197 | fnc_folder_remove "${folder_list[*]}";
198 | ;;
199 | # ("-a"|"--appdata")
200 | # unset "folder_list[0]";
201 | # fnc_folder_clean -a "${folder_list[*]}";
202 | # ;;
203 | # ("-g"|"--configs")
204 | # unset "folder_list[0]";
205 | # fnc_folder_clean -g "${folder_list[*]}";
206 | # ;;
207 | # ("-s"|"-w"|"--swarm")
208 | # unset "folder_list[0]";
209 | # fnc_folder_clean -w "${folder_list[*]}";
210 | # ;;
211 | ("-p"|"-u"|"--perms"|"--update")
212 | case "${2}" in
213 | ("")
214 | unset "folder_list[0]";
215 | folder_list=( "$(IFS=$'\n'; cd "${docker_compose:?}" && find . -type d -not -path '*/\.*' | sed 's/^\.\///g')" )
216 | fnc_permissions_update "${folder_list[@]}";
217 | esac
218 | unset "folder_list[0]";
219 | fnc_permissions_update "${folder_list[@]}";
220 | ;;
221 | ("-r"|"--replace")
222 | unset "folder_list[0]";
223 | fnc_folder_remove "${folder_list[*]}";
224 | fnc_folder_create "${folder_list[*]}";
225 | ;;
226 | (*)
227 | fnc_invalid_syntax;
228 | ;;
229 | esac
230 | ;;
231 | (*) # default to create folder structure
232 | folder_list=("${@}");
233 | fnc_folder_create "${folder_list[*]}";
234 | ;;
235 | esac
236 |
237 | fnc_script_outro
--------------------------------------------------------------------------------
/docker_compose_function.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | ################################################################################
3 | ######### --> **** UPDATE THESE VARIABLES FOR YOUR ENVIRONMENT **** <-- ########
4 |
5 | export docker_usr="docker"
6 | export docker_grp="docker"
7 | export docker_dir="$HOME/docker"
8 |
9 | ################################################################################
10 | ##################### NOTHING BELOW HERE SHOULD BE CHANGED #####################
11 | ################################################################################
12 |
13 | ################################################################################
14 | ####################### docker uid/gid/directories setup #######################
15 |
16 | # alias to easily source this file
17 | alias dkfnc='. $ln_source'
18 |
19 | # docker directory structure
20 | export docker_appdata="$docker_dir/appdata"
21 | export docker_compose="$docker_dir/compose"
22 | export docker_secrets="$docker_dir/secrets"
23 | export docker_swarm="$docker_dir/swarm"
24 |
25 | ## assign docker UID and GID variables
26 | docker_uid=$(id -u "$docker_usr") # docker UID (1000)
27 | export docker_uid #&& echo "DEBUG: docker UID: $docker_uid"
28 | docker_gid=$(id -g "$docker_usr") # docker GID (1000)
29 | export docker_gid #&& echo "DEBUG: docker GID: $docker_gid"
30 |
31 | # folder and file permissions
32 | export perms_cert="a-rwx,u=rwX,g=,o=" # 600 # -rw-rw----
33 | export perms_conf="a-rwx,u+rwX,g=rwX,o=rX" # 664 # -rw-rw-r--
34 | export perms_data="a-rwx,u+rwX,g=rwX,o-rX" # 660 # -rw-rw----
35 | # export dk_dir="" # 775 # -rwxrwxr-x
36 |
37 | # check if sudo is needed for some commands used in these custom docker functions
38 | if [[ $(id -u) -ne 0 ]]; then var_sudo="$(command -v sudo 2>/dev/null) "; else unset var_sudo; fi;
39 |
40 | # create the $HOME/.docker_fnc symlink if it does not exist
41 | ln_source="$HOME/.docker_fnc"
42 | ln_target="$docker_dir/docker_functions"
43 | if [[ ! -f "$ln_source" ]]; then ln -s "$ln_target" "$ln_source"; fi;
44 |
45 | # create docker directory structure and .docker.env if they don't exist
46 | if [[ ! -d "$docker_appdata" ]]; then ${var_sudo}install -o "$docker_uid" -g "$docker_gid" -m "$perms_data" -d "$docker_dir/appdata"; fi
47 | if [[ ! -d "$docker_compose" ]]; then ${var_sudo}install -o "$docker_uid" -g "$docker_gid" -m "$perms_conf" -d "$docker_dir/compose"; fi
48 | if [[ ! -d "$docker_secrets" ]]; then ${var_sudo}install -o "$docker_uid" -g "$docker_gid" -m "$perms_data" -d "$docker_dir/secrets"; fi
49 | # if [[ ! -d "$docker_stacks" ]]; then ${var_sudo}install -o "$docker_uid" -g "$docker_gid" -m "$perms_conf" -d "$docker_dir/stacks"; fi
50 | if [[ ! -d "$docker_swarm" ]]; then ${var_sudo}install -o "$docker_uid" -g "$docker_gid" -m "$perms_conf" -d "$docker_dir/swarm"; fi
51 |
52 | # check if docker.env exists and download if it doesn't otherwise create a blank .docker.env
53 | docker_env_url="https://raw.githubusercontent.com/drauku/bash-scripts/master/docker.env.example"
54 | docker_env_example="$docker_dir/docker.env.example"
55 | docker_env="$docker_dir/.docker.env"
56 | if [[ ! -f "$docker_env" ]]; then
57 | if [[ ! -f "$docker_env_example" ]]; then
58 | if ! wget $docker_env_url -O "$docker_env_example"; then
59 | echo "ERROR: Failed to download $docker_env_url";
60 | ${var_sudo}install -o "$docker_uid" -g "$docker_gid" -m "$perms_data" /dev/null "$docker_env";
61 | fi;
62 | else
63 | ${var_sudo}install -o "$docker_uid" -g "$docker_gid" -m "$perms_data" "$docker_env_example" "$docker_env";
64 | fi
65 | fi;
66 |
67 | ################################################################################
68 | ########################### general docker functions ###########################
69 |
70 | lda(){ echo "ls $docker_appdata"; ls "$docker_appdata"; echo; }
71 | appdata(){ cd "$docker_appdata/$1" || echo; return; }
72 | alias dka="appdata"
73 | ldc(){ echo "ls $docker_compose"; ls "$docker_compose"; echo; }
74 | compose(){ cd "$docker_compose/$1" || echo; return; }
75 | alias dkc="compose"
76 | lds(){ echo "ls $docker_secrets"; ls "$docker_secrets"; echo; }
77 | secrets(){ cd "$docker_secrets/$1" || echo; return; }
78 | alias dks="secrets"
79 | ldw(){ echo "ls $docker_swarm"; ls "$docker_swarm"; echo; }
80 | swarm(){ cd "$docker_swarm/$1" || echo; return; }
81 | alias dkw="swarm"
82 |
83 | vpncheck(){ echo " > Host IP: $(wget -qO- ifconfig.me)" && echo "Container IP: $(docker container exec -it "${*}" wget -qO- ipinfo.io)"; }
84 | ipcheck(){ echo " > Container IP: $(docker container exec -it "${*}" curl ipinfo.io)"; }
85 |
86 | fnc_check_app(){ if [[ "$1" == "" ]]; then echo; echo " > Application name must be specified. Nothing to do."; echo; return; fi; }
87 | fnc_check_dir(){ if [[ ! -d "$1" ]]; then echo -e " > \`$1\` docker container directory does not exist <"; return 1; fi; }
88 |
89 | fnc_appname_validate(){
90 | if [[ ${1:0:1} =~ ^[_-]+$ ]] || [[ ! ${1} =~ ^[a-zA-Z0-9_-]+$ ]];
91 | then echo -e " > \`$1\` is an invalid docker container name <"; return 1;
92 | else return 0; # container name only contains valid characters
93 | fi;
94 | }
95 |
96 | fnc_verify_action(){
97 | while read -r -p "$2" input; do
98 | case "${input:-N}" in
99 | ([yY]|[yY][eE][sS]) return 0; ;;
100 | ([nN]|[nN][oO]) return 1; ;;
101 | (*) echo -e " > invalid input <"; return 1; ;;
102 | esac
103 | done
104 | }
105 |
106 | docker_file_permissions(){
107 | case "${1}" in
108 | ("-a"|"--all") # update all docker file permissions
109 | files_dir="${configs_dir}" ;;
110 | (*) # update specific docker file permissions
111 | files_dir="${configs_dir}/${1}" ;;
112 | esac
113 | # update restricted access file permissions to 600
114 | files_restricted=("acme.json" "*.crt" "*.key" "*.pub" "*.ppk" "*.pem");
115 | for file in "${files_restricted[@]}"; do
116 | ${var_sudo}find "$files_dir" -iname "$file" -type f -exec chmod "$perms_cert" {} +
117 | done
118 | # update limited access file permissions to 660
119 | files_limited=(".conf" "*.env" ".log" "*.secret");
120 | for file in "${files_limited[@]}"; do
121 | ${var_sudo}find "$files_dir" -iname "$file" -type f -exec chmod "$perms_data" {} +
122 | done
123 | # # update general access file permissions to 664
124 | # files_general=("*.yml" "*.yaml" "*.toml");
125 | # for file in "${files_general[@]}"; do
126 | # ${var_sudo}find "$docker_dir" -iname "$file" -type f -exec chmod "$perms_conf" {} +
127 | # done
128 | }
129 | docker_folder_permissions(){
130 | fnc_check_app "$1";
131 | for stack in ${1}; do
132 | case "${stack}" in
133 | ("-a"|"--all") # update all docker folder permissions
134 | ${var_sudo}chown -R "${docker_uid}:${docker_gid}" "${docker_dir:?}";
135 | ${var_sudo}chmod -R "${perms_data}" "${docker_appdata:?}"; # -rwXrwX---
136 | ${var_sudo}chmod -R "${perms_conf}" "${docker_compose:?}"; # -rwXrwXr-X
137 | ${var_sudo}chmod -R "${perms_data}" "${docker_secrets:?}"; # -rwXrwX---
138 | ${var_sudo}chmod -R "${perms_conf}" "${docker_swarm:?}"; # -rwXrwXr-X
139 | docker_file_permissions --all;
140 | echo -e " > \`ALL\` docker subdirectory and file permissions updated <"
141 | ;;
142 | (*) # update specified docker folder permissions
143 | appdata_dir="${docker_appdata:?}/${stack}";
144 | appconf_dir="${configs_dir:?}/${stack}";
145 | if [[ ! -d "${appconf_dir:?}" ]]; then echo -e " > \`${appconf_dir:?}\` docker container directory does not exist <"; return; fi;
146 | ## appdata folder and file permissions
147 | ${var_sudo}chown -R "${docker_uid}:${docker_gid}" "${appdata_dir:?}";
148 | ${var_sudo}chmod -R "${perms_data}" "${appdata_dir:?}";
149 | ## compose folder and file permissions
150 | ${var_sudo}chown -R "${docker_uid}:${docker_gid}" "${appconf_dir:?}";
151 | ${var_sudo}chmod -R "${perms_conf}" "${appconf_dir:?}";
152 | # echo -e "\n ${ylw:?}UPDATED ${blu:?}${docker_appdata:?}/${mgn:?}${stack}${def:?} AND ${blu:?}${docker_compose:?}/${mgn:?}${stack}${def:?} FOLDERS AND FILE PERMISSIONS ${def:?}";
153 | docker_file_permissions "${stack}";
154 | echo -e " > \`${stack}\` docker container subdirectory and file permissions updated <";
155 | ;;
156 | esac
157 | done;
158 | }
159 |
160 | docker_env_create(){
161 | case "${1}" in
162 | "-c"|"--copy"|"-f"|"--force") # force copy .docker.env.example to .docker.env
163 | ${var_sudo}install -o "$docker_uid" -g "$docker_gid" -m "$perms_data" "$docker_env" "$configs_dir/$2/.env";
164 | ;;
165 | *) # symlink .env to .docker.env.example if it does not exist
166 | if [[ ! -f "$configs_dir/$1/.env" ]]; then
167 | ln -s "$docker_env" "$configs_dir/$1/.env"; # symlinks .env to .docker.env
168 | fi
169 | ;;
170 | esac
171 | }
172 |
173 | docker_folders_create(){
174 | fnc_check_app "$1";
175 | docheck=0;
176 | if [[ -d "$configs_dir/$1" ]]; then docheck=$((docheck + 1));
177 | else # create docker container config directories and files
178 | # if [[ $1 =~ ^[compose]+$ ]];
179 | # then export configs_dir="$docker_compose";
180 | # elif [[ $1 =~ ^[swarm]+$ ]];
181 | # then export configs_dir="$docker_swarm";
182 | # fi;
183 | if fnc_appname_validate "$1"; then
184 | # echo -e " > Creating directories and files for the \` $configs_dir/$1 \` container <"; echo;
185 | ${var_sudo}install -o "$docker_uid" -g "$docker_gid" -m "$perms_conf" -d "$configs_dir/$1";
186 | ${var_sudo}install -o "$docker_uid" -g "$docker_gid" -m "$perms_conf" /dev/null "$configs_dir/$1/compose.yml";
187 | docker_env_create "$1";
188 | echo " > Docker config directories and files created for the \`$1\` application.";
189 | fi;
190 | fi;
191 | if [[ -d "$docker_appdata/$1" ]]; then docheck=$((docheck + 2));
192 | else # create docker container data directory
193 | if fnc_appname_validate "$1"; then
194 | ${var_sudo}install -o "$docker_uid" -g "$docker_gid" -m "$perms_data" -d "$docker_appdata/$1";
195 | echo " > Docker appdata directory created for the \`$1\` application.";
196 | fi;
197 | fi;
198 | case "$docheck" in
199 | "1") echo " > Docker config directory for \`$configs_dir/$1\` already exists.";;
200 | "2") echo " > Docker data directory for \`$docker_appdata/$1\` already exists.";;
201 | "3") echo " > Docker config and data directories for the \`$1\` application already exist.";;
202 | esac
203 | echo
204 | }
205 | docker_folders_delete(){
206 | if ! fnc_verify_action "$1" " > This will forcefully delete all \`$1\` application directories and files. Continue? [y/N] "; then return; fi; echo;
207 | fnc_check_app "$1";
208 | docheck=0;
209 | if [[ -d "${docker_appdata:?}/$1" ]];
210 | then
211 | rm -rf "${docker_appdata:?}/$1"; #docheck=$((docheck+1));
212 | echo " > \`${docker_appdata:?}/$1\` and contents deleted.";
213 | else echo " > \`$docker_appdata/$1\` does not exists. Nothing to remove."; echo;
214 | fi;
215 | if [[ -d "${configs_dir:?}/$1" ]];
216 | then
217 | rm -rf "${configs_dir:?}/$1"; #docheck=$((docheck+1));
218 | echo " > \`${configs_dir:?}/$1\` and contents deleted.";
219 | else echo " > \`$configs_dir/$1\` does not exists. Nothing to remove."; echo;
220 | fi;
221 | # if [[ $configs_dir =~ ^[compose]+$ ]]; then
222 | # if [[ -d "$docker_compose/$1" ]];
223 | # # then rm -rf "${docker_compose:?}/$1";
224 | # then echo "DEBUG: rm -rf ${docker_compose:?}/$1";
225 | # else echo " > \`$1\` does not exists. Nothing to remove."; echo;
226 | # fi;
227 | # fi;
228 | # if [[ $configs_dir =~ ^[swarm]+$ ]]; then
229 | # if [[ -d "$docker_swarm/$1" ]];
230 | # # then rm -rf "${docker_swarm:?}/$1";
231 | # then echo "DEBUG: rm -rf ${docker_swarm:?}/$1";
232 | # else echo " > \`$1\` does not exists. Nothing to remove."; echo;
233 | # fi;
234 | # fi;
235 | # if [[ $docheck -eq 0 ]]; then echo " > \`$1\` docker container subdirectories and files deleted."; echo; fi;
236 | echo;
237 | }
238 | docker_folder_actions(){
239 | case "$1" in
240 | -*) # perform optional action
241 | case "$1" in
242 | "-c"|"--create") docker_folders_create "$2" ;;
243 | "-d"|"--delete") docker_folders_delete "$2" ;;
244 | "-r"|"--remove") docker_folders_delete "$2" ;;
245 | *) echo " > Invalid option \`$1\` used."; echo;
246 | esac
247 | ;;
248 | *) docker_folders_create "$@" ;;
249 | esac;
250 | }
251 |
252 | ################################################################################
253 | ########################### docker compose functions ###########################
254 |
255 | docker_list_containers(){
256 | case "$1" in
257 | "-a"|"--all")
258 | docker container list --all --format "table {{.ID}} {{.Names}}\t{{.Status}}\t{{.RunningFor}}\t{{.Image}}";;
259 | "-l"|"--labels")
260 | docker container list --no-trunc --format "table {{.Names}}\t{{.Status}}\t{{.Labels}}\t{{.Command}}";;
261 | "-n"|"--networks")
262 | docker container list --no-trunc --format "table {{.Names}}\t{{.Status}}\t{{.Networks}}\t{{.Ports}}";;
263 | "-v"|"--volumes")
264 | docker container list --no-trunc --format "table {{.Names}}\t{{.Status}}\t{{.LocalVolumes}}\t{{.Mounts}}";;
265 | *)
266 | docker container list --format "table {{.ID}} {{.Names}}\t{{.Status}}\t{{.Image}}\t{{.Command}}";;
267 | esac
268 | }
269 | alias dlc="docker_list_containers" # "docker list containers"
270 | alias dll="docker_list_containers" # "docker list local apps"
271 |
272 | docker_compose_folders(){
273 | export configs_dir="$docker_compose";
274 | docker_folder_actions "$@";
275 | }
276 | alias dcf='docker_compose_folders'
277 |
278 | docker_compose_env(){
279 | export configs_dir="$docker_compose";
280 | docker_env_create "$@";
281 | }
282 | alias dcenv='docker_compose_env'
283 |
284 | docker_compose_permissions(){
285 | export configs_dir="$docker_compose";
286 | docker_folder_permissions "$1";
287 | }
288 | alias dcp="docker_compose_permissions"
289 |
290 | docker_compose_edit(){ nano "$docker_compose/$1/compose.yml"; }
291 | alias dce="docker_compose_edit"
292 |
293 | docker_compose_config(){ docker compose -f "$docker_compose/$1/compose.yml" config; }
294 | alias dcc="docker_compose_config"
295 | alias dct="docker_compose_config"
296 |
297 | docker_compose_logs(){ (cd "$docker_compose/$1" && docker compose logs -f); }
298 | alias dcl="docker_compose_logs"
299 |
300 | docker_compose_networks(){
301 | docker network create --driver "bridge" --opt "encrypted" --scope "local" --subnet "172.20.0.0/16" --gateway "172.20.0.254" --attachable "docker_socket"
302 | docker network create --driver "bridge" --opt "encrypted" --scope "local" --subnet "172.21.1.0/16" --gateway "172.21.0.254" --attachable "external_edge"
303 | docker network create --driver "bridge" --opt "encrypted" --scope "local" --subnet "172.22.2.0/16" --gateway "172.22.0.254" --attachable "reverse_proxy"
304 | echo "The \`docker_socket\`, \`external_edge\`, and \`reverse_proxy\` docker bridge networks exist or were created."; echo
305 | }
306 | alias dcn="docker_compose_networks"
307 |
308 | docker_list_networks(){ docker network ls; }
309 | alias dln="docker_list_networks"
310 |
311 | fnc_strip_option(){ export applist=( "${applist[@]:1}" ); } # remove first element
312 |
313 | docker_compose_start(){
314 | applist=( "$*" )
315 | export configs_dir="$docker_compose";
316 | fnc_compose_start(){
317 | for app in "$@"; do
318 | if [[ -f "$docker_compose/$app/compose.yml" ]]; then
319 | docker_env_create "$app";
320 | docker compose -f "$docker_compose/$app/compose.yml" up -d --remove-orphans;
321 | else echo " > No docker compose configuration file found for the \`$app\` application.";
322 | fi;
323 | done
324 | echo;
325 | }
326 | case "$1" in
327 | -*) # perform optional action
328 | case "$1" in
329 | "-l"|"--logs")
330 | fnc_strip_option "$@"
331 | fnc_compose_start "${applist[@]}"
332 | docker_compose_logs "${2:-${applist[1]}}";
333 | ;;
334 | *) echo "Invalid option: \`$1\`"; echo;
335 | esac
336 | ;;
337 | *)
338 | fnc_compose_start "${applist[@]}"
339 | ;;
340 | esac
341 | }
342 | alias dcu="docker_compose_start"
343 |
344 | docker_compose_stop(){
345 | if [[ -f "$docker_compose/$1/compose.yml" && -f "$docker_compose/$1/.env" ]]
346 | then docker compose -f "$docker_compose/$1/compose.yml" down;
347 | else docker stop "$1" && docker container rm "$1"
348 | fi
349 | echo
350 | }
351 | alias dcd="docker_compose_stop"
352 |
353 | docker_compose_bounce(){ docker_compose_stop "$1" && docker_compose_start "$1" ; }
354 | alias dcb="docker_compose_bounce"
355 |
356 | # echo -e "\n>> docker compose aliases and functions created <<";
357 |
358 | ################################################################################
359 | ############################ docker swarm functions ############################
360 |
361 | docker_list_stacks(){
362 | case "$1" in
363 | "-a"|"--all")
364 | docker stack ls;;
365 | *)
366 | docker stack ls --format "table {{.Name}}\t{{.Description}}";;
367 | esac
368 | }
369 | alias dls="docker_list_stacks" # "docker list stacks"
370 | alias dlw="docker_list_stacks" # "docker list swarm apps"
371 |
372 | docker_swarm_folders(){
373 | export configs_dir="$docker_swarm";
374 | docker_folder_actions "$@";
375 | }
376 | alias dwf="docker_swarm_folders"
377 |
378 | docker_swarm_env(){
379 | export configs_dir="$docker_swarm";
380 | docker_env_create "$@";
381 | }
382 | alias dwenv="docker_swarm_env"
383 |
384 | docker_swarm_permissions(){
385 | export configs_dir="$docker_swarm";
386 | docker_folder_permissions "$1";
387 | }
388 | alias dwp="docker_swarm_permissions"
389 |
390 | docker_swarm_edit(){ nano "$docker_swarm/$1/compose.yml"; }
391 | alias dwe="docker_swarm_edit"
392 |
393 | docker_swarm_config(){ docker compose -f "$docker_swarm/$1/compose.yml" config; }
394 | alias dwc="docker_swarm_config"
395 | alias dwt="docker_swarm_config"
396 |
397 | docker_swarm_logs(){ (cd "$docker_swarm/$1" && docker compose logs -f); }
398 | alias dwl="docker_swarm_logs"
399 |
400 | docker_swarm_networks(){
401 | docker network create --driver "overlay" --opt "encrypted" --scope "swarm" --subnet "172.20.0.0/16" --gateway "172.20.0.254" --attachable "docker_socket"
402 | docker network create --driver "overlay" --opt "encrypted" --scope "swarm" --subnet "172.21.0.0/16" --gateway "172.21.0.254" --attachable "external_edge"
403 | docker network create --driver "overlay" --opt "encrypted" --scope "swarm" --subnet "172.22.0.0/16" --gateway "172.22.0.254" --attachable "reverse_proxy"
404 | echo "The \`docker_socket\`, \`external_edge\`, and \`reverse_proxy\` docker overlay networks exist or were created."; echo
405 | }
406 | alias dwn="docker_swarm_networks"
407 |
408 | docker_swarm_start(){
409 | if [[ -f "$docker_swarm/$1/compose.yml" ]]; then
410 | docker_env_create "$1";
411 | docker stack deploy "${1}" -c "${docker_swarm}/${1}/compose.yml" --prune;
412 | else echo "No docker swarm configuration file found for the \`$1\` application.";
413 | fi;
414 | echo;
415 | }
416 | alias dwu="docker_swarm_start"
417 |
418 | docker_swarm_stop(){
419 | if [[ -f "$docker_swarm/$1/compose.yml" && -f "$docker_swarm/$1/.env" ]]
420 | then docker compose -f "$docker_swarm/$1/compose.yml" down;
421 | else docker stop "$1" && docker container rm "$1"
422 | fi
423 | echo
424 | }
425 | alias dwd="docker_swarm_stop"
426 |
427 | docker_swarm_bounce(){ docker_swarm_stop "$1" && docker_swarm_start "$1" ; }
428 | alias dwb="docker_swarm_bounce"
429 |
430 | docker_list_swarm_nodes(){ docker node ls -q | xargs docker node inspect -f '{{ .ID }} [hostname={{ .Description.Hostname }}, Addr={{ .Status.Addr }}, State={{ .Status.State }}, Role={{ .Spec.Role }}, Availability={{ .Spec.Availability }}]: Arch={{ .Description.Platform.Architecture }}, OS={{ .Description.Platform.OS }}, NanoCPUs={{ .Description.Resources.NanoCPUs }}, MemoryBytes={{ .Description.Resources.MemoryBytes }}, docker_version={{ .Description.Engine.EngineVersion }}, labels={{ range $k, $v := .Spec.Labels }}{{ $k }}={{ $v }} {{end}}'; }
431 | alias dkwn="docker_list_swarm_nodes"
432 |
433 | # echo -e "\n>> docker swarm aliases and functions created <<"; echo;
434 |
435 | ################################################################################
436 |
437 | echo -e "\n>> docker aliases and functions created <<"; echo;
--------------------------------------------------------------------------------
/docker_compose_logs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # function definitions
7 | fnc_help_compose_logs(){
8 | echo -e "${blu:?}[-> # This script displays 50 log entries for the indicated docker compose container. <-]${def:?}"
9 | echo -e " -"
10 | echo -e " - SYNTAX: # dcl ${cyn:?}container_name${def:?}"
11 | echo -e " - SYNTAX: # dcl ${cyn:?}-option${def:?}"
12 | echo -e " - VALID OPTIONS:"
13 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message."
14 | echo
15 | exit 1 # Exit script after printing help
16 | }
17 | case "$1" in ("-h"|*"help"*) fnc_help_compose_logs ;; esac
18 |
19 | fnc_script_intro(){ echo -e "${blu:?}[-> LISTING THE 50 MOST RECENT DOCKER COMPOSE LOG ENTRIES <-]${def:?}"; }
20 | fnc_script_outro(){ echo -e "${grn:?}[-- MOST RECENT 50 LOG ENTRIES LISTED --]${def:?}"; echo; }
21 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> no log entries to display${def:?}"; }
22 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
23 | fnc_compose_logs(){ docker compose logs -tf --tail="50" "${docker_compose}/${1}/compose.yml"; }
24 |
25 | # option logic action determination
26 | case "${1}" in
27 | (-*) # validate entered option exists
28 | case "${1}" in
29 | (*) echo -e "${ylw:?} >> INVALID OPTION SYNTAX -- USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1 ;;
30 | esac
31 | ;;
32 | (*) fnc_script_intro;
33 | if [ "$(fnc_compose_logs)" ]
34 | then fnc_compose_logs "${1}"
35 | else fnc_nothing_to_do
36 | fi
37 | echo
38 | ;;
39 | esac
40 |
--------------------------------------------------------------------------------
/docker_compose_networks.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # function definitions
7 | fnc_help(){
8 | echo -e "${blu:?}[- This script creates Docker ${blu:?}networks${def:?} required for compose and swarm containers by ${cyn:?}Drauku${blu:?} -]${def:?}"
9 | echo -e " - ${blu:?}(modified from ${cyn:?}gkoerk's (RIP)${blu:?} famously awesome networks for stacks)${def:?}"
10 | echo -e " -"
11 | echo -e " - SYNTAX: dnc ${cyn:?}-option${def:?}"
12 | echo -e " - VALID OPTIONS:"
13 | echo -e " - ${cyn:?}-c │ --create ${def:?}│ ${grn:?}Creates${def:?} the ${blu:?}{netproxy,netsocket}${def:?} docker networks"
14 | echo -e " - ${cyn:?}-d │ --delete ${def:?}│ ${red:?}Deletes${def:?} the ${blu:?}{netproxy,netsocket}${def:?} docker networks"
15 | echo -e " - ${cyn:?}-l │ --list ${def:?}│ ${red:?}Lists${def:?} the current docker networks"
16 | echo
17 | }
18 | case "${1}" in ("-h"|*"help"*) fnc_help ;; esac
19 | fnc_script_intro(){ echo -e "${blu:?}[- CREATE DOCKER NETWORKS REQUIRED FOR USE WITH DOCKER SOCKET AND A REVERSE PROXY -]${def:?}"; }
20 | fnc_script_outro(){ echo -e "${grn:?} - DOCKER NETWORKS '${var_net_rproxy} & ${var_net_socket}' CREATED${def:?}"; echo; exit 1; }
21 | fnc_nothing_to_do(){ echo -e "${ylw:?} >> A valid option and container name(s) must be entered for this command to work (use ${cyn:?}--help ${ylw:?}for info)${def:?}"; }
22 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE ${cyn:?}-help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; echo; exit 1; }
23 | fnc_invalid_input(){ echo -e "${ylw:?}INVALID INPUT${def:?}: Must be any case-insensitive variation of '(Y)es' or '(N)o'."; }
24 |
25 | fnc_create_networks() {
26 | docker network create --driver "bridge" --opt "encrypted" --scope "local" --subnet "172.27.0.0/24" --gateway "172.27.0.254" --attachable "docker_socket"
27 | docker network create --driver "bridge" --opt "encrypted" --scope "local" --subnet "172.27.1.0/24" --gateway "172.27.1.254" --attachable "external_edge"
28 | docker network create --driver "bridge" --opt "encrypted" --scope "local" --subnet "172.27.2.0/24" --gateway "172.27.2.254" --attachable "reverse_proxy"
29 | }
30 | fnc_delete_networks() {
31 | docker network rm "docker_socket"
32 | docker network rm "external_edge"
33 | docker network rm "reverse_proxy"
34 | }
35 | fnc_list_networks() {
36 | docker network ls
37 | }
38 |
39 | case "${1}" in
40 | "-c"|"--create")
41 | fnc_create_networks ;;
42 | "-d"|"--delete")
43 | fnc_delete_networks ;;
44 | "-l"|"--list"|"")
45 | fnc_list_networks ;;
46 | *)
47 | fnc_nothing_to_do ;;
48 | esac
--------------------------------------------------------------------------------
/docker_compose_start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # script variable definitions
7 | unset stacks_list IFS
8 | bounce_list=""
9 |
10 | # function definitions
11 | fnc_help_compose_start(){
12 | echo -e " - ${blu:?}[-> This script STARTS 'up' a single Docker container using a pre-written compose file <-]${def:?}"
13 | echo -e " -"
14 | echo -e " - SYNTAX: # dcu | dcs | dct"
15 | echo -e " - SYNTAX: # dcu ${cyn:?}stack_name${def:?}"
16 | echo -e " - SYNTAX: # dcu ${cyn:?}-option${def:?}"
17 | echo -e " - VALID OPTIONS:"
18 | echo -e " - ${cyn:?}-h │ --help ${def:?}| Displays this help message."
19 | echo -e " - ${cyn:?}-a | --all ${def:?}| Deploys all stacks with a config file inside the '${ylw:?}${docker_compose:?}/${def:?}' path."
20 | echo -e " - NOTE: config files must follow this naming format: '${cyn:?}/stackname${cyn:?}/compose.yml${def:?}'"
21 | echo
22 | exit 1 # Exit script after printing help
23 | }
24 | case "$1" in ("-h"|*"help"*) fnc_help_compose_start ;; esac
25 |
26 | fnc_script_intro(){ echo -e "${blu:?}[- ${grn:?}STARTING${blu:?} LISTED DOCKER CONTAINERS -]${def:?}"; }
27 | fnc_script_outro(){ echo -e "${blu:?}[- List of Docker containers ${grn:?}STARTED${blu:?} <-]${def:?}"; }
28 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> no configuration file exists for the entered stack(s)${def:?}"; }
29 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE ${cyn:?}--help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
30 |
31 | # # fnc_remove_cmd_option(){ for i in "${!stacks_list[@]}"; do if [[ "${stacks_list[i]}" = "-*" || "${stacks_list[i]}" = "." ]]; then unset "${stacks_list[i]}"; fi; done; }
32 | # fnc_remove_cmd_option() { # remove elements starting with '-' from array
33 | # local filtered=()
34 | # for element in "$@"; do
35 | # if [[ $element != \-* && $element != . ]]; then
36 | # filtered+=("$element")
37 | # fi
38 | # done
39 | # stacks_list=("${filtered[@]}")
40 | # }
41 |
42 | ## consolidate list_processing in bounce and start functions
43 | ## track down permissions issue with .env, preventing script to run - DONE, was missing 'w' permission for group
44 | ## - figure out why sudo function isn't working
45 |
46 | # fnc_check_sudo_usage(){
47 | # case "$(awk -F'=' '/^ID=/ { gsub("\"","",$2); print tolower($2) } ' /etc/*-release 2> /dev/null)" in
48 | # ("qts"|"quts"|"debian")
49 | # unset var_sudo IFS;
50 | # case "$(id -un)" in
51 | # ("admin"|"root")
52 | # unset var_sudo IFS;
53 | # ;;
54 | # (*)
55 | # var_sudo="/usr/bin/sudo ";
56 | # ;;
57 | # esac
58 | # ;;
59 | # (*)
60 | # var_sudo="/usr/bin/sudo ";
61 | # ;;
62 | # esac
63 | # }
64 |
65 | fnc_list_all_running(){ IFS=$'\n' bounce_list=("$(docker container list --format '{{.Names}}')"); }
66 | fnc_list_sort(){ deploy_list=( "$(for stack in "${deploy_list[@]}" ; do echo "$stack" ; done | sort -u)" ); }
67 | # fnc_subdirectories_list=( "$(IFS=$'\n'; cd "${docker_compose:?}" && find . -type d -not -path '*/\.*' | sed 's/^\.\///g')" )
68 | fnc_configs_folder_list(){ IFS=$'\n'; configs_folder_list=( "$(cd "${docker_compose:?}" && find . -maxdepth 1 -type d -not -path '*/\.*' | sed 's/^\.\///g')" ); }
69 | fnc_deploy_list_cleanup(){ # check that each folder has a .yml config file and clean up the array
70 | unset configs_list IFS;
71 | for i in "${!configs_folder_list[@]}"; do
72 | # remove '.' folder name from printed list
73 | if [[ "${configs_folder_list[i]}" = "." ]]; then unset "${configs_folder_list[i]}"; fi
74 | if [[ -f "${docker_compose:?}"/"${configs_folder_list[i]}"/"${var_configs_file:?}" ]]
75 | then configs_list="${configs_list} ${configs_folder_list[i]}"
76 | fi
77 | done
78 | unset deploy_list IFS;
79 | IFS=$'\n'; deploy_list=( "${configs_list[@]}" )
80 | }
81 | fnc_bounce_list(){ # populate list of stacks to be started
82 | # fnc_check_sudo_usage;
83 | if [[ "${bounce_list[*]}" = "" ]]; then
84 | # populate list of configuration folders
85 | fnc_configs_folder_list
86 | # check that each existing folder has a .yml config file inside
87 | fnc_deploy_list_cleanup
88 | else IFS=$'\n'; deploy_list=( "${bounce_list[@]}" )
89 | fi
90 | }
91 | fnc_start_containers(){ # perform script main function
92 | # fnc_check_sudo_usage;
93 | # IFS=$'\n'; deploy_list=( $(for stack in "${deploy_list[@]}" ; do echo "${stack}" ; done | sort -u) )
94 | fnc_list_sort "${deploy_list[@]}"
95 | for stack in "${deploy_list[@]}"; do
96 | # create '.env' file redirect if used
97 | # if [ ! -f "${docker_compose:?}/${deploy_list[stack]}/.env" ]; then ln -s "${var_script_vars:?}" "${docker_compose:?}/${deploy_list[stack]}/.env"; fi
98 | # [ ! -f "${docker_compose:?}/${deploy_list[stack]}/.env" ] && ln -sf "${var_script_vars:?}" "${docker_compose:?}/${deploy_list[stack]}/.env";
99 | # "${var_sudo}"
100 | if [ ! -f "${docker_compose:?}/${stack}/.env" ]; then ln -sf "${var_script_vars:?}" "${docker_compose:?}/${stack}/.env"; fi;
101 | docker compose -f "${docker_compose:?}/${stack}/${var_configs_file:?}" up -d --remove-orphans
102 | sleep 1
103 | done
104 | }
105 |
106 | # option logic action determination
107 | case "${1}" in
108 | (-*) # validate entered option exists
109 | case "${1}" in
110 | ("-a"|"--all")
111 | unset "deploy_list[0]"
112 | fnc_bounce_list
113 | ;;
114 | (*)
115 | fnc_invalid_syntax
116 | ;;
117 | esac
118 | ;;
119 | (*)
120 | IFS=' ' deploy_list=("$@")
121 | ;;
122 | esac
123 |
124 | # perform script main function
125 | fnc_start_containers
126 |
--------------------------------------------------------------------------------
/docker_compose_stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # script variable definitions
7 | unset stacks_list IFS
8 | IFS=' ' stacks_list=("$@")
9 |
10 | # function definitions
11 | fnc_help_compose_stop(){
12 | echo -e "${blu:?}[- This script STOPS or brings DOWN a single Docker container using a pre-written compose file -]${def:?}"
13 | echo -e " -"
14 | echo -e " - SYNTAX: # dcd | dcp | dcr ${cyn:?}stack_name${def:?}"
15 | # echo -e " - SYNTAX: # dcd ${cyn:?}-option${def:?}"
16 | echo -e " - VALID OPTIONS:"
17 | echo -e " - ${cyn:?}-h │ --help ${def:?}| Displays this help message."
18 | echo -e " - ${cyn:?}-d | --Down ${def:?}| Brings ${red:?}Down${def:?} docker container(s) and associated network(s)."
19 | echo -e " - ${cyn:?}-p | --stoP ${def:?}| ${ylw:?}stoPs${def:?} currently running docker container(s)."
20 | echo -e " - ${cyn:?}-r | --Remove ${def:?}| ${ylw:?}stoPs${def:?} and ${red:?}Removes${def:?} listed docker container(s)."
21 | echo
22 | exit 1 # Exit script after printing help
23 | }
24 | case "$1" in ("-h"|*"help"*) fnc_help_compose_stop ;; esac
25 |
26 | fnc_intro_compose_stop(){ echo -e "${blu:?}[- ${red:?}STOPPING${blu:?} LISTED DOCKER CONTAINERS -]${def:?}"; }
27 | fnc_outro_compose_stop(){ echo -e "${blu:?}[- LISTED DOCKER CONTAINERS ${red:?}STOPPED${blu:?} -]${def:?}"; }
28 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE ${cyn:?}-help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
29 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> No compose or stack specified. Expected synatax: ${def:?}dcd ${cyn:?}stack_name${def:?}"; }
30 |
31 | # fnc_remove_cmd_option(){ for i in "${!stacks_list[@]}"; do if [[ "${stacks_list[i]}" = "-*" || "${stacks_list[i]}" = "." ]]; then unset "${stacks_list[i]}"; fi; done; }
32 | fnc_remove_cmd_option() { # remove args starting with '-' from array
33 | local filtered=()
34 | local args="$@"
35 | for arg in "${args[@]}"; do
36 | # if [[ $arg = . ]]; then unset $args[#]; fi
37 | # if [[ $arg = \-* ]]; then options+=("$arg"); fi
38 | if [[ $arg != \-* && $arg != . ]]; then filtered+=("$arg"); fi
39 | done
40 | option_list=("${options[@]}")
41 | stacks_list=("${filtered[@]}")
42 | }
43 |
44 | # fnc_list_sort(){ IFS=$'\n'; stacks_list=( $(for stack in "${stacks_list[@]}" ; do echo "${stack}" ; done | sort -u) ); }
45 | fnc_list_sort(){ sort_list="${stacks_list[*]}"; IFS=$'\n' read -r stacks_list <<< "$( for stack in "${sort_list[@]}" ; do echo "${stack}" ; done | sort -u )"; }
46 | # fnc_list_sort(){
47 | # stacks_list=();
48 | # while IFS=$'' read -r line; do stacks_list+=("$line"); done < <( for stack in "${stacks_list[@]}" ; do echo "${stack}" ; done | sort -u );
49 | # }
50 | fnc_configs_list_all(){ IFS=$'\n'; stacks_list=($(docker container list --format {{.Names}})); fnc_list_sort; }
51 | # fnc_configs_list_all(){
52 | # stacks_list=();
53 | # while IFS=$'' read -r line; do stacks_list+=("$line"); done < <( docker container list --format "{{.Names}}" ); fnc_list_sort;
54 | # }
55 | # fnc_configs_list_all(){ IFS=$'\n' read -r -q stacks_list <<< "$( docker container list --format "{{.Names}}" )"; fnc_list_sort; }
56 | fnc_env_file_remove(){ if [[ -f "${docker_compose:?}/${1}/.env" ]]; then rm -f "${docker_compose:?}/${1}/.env"; fi; }
57 | fnc_docker_stop(){ docker stop "${1}"; }
58 | fnc_docker_container_rm(){ docker container rm -f "${1}"; } #fnc_env_file_remove "${1}"; }
59 | fnc_docker_compose_down(){ docker compose -f "${docker_compose:?}/${1}/${var_configs_file:?}" down; } # fnc_env_file_remove "${1}"; }
60 | fnc_docker_compose_stop(){ docker compose -f "${docker_compose:?}/${1}/${var_configs_file:?}" stop; }
61 |
62 | #### NOTE: below function order must not change
63 |
64 | # TODO: this function might replace individual "rm/down/stop" functions with an "action" variable assigned during case logic
65 | fnc_container_action(){
66 | for stack in "${stacks_list[@]}"; do
67 | if [[ -f "${docker_compose:?}/${stack}/${var_configs_file:?}" ]]; then
68 | docker compose -f "${docker_compose:?}/${stack}/${var_configs_file:?}" "${action}"
69 | else
70 | if [[ "${action}" == "down" ]]; then
71 | fnc_docker_stop "${stack}"
72 | fnc_docker_container_rm "${stack}"
73 | elif [[ "${action}" == "stop" ]]; then
74 | fnc_docker_stop "${stack}"
75 | fi
76 | fi
77 | sleep 1
78 | done
79 | }
80 | fnc_container_stop(){
81 | for stack in "${stacks_list[@]}"; do
82 | # TODO: check if compose file exists, if not, try to stop container instead
83 | if [[ -f "${docker_compose:?}/${stack}/${var_configs_file:?}" ]]; then
84 | fnc_docker_compose_stop "${stack}"
85 | else
86 | fnc_docker_stop "${stack}"
87 | fi
88 | sleep 1
89 | done
90 | }
91 | fnc_container_remove(){
92 | # stacks_list=($(fnc_remove_cmd_option "${stacks_list[@]}"))
93 | fnc_remove_cmd_option "${stacks_list[@]}"
94 | for stack in "${stacks_list[@]}"; do
95 | # TODO: check if compose file exists, if not, try to stop and remove container instead
96 | if [[ -f "${docker_compose:?}/${stack}/${var_configs_file:?}" ]]; then
97 | fnc_docker_compose_down "${stack}"
98 | else
99 | fnc_docker_stop "${stack}"
100 | fnc_docker_container_rm "${stack}"
101 | fi
102 | # fnc_env_file_remove "${stack}"
103 | sleep 1
104 | done
105 | }
106 |
107 | # option logic action determination
108 | case "${1}" in
109 | ("")
110 | fnc_nothing_to_do
111 | ;;
112 | (-*) # validate entered option exists
113 | case "${1}" in
114 | ("-a"|"--all")
115 | unset stacks_list
116 | fnc_configs_list_all
117 | action="down"
118 | fnc_remove_cmd_option "${stacks_list[@]}"
119 | fnc_container_remove "${stacks_list[@]}"
120 | ;;
121 | ("-d"|"--down")
122 | # unset "stacks_list[0]"
123 | action="down"
124 | fnc_remove_cmd_option "${stacks_list[@]}"
125 | fnc_container_remove "${stacks_list[@]}"
126 | ;;
127 | ("-p"|"--stop")
128 | # unset "stacks_list[0]"
129 | action="stop"
130 | fnc_remove_cmd_option "${stacks_list[@]}"
131 | fnc_container_stop "${stacks_list[@]}"
132 | ;;
133 | ("-r"|"--remove")
134 | # unset "stacks_list[0]"
135 | action="rm"
136 | fnc_remove_cmd_option "${stacks_list[@]}"
137 | fnc_container_remove "${stacks_list[@]}"
138 | ;;
139 | ("-l"|"--list")
140 | # unset "stacks_list[0]"
141 | action="ls"
142 | fnc_remove_cmd_option "${stacks_list[@]}"
143 | fnc_configs_list_all
144 | echo "${stacks_list[*]}"
145 | ;;
146 | (*)
147 | fnc_invalid_syntax
148 | ;;
149 | esac
150 | ;;
151 | (*)
152 | # fnc_invalid_syntax
153 | action="down"
154 | fnc_remove_cmd_option "${stacks_list[@]}"
155 | fnc_container_remove "${stacks_list[@]}"
156 | ;;
157 | esac
158 |
159 | # fnc_outro_compose_stop
--------------------------------------------------------------------------------
/docker_compose_test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | #function definitions
7 | fnc_help_docker_compose_test(){
8 | echo -e "${blu:?}[- This script displays the indicated compose file with variables/secrets filled in. -]${def:?}"
9 | echo -e " -"
10 | echo -e " - SYNTAX: # dcc | dct | dctest ${cyn:?}stack_name${def:?}"
11 | # echo -e " - SYNTAX: # dcd ${cyn:?}-option${def:?}"
12 | echo -e " - VALID OPTIONS:"
13 | echo -e " - ${cyn:?}-h │ --help ${def:?}| Displays this help message."
14 | echo
15 | exit 1 # Exit script after printing help
16 | }
17 | case "$1" in ("-h"|*"help"*) fnc_help_docker_compose_test ;; esac
18 |
19 | fnc_intro_docker_compose_test(){ echo -e "${blu:?}[- ${mgn:?}DISPLAYING${blu:?} COMPLETED COMPOSE FILE FOR ${cyn:?}stack_name${blu:?} -]${def:?}"; }
20 | fnc_outro_docker_compose_test(){ echo -e "${blu:?}[- ${cyn:?}\`docker compose config\`${def:?} display complete. -]${def:?}"; }
21 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE ${cyn:?}-help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
22 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> No compose or stack specified. Expected synatax: ${def:?}dcc ${cyn:?}stack_name${def:?}"; }
23 |
24 | fnc_docker_compose_test(){ docker compose -f "${docker_compose:?}/${1}/${var_configs_file:?}" config; }
25 |
26 | case "$1" in
27 | *) fnc_intro_docker_compose_test; fnc_docker_compose_test "${@}"; fnc_outro_docker_compose_test;;
28 | # "dct") fnc_intro_docker_compose_test; fnc_docker_compose_test "${@}"; fnc_outro_docker_compose_test;;
29 | # "dctest") fnc_intro_docker_compose_test; fnc_docker_compose_test "${@}"; fnc_outro_docker_compose_test;;
30 | # "") fnc_nothing_to_do;;
31 | # *) fnc_invalid_syntax;;
32 | esac
--------------------------------------------------------------------------------
/docker_folders_create.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # script help text
7 | fnc_help_folders_create(){
8 | echo -e "${blu:?}[-> This script creates Docker configuration folders using the schema developed by ${cyn:?}Drauku${blu:?} <-]${def:?}"
9 | echo -e " - ${blu:?}(modified from ${cyn:?}gkoerk's (RIP)${blu:?} famously awesome folder structure for stacks)${def:?}"
10 | echo -e " -"
11 | echo -e " -NOTE: stack_names must NOT contain spaces, but MUST be separated by a 'space' character: "
12 | echo -e " -"
13 | echo -e " - SYNTAX: ${command_name} ${cyn:?}stack_name1${def:?} ${cyn:?}stack_name2${def:?} etc etc"
14 | echo -e " - SYNTAX: ${command_name} ${cyn:?}-option${def:?}"
15 | echo -e " - VALID OPTIONS:"
16 | echo -e " - ${cyn:?}-h │ --help ${def:?}| Displays this help message."
17 | echo -e " -"
18 | echo -e " - The below folder structure and files are created for each 'stack_name' entered with this command:"
19 | echo -e " - ${ylw:?}${docker_appdata}/${cyn:?}stack_name${mgn:?}/stack_name-logs.yml${def:?}"
20 | echo -e " - ${ylw:?}${docker_compose}/${cyn:?}stack_name${mgn}/${var_configs_file}${def:?}"
21 | echo
22 | exit 1 # Exit script after printing help
23 | }
24 | # case "$1" in ("-h"|*"help"*) fnc_help_folders_create ;; esac # disabled because this script handles both compose and swarm folder creation
25 |
26 | ## function definitions
27 | fnc_intro_folders_create(){ echo -e "${blu:?}[-> CREATE DOCKER FOLDER STRUCTURE FOR LISTED STACKS <-]${def:?}"; }
28 | fnc_outro_folders_create(){ echo -e "${grn:?} -> DOCKER CONFIGS FOLDER STRUCTURE AND FILES CREATED${def:?}"; echo; }
29 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
30 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> This command requires a valid option followed by container name(s). Use ${cyn:?}-help${ylw:?} do display options. ${def:?}"; }
31 | fnc_create_folders(){
32 | echo; exist=0;
33 | folder_list=("$@")
34 | for stack in "${folder_list[@]}"; do
35 | if [ ! -d "${appdata_folder}/${stack}" ];
36 | then install -o "${var_uid}" -g "${var_gid}" -m 664 -d "${appdata_folder}/${stack}";
37 | else echo -e " > ${cyn:?}${appdata_folder}${cyn:?}/${stack} ${ylw:?}ALREADY EXISTS ${def:?}"; exist=1;
38 | fi;
39 | if [ ! -d "${configs_folder}/${stack}" ];
40 | then install -o "${var_uid}" -g "${var_gid}" -m 664 -d "${configs_folder}/${stack}";
41 | else echo -e " > ${cyn:?}${configs_folder}${cyn:?}/${stack} ${ylw:?}ALREADY EXISTS ${def:?}"; exist=1;
42 | fi;
43 | [ "${exist}" == "0" ] && echo -e " > ${cyn:?}${stack} ${ylw:?}COMPOSE FOLDER SET ${grn:?}CREATED ${def:?}";
44 | done
45 | }
46 | fnc_create_files(){
47 | echo; exist=0;
48 | folder_list=("$@")
49 | for stack in "${folder_list[@]}"; do
50 | if [ ! -f "${appdata_folder}/${stack}/${stack}-logs.yml" ];
51 | then install -o "${var_uid}" -g "${var_gid}" -m 660 /dev/null "${appdata_folder}/${stack}/${stack}-logs.yml";
52 | else echo -e " > ${cyn:?}${appdata_folder}${cyn:?}/${stack} ${ylw:?}ALREADY EXISTS ${def:?}"; exist=1;
53 | fi;
54 | if [ ! -f "${configs_folder}/${stack}/${var_configs_file}" ];
55 | then install -o "${var_uid}" -g "${var_gid}" -m 664 "${var_template_yaml}" "${configs_folder}/${stack}/${var_configs_file}";
56 | else echo -e "${ylw:?} > ${cyn:?}${appdata_folder}/${cyn:?}${stack}/${var_configs_file} ${ylw:?}ALREADY EXISTS ${def:?}"; exist=1;
57 | fi;
58 | if [ ! -f "${configs_folder}/${stack}/.env" ];
59 | then ln -sf "${var_script_vars}" "${configs_folder}/${stack}/.env"
60 | fi;
61 | [ "${exist}" == "0" ] && echo -e " > ${cyn:?}${stack} ${ylw:?}COMPOSE FOLDER SET ${grn:?}CREATED ${def:?}";
62 | done
63 | }
64 |
65 | # output determination logic
66 | case "${1}" in
67 | ("")
68 | fnc_nothing_to_do
69 | ;;
70 | ("-"*) # validate and perform option
71 | case "${1}" in
72 | ("-c"|"-compose"|"--compose")
73 | echo "1='${1}', 2='${2}', all='${*}'"
74 | case "${2}" in
75 | ("-h"|*"-help"*)
76 | command_name="dcf"
77 | fnc_help_folders_create
78 | ;;
79 | esac
80 | appdata_folder="${docker_appdata}";
81 | configs_folder="${docker_compose}";
82 | fnc_create_folders "${*}";
83 | fnc_create_files "${*}";
84 | ;;
85 | ("-w"|"-swarm"|"--swarm")
86 | echo "1='${1}', 2='${2}', all='${*}'"
87 | case "${2}" in
88 | ("-h"|*"-help"*)
89 | command_name="dsf || dwf"
90 | fnc_help_folders_create
91 | ;;
92 | esac
93 | appdata_folder="${docker_appdata}";
94 | configs_folder="${docker_swarm}";
95 | fnc_create_folders "${*}";
96 | fnc_create_files "${*}";
97 | ;;
98 | (*)
99 | fnc_invalid_syntax
100 | ;;
101 | esac
102 | ;;
103 | esac
104 |
105 | # fnc_outro_folders_create
--------------------------------------------------------------------------------
/docker_list_configs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # external variable sources
4 | source /opt/docker/scripts/.color_codes.conf
5 | source /opt/docker/scripts/.vars_docker.env
6 |
7 | # script variable definitions
8 | unset configs_folder_list IFS
9 | unset configs_list IFS
10 | unset configs_path IFS
11 |
12 | # script help text
13 | fnc_help_list_configs(){
14 | echo -e "${blu:?}[-> This script lists the existing 'stackname.yml' files in the ${ylw:?}../swarm/${blu:?} or ${ylw:?}../compose/${blu:?} folder structure. <-]${def:?}"
15 | echo -e " -"
16 | echo -e " - SYNTAX: # dlg ${cyn:?}-option${def:?}"
17 | echo -e " - SYNTAX: # dccfg | dcg == 'dlg ${cyn:?}--compose${def:?}'"
18 | echo -e " - SYNTAX: # dwcfg | dwg == 'dlg ${cyn:?}--swarm${def:?}'"
19 | echo -e " - VALID OPTIONS:"
20 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message."
21 | echo -e " - ${cyn:?}-c │ --compose ${def:?}│ Displays stacks with config files in the ${ylw:?}..${docker_compose:-/opt/docker/compose}/${def:?} filepath."
22 | echo -e " - ${cyn:?}-w │ --swarm ${def:?}│ Displays stacks with config files in the ${ylw:?}..${docker_swarm:-/opt/docker/swarm}/${def:?} filepath."
23 | echo -e " -"
24 | echo -e " - NOTE: a valid option from above is required for this script to function"
25 | echo
26 | exit 1 # Exit script after printing help
27 | }
28 | case "$1" in ("-h"|*"help"*) fnc_help_list_configs ;; esac
29 |
30 | ## function definitions
31 | # intro message for script
32 | fnc_intro_list_configs(){ echo -e "${blu:?}[-> EXISTING DOCKER ${cyn:?}${conftype:?}${blu:?} CONFIG FILES IN ${ylw:?}${configs_path}/${blu:?} <-]${def:?}"; }
33 | # outro message for script
34 | fnc_outro_list_configs(){
35 | # echo -e "[-- ${grn:?} DISPLAYED LIST OF CONFIG FILES IN ${ylw:?}${configs_path}/ ${def:?} --]";
36 | echo;
37 | }
38 | # invalid syntax message
39 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
40 | # nothing to do message
41 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> no configuration files exist${def:?}"; }
42 | # populate configs list array with docker config files in the '/opt/docker/${conftype}' folder
43 | fnc_list_config_folders(){
44 | IFS=$'\n' configs_folder_list=( $(cd "${configs_path}" && find . -maxdepth 1 -type d -not -path '*/\.*' | sort | sed 's/^\.\///g') );
45 | }
46 | # set script variables for Docker Compose configs
47 | fnc_type_compose(){
48 | conftype="compose";
49 | configs_path="${docker_compose:-/opt/docker/compose}";
50 | source "${docker_compose}"/.stackslist-compose.conf;
51 | }
52 | # set script variables for Docker Swarm configs
53 | fnc_type_swarm(){
54 | conftype="swarm";
55 | configs_path="${docker_swarm:-/opt/docker/swarm}";
56 | source "${docker_swarm}"/.stackslist-swarm.conf;
57 | }
58 | # clean up configs list array
59 | fnc_folder_list_cleanup(){
60 | if [[ "${configs_folder_list[i]}" = "." ]]; then
61 | unset "configs_folder_list[i]";
62 | fi;
63 | for i in "${!configs_folder_list[@]}"; do
64 | if [ i == "." ]; then unset "configs_folder_list[i]"; fi;
65 | done;
66 | }
67 | # populate the configs_list array
68 | fnc_list_config_files(){
69 | if [[ -f "${configs_path}/${configs_folder_list[i]}/${var_configs_file:-compose.yml}" ]];
70 | then configs_list="${configs_list} ${configs_folder_list[i]}";
71 | fi;
72 | }
73 | fnc_display_config_files(){
74 | # display config files list if any
75 | if [[ ! ${configs_list} ]]; then
76 | echo -e " -> ${ylw:?}no configuration files exist${def:?}";
77 | else
78 | echo -e " ->${cyn:?}${configs_list[*]}${def:?}";
79 | fi;
80 | echo;
81 | }
82 |
83 | # determine configuration type to query
84 | case "$1" in
85 | ("-h"|"-help"|"--help")
86 | fnc_help_list_configs
87 | ;;
88 | ("-c"|"--compose")
89 | fnc_type_compose
90 | fnc_intro_list_configs
91 | ;;
92 | ("-s"|"-w"|"--swarm")
93 | fnc_type_swarm
94 | fnc_intro_list_configs
95 | ;;
96 | (*)
97 | fnc_invalid_syntax
98 | ;;
99 | esac
100 |
101 | # common tasks for all config types
102 | fnc_list_config_folders
103 | # fnd_list_config_files
104 | fnc_display_config_files
105 | # fnc_outro_list_configs
--------------------------------------------------------------------------------
/docker_list_container.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # function definitions
7 | fnc_help(){
8 | echo -e "${blu:?}[-> This script lists current '${cyn:?}stacknames${blu:?}' and the number of '${cyn:?}services${blu:?}' in that stack <-]${def:?} "
9 | echo -e "${blu:?}[-> It will also list services inside a '${cyn:?}stacknames${blu:?}' when passing one of the below options <-]${def:?} "
10 | echo -e " -"
11 | echo -e " - SYNTAX: # dlc ${cyn:?}-option${def:?}"
12 | echo -e " - VALID OPTION(S):"
13 | echo -e " - ${cyn:?}-h │ -help ${def:?}| Displays this help message."
14 | echo -e " -"
15 | echo -e " - SYNTAX: # dlc │ Displays '${cyn:?}docker container ls' formatted for easy readability.${def:?}"
16 | echo -e " -"
17 | echo -e " - SYNTAX: # dlc ${cyn:?}stackname${def:?}"
18 | echo -e " - VALID OPTION(S):"
19 | echo -e " - ${cyn:?}-l │ -lbl │ --labels ${def:?}│ Displays '${cyn:?}docker container ls${def:?}' output with only 'Names' and 'Labels' columns."
20 | echo -e " - ${cyn:?}-n │ -net │ --network ${def:?}│ Displays '${cyn:?}docker container ls${def:?}' output with only 'Networks' and 'Ports' columns."
21 | echo -e " - ${cyn:?}-v │ -vol │ --volumes ${def:?}│ Displays '${cyn:?}docker container ls${def:?}' output with only 'Volumes' and 'Mounts' columns."
22 | echo -e " -"
23 | echo -e " - SYNTAX: # dlc ${cyn:?}stackname${def:?} ${cyn:?}-option${def:?}"
24 | echo -e " - VALID OPTION(S):"
25 | echo -e " - ${cyn:?}-l | --list ${def:?}| Displays '${cyn:?}docker container list --no-trunc ${cyn:?}stackname${def:?}' output with non-truncated entries and select columns."
26 | echo -e " - ${cyn:?}-s | --services ${def:?}| Displays '${cyn:?}docker container services ${cyn:?}stackname${def:?}' output with custom selected columns."
27 | echo
28 | exit 1 # Exit after printing help
29 | }
30 | case "$1" in ("-h"|*"help"*) fnc_help ;; esac
31 | fnc_script_intro(){ echo -e "${blu:?}[-> LIST OF CURRENT DOCKER CONTAINERS <-]${def:?} "; }
32 | fnc_script_error(){ echo -e "${blu:?}[-> LIST OF DOCKER CONTAINER ${red:?}ERRORS${blu:?} <-]${def:?} "; }
33 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> no current docker containers exist${def:?}"; }
34 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE '--${cyn:?}help${ylw:?}' OPTION TO DISPLAY PROPER SYNTAX${def:?} <<"; exit 1; }
35 | fnc_container_list(){ docker container list -a -q; }
36 | fnc_error_check(){ docker container list --no-trunc --format "{{.Error}}" "${1}"; }
37 | fnc_list_container_act(){ docker container list --format "table {{.ID}} {{.Names}}\t{{.Status}}\t{{.Image}}\t{{.Command}}"; }
38 | fnc_list_container_all(){ docker container list --all --format "table {{.ID}} {{.Names}}\t{{.Status}}\t{{.RunningFor}}\t{{.Image}}"; }
39 | fnc_list_container_lbl(){ docker container list --no-trunc --format "table {{.Names}}\t{{.Status}}\t{{.Labels}}\t{{.Command}}"; }
40 | fnc_list_container_net(){ docker container list --no-trunc --format "table {{.Names}}\t{{.Status}}\t{{.Networks}}\t{{.Ports}}"; }
41 | fnc_list_container_vol(){ docker container list --no-trunc --format "table {{.Names}}\t{{.Status}}\t{{.LocalVolumes}}\t{{.Mounts}}"; }
42 |
43 | # output determination logic
44 | case "${1}" in
45 | ("")
46 | fnc_script_intro;
47 | if [ ! "$(fnc_container_list)" ]; then fnc_nothing_to_do; else fnc_list_container_act; fi ;;
48 | (-*)
49 | case "${1}" in
50 | ("-a"|"-all"|"--all")
51 | fnc_script_intro; fnc_list_container_all;
52 | ;;
53 | ("-l"|"-lbl"|"--labels")
54 | fnc_script_intro; fnc_list_container_lbl;
55 | ;;
56 | ("-n"|"-net"|"--network")
57 | fnc_script_intro; fnc_list_container_net;
58 | ;;
59 | ("-v"|"-vol"|"--volumes")
60 | fnc_script_intro; fnc_list_container_vol;
61 | ;;
62 | (*)
63 | fnc_invalid_syntax;
64 | ;;
65 | esac
66 | ;;
67 | (*)
68 | case "${2}" in
69 | ("")
70 | # if [ "$(fnc_error_check)" ]; then fnc_list_service_err "${1}" "${2}"; else fnc_list_service_act "${1}" "${2}"; fi
71 | if [ ! "$(fnc_error_check "${1}" "${2}")" ];
72 | then fnc_script_intro; fnc_list_service_act "${1}" "${2}";
73 | else fnc_script_error; fnc_list_service_err "${1}" "${2}";
74 | fi
75 | ;;
76 | (-*)
77 | case "${2}" in
78 | ("-ls"|"--list")
79 | fnc_script_intro; fnc_list_container_err "${1}" "${2}";
80 | ;;
81 | ("-sv"|"-svcs"|"--services")
82 | fnc_script_intro; fnc_list_container_act "${1}" "${2}";
83 | ;;
84 | (*)
85 | fnc_invalid_syntax;
86 | ;;
87 | esac
88 | esac
89 | ;;
90 | esac
91 | echo
92 |
93 | # fnc_script_outro
94 |
95 | # to list possible --format tags, type 'docker command --format='{{json .}}''
96 |
97 | # docker container --format='{{json .}}'
98 | # {{.Command}}
99 | # {{.CreatedAt}}
100 | # {{.ID}}
101 | # {{.Image}}
102 | # {{.Labels}}
103 | # {{.LocalVolumes}}
104 | # {{.Mounts}}
105 | # {{.Names}}
106 | # {{.Networks}}
107 | # {{.Ports}}
108 | # {{.RunningFor}}
109 | # {{.Size}}
110 | # {{.Status}}
111 |
--------------------------------------------------------------------------------
/docker_list_stack.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # external variable sources
4 | source /opt/docker/scripts/.color_codes.conf
5 | source /opt/docker/scripts/.vars_docker.env
6 |
7 | # function definitions
8 | fnc_help(){
9 | echo -e "${blu:?}[-> This script lists current '${cyn:?}stacknames${blu:?}' and the number of '${cyn:?}services${blu:?}' in that stack <-]${def:?} "
10 | echo -e "${blu:?} -> It will also list services inside a '${cyn:?}stacknames${blu:?}' when passing one of the below options <-]${def:?} "
11 | echo -e " -"
12 | echo -e " - SYNTAX: # dls ${cyn:?}stackname${def:?} │ this is the same as with '-sv' option"
13 | echo -e " - SYNTAX: # dls ${cyn:?}stackname${def:?} ${cyn:?}-option${def:?}"
14 | echo -e " - VALID OPTION(S):"
15 | echo -e " - ${cyn:?}-e | --errors${def:?} │ Displays '${cyn:?}docker stack ps --no-trunc ${cyn:?}stackname${def:?}' output with non-truncated entries and select columns."
16 | echo -e " - ${cyn:?}-s | --services${def:?} │ Displays '${cyn:?}docker stack services ${cyn:?}stackname${def:?}' output with custom selected columns."
17 | echo -e " -"
18 | echo -e " - SYNTAX: # dls ${cyn:?}-option${def:?}"
19 | echo -e " - VALID OPTION(S):"
20 | echo -e " - ${cyn:?}-h | --help${def:?} │ Displays this help message."
21 | echo
22 | exit 1 # Exit script after printing help
23 | }
24 | fnc_script_intro(){ echo -e "${blu:?}[-> LIST OF CURRENT DOCKER SWARM STACKS <-]${def:?} "; }
25 | fnc_script_error(){ echo -e "${blu:?}[-> LIST OF DOCKER SWARM STACK ${red:?}ERRORS${blu:?} <-]${def:?} "; }
26 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> no current docker swarm stacks exist${def:?}"; }
27 | fnc_not_swarm_node(){ echo -e "${ylw:?} -> this docker node is not a swarm manager ${def:?}"; }
28 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE '${cyn:?}--help${ylw:?}' OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; }
29 | fnc_stack_lst(){ docker stack ls; }
30 | fnc_stack_svc(){ docker stack services "${1}" --format "table {{.ID}}\t{{.Name}}\t{{.Image}}\t{{.Ports}}"; }
31 | fnc_stack_err(){ docker stack ps --no-trunc --format "table {{.ID}}\t{{.Name}}\t{{.Node}}\t{{.CurrentState}}\t{{.Error}}" "${1}"; }
32 | fnc_stack_chk(){ docker stack ps --no-trunc --format "{{.Error}}" "${1}"; }
33 |
34 | # fnc_node_lst(){ docker node ps "$(docker node ls -q)" --format "table {{.Node}}\t{{.Name}}\t{{.CurrentState}}" --filter desired-state=Running | uniq; }
35 |
36 | # determine script output according to option entered
37 | case "${1}" in
38 | ("")
39 | fnc_script_intro;
40 | case "$(fnc_stack_lst)" in
41 | ("NAME SERVICES")
42 | fnc_nothing_to_do;
43 | ;;
44 | ("Error response from daemon: This node is not a swarm manager. Use \"docker swarm init\" or \"docker swarm join\" to connect this node to swarm and try again.")
45 | fnc_not_swarm_node;
46 | ;;
47 | (*)
48 | fnc_stack_lst;
49 | ;;
50 | esac
51 | ;;
52 | (-*) # confirm entered option is valid
53 | case "${1}" in
54 | ("-"|"-h"|"-help"|"--help")
55 | fnc_help
56 | ;;
57 | (*)
58 | fnc_invalid_syntax
59 | ;;
60 | esac
61 | ;;
62 | (*)
63 | case "${2}" in
64 | (-*) # confirm entered option is valid
65 | case "${2}" in
66 | ("-e"|"--errors")
67 | fnc_script_error;
68 | fnc_stack_err "${1}" "${2}";
69 | ;;
70 | ("-s"|"--services")
71 | fnc_script_intro;
72 | fnc_stack_svc "${1}" "${2}";
73 | ;;
74 | (*)
75 | fnc_invalid_syntax;
76 | ;;
77 | esac
78 | ;;
79 | (*)
80 | fnc_script_intro;
81 | case "$(fnc_stack_chk "${1}" "${2}")" in
82 | ("")
83 | fnc_stack_svc "${1}" "${2}";
84 | ;;
85 | (*)
86 | fnc_stack_err "${1}" "${2}";
87 | ;;
88 | esac
89 | ;;
90 | esac
91 | ;;
92 | esac
93 | echo
94 |
95 | # to list possible --format tags, type 'docker command --format='{{json .}}''
96 |
97 | # docker stack services traefik --format='{{json .}}'
98 | # {{.ID}}
99 | # {{.Image}}
100 | # {{.Mode}}
101 | # {{.Name}}
102 | # {{.Ports}}
103 | # {{.Replicas}}
104 |
105 | # docker service ps traefik_app --format='{{json .}}'
106 | # {{.CurrentState}}
107 | # {{.DesiredState}}
108 | # {{.Error}}
109 | # {{.ID}}
110 | # {{.Image}}
111 | # {{.Name}}
112 | # {{.Node}}
113 | # {{.Ports}}
114 |
115 | # fnc_service_lst(){ docker service ps "${1}" --format "table {{.ID}}\t{{.Name}}\t{{.Image}}\t{{.Node}}\t{{.CurrentState}}"; }
116 | # fnc_service_err(){ docker service ps "${1}" --no-trunc --format "table {{.ID}}\t{{.Name}}\t{{.Node}}\t{{.CurrentState}}\t{{.Error}}"; }
117 | # fnc_container_lst(){ docker service ps --no-trunc --format "table {{.Node}}\t{{.ID}}\t{{.Names}}\t{{.Error}}" "${1}"; }
118 | # fnc_container_err(){ docker service ps --no-trunc --format "table {{.Node}}\t{{.ID}}\t{{.Names}}\t{{.Error}}" "${1}"; }
119 |
--------------------------------------------------------------------------------
/docker_scripts_setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # external variables used in this script
4 | red=$'\033[38;2;255;000;000m'; export red
5 | orn=$'\033[38;2;255;075;075m'; export orn
6 | ylw=$'\033[38;2;255;255;000m'; export ylw
7 | grn=$'\033[38;2;000;170;000m'; export grn
8 | cyn=$'\033[38;2;085;255;255m'; export cyn
9 | blu=$'\033[38;2;000;120;255m'; export blu
10 | prp=$'\033[38;2;085;085;255m'; export prp
11 | mgn=$'\033[38;2;255;085;255m'; export mgn
12 | wht=$'\033[38;2;255;255;255m'; export wht
13 | blk=$'\033[38;2;025;025;025m'; export blk
14 | def=$'\033[m'; export def
15 |
16 | # script help message check and display when called
17 | fnc_help_scripts_setup(){
18 | echo -e "${blu:?}[-> This script installs Docker HomeLab scripts from 'https://www.gitlab.com/qnap-homelab/docker-scripts'. <-]${def:?}"
19 | echo -e " -"
20 | echo -e " - SYNTAX: # dsup"
21 | echo -e " - SYNTAX: # dsup ${cyn:?}-option${def:?}"
22 | echo -e " - VALID OPTIONS:"
23 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message."
24 | # echo -e " - ${cyn:?}-o | --overwrite ${def:?}│ Does not prompt for overwrite of scripts if they already exist."
25 | echo
26 | exit 1 # Exit script after printing help
27 | }
28 | case "$1" in ("-h"|*"help"*) fnc_help_scripts_setup ;; esac
29 |
30 | ## function definitions
31 | fnc_intro_scripts_setup(){ echo; echo -e "${blu:?}[-> DOCKER HOMELAB TERMINAL SCRIPT INSTALLATION ${ylw:?}STARTING${blu:?} <-]${def:?}"; echo; }
32 | fnc_outro_scripts_setup(){ echo; echo -e "${blu:?}[-> DOCKER HOMELAB TERMINAL SCRIPT INSTALLATION ${grn:?}COMPLETE${blu:?} <-]${def:?}"; echo; }
33 | fnc_invalid_input(){ echo -e "${ylw:?}INVALID INPUT${def:?}: Must be any case-insensitive variation of '(Y)es' or '(N)o'."; }
34 | # fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE ${cyn:?}-help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
35 | # fnc_nothing_to_do(){ echo -e " >> ${ylw:?}DOCKER HOMELAB FILES ALREADY EXIST, AND WILL NOT BE OVERWRITTEN${def:?} << "; echo; }
36 | fnc_check_sudo(){
37 | ## check if user id is 0, if not, set var_sudo
38 | user_id=$(id -u) || { echo "Error getting user id"; exit 1; }
39 | if [[ $user_id -ne 0 ]];
40 | then var_sudo="$(command -v sudo 2>/dev/null)";
41 | else unset var_sudo;
42 | fi;
43 | }
44 | fnc_variable_input(){
45 | unset docker_uid docker_gid exit_code
46 | docker_uid=$(id -u docker 2>/dev/null) || { echo "Error getting docker user id"; return 1; }
47 | docker_gid=$(id -g docker 2>/dev/null) || { echo "Error getting docker group id"; return 1; }
48 | ## ask user to input `docker_uid` and `docker_gid` with defaults of 1000
49 | # echo -e " Currently configured 'docker' user ID: ${orn:?}${docker_uid}${def:?} and docker group ID: ${orn:?}${docker_gid}${def}"
50 | while read -p " ${mgn:?}Confirm${def:?} the 'docker' user ID: ${orn:?}${docker_uid:-UNKNOWN}${def:?} and docker group ID: ${orn:?}${docker_gid:-UNKNOWN}${def}? [Y]es - continue / (N)o - manual entry : " input; do
51 | case "${input}" in
52 | [yY]|[yY][eE][sS]|"")
53 | break ;;
54 | [nN]|[nN][oO])
55 | echo -e " If you want to set the UID and GID manually, enter below, otherwise enter 'n' to exit the script."
56 | read -p " Enter the UID of the docker user [1000]: " input_uid
57 | case "${input_uid}" in
58 | [nN]|[nN][oO])
59 | exit_code=1
60 | break ;;
61 | "")
62 | docker_uid=1000 ;;
63 | *)
64 | if [[ ${input_uid} =~ ^[0-9]+$ ]];
65 | then docker_uid="${input_uid}"
66 | else fnc_invalid_input
67 | fi ;;
68 | esac
69 | read -p " Enter the GID of the docker user [1000]: " input_gid
70 | case "${input_gid}" in
71 | [nN]|[nN][oO])
72 | exit_code=1
73 | break ;;
74 | "")
75 | docker_gid=1000 ;;
76 | *)
77 | if [[ "${input_gid}" =~ ^[0-9]+$ ]]
78 | then docker_gid="${input_gid}"
79 | else fnc_invalid_input
80 | fi ;;
81 | esac ;;
82 | *)
83 | fnc_invalid_input ;;
84 | esac
85 | done;
86 | if [[ exit_code -eq 1 ]]; then
87 | echo -e "\n Look up the correct UID/GID with the '${cyn:?}id -u docker${def:?}' and '${cyn:?}id -g docker${def:?}' commands.\n"
88 | exit 1
89 | fi
90 |
91 | ## ask user to confirm the docker path, updates according to user input
92 | while read -p " Currently configured 'docker' directory is ${cyn:?}${docker_dir}${def:?} Is this correct? [Y]es / (N)o " input; do
93 | case "${input}" in
94 | [yY]|[yY][eE][sS]|"")
95 | break ;;
96 | [nN]|[nN][oO])
97 | read -p " Enter the Docker directory [${docker_dir}]: " input_dkdir ;;
98 | *)
99 | fnc_invalid_input ;;
100 | esac
101 | done
102 |
103 | # docker subfolder path variables
104 | docker_dir="${input_dkdir:-$docker_dir}"; export docker_dir
105 | docker_folder="${docker_folder:-$HOME/docker}"; export docker_folder
106 | docker_appdata="${docker_folder}/appdata"; export docker_appdata
107 | docker_compose="${docker_folder}/compose"; export docker_compose
108 | docker_scripts="${docker_folder}/scripts"; export docker_scripts
109 | docker_secrets="${docker_folder}/secrets"; export docker_secrets
110 | docker_swarm="${docker_folder}/swarm"; export docker_swarm
111 |
112 | ## ask user to confirm media data path, updates according to user input
113 | while read -p " Currently configured Media (Data) path is ${cyn:?}${input_data:-$data_dir}${def:?} Is this correct? [Y]es / (N)o " input; do
114 | case "${input}" in
115 | [yY]|[yY][eE][sS]|"")
116 | break ;;
117 | [nN]|[nN][oO])
118 | read -p " Enter the Media (Data) path [${data_dir}]: " input_data ;;
119 | *)
120 | fnc_invalid_input ;;
121 | esac
122 | done
123 | data_dir="${input_data:-$data_dir}"; export data_dir
124 | }
125 | fnc_create_directory(){
126 | dir_path="${1}";
127 | permissions="${2:-755}";
128 | if [[ -z "${dir_path}" ]]; then
129 | echo -e " ${red:?}ERROR${def:?}: Missing required argument for 'fnc_create_directory' function."; return 1;
130 | fi
131 | if [[ ! -d "${dir_path}" ]]; then ${var_sudo:-} install -o "${docker_uid}" -g "${docker_gid}" -m "${permissions}" -d "${dir_path}"; fi
132 | }
133 | fnc_docker_dir_setup(){
134 | # fnc_check_sudo
135 |
136 | ## folder and file permissions
137 | perms_cert='a-rwx,u=rwX,g=,o='; export perms_cert # 600 # -rw-rw----
138 | perms_conf='a-rwx,u+rwX,g=rwX,o=rX'; export perms_conf # 664 # -rw-rw-r--
139 | perms_data='a-rwx,u+rwX,g=rwX,o='; export perms_data # 660 # -rw-rw----
140 | perms_main='a=rwX,o-w'; export perms_main # 775 # -rwxrwxr-x
141 |
142 | # if [[ ! -d "${docker_folder}" ]]; then
143 | # ${var_sudo:-} install -o "${docker_uid}" -g "${docker_gid}" -m 755 -d "${docker_folder}"
144 | # ${var_sudo:-} chmod g+s "${docker_folder}"
145 | # fi
146 | # if [[ ! -d "${docker_appdata}" ]]; then ${var_sudo:-} install -o "${docker_uid}" -g "${docker_gid}" -m 755 -d "${docker_appdata}"; fi
147 | # if [[ ! -d "${docker_compose}" ]]; then ${var_sudo:-} install -o "${docker_uid}" -g "${docker_gid}" -m 755 -d "${docker_compose}"; fi
148 | # if [[ ! -d "${docker_scripts}" ]]; then ${var_sudo:-} install -o "${docker_uid}" -g "${docker_gid}" -m 776 -d "${docker_scripts}"; fi
149 | # if [[ ! -d "${docker_secrets}" ]]; then ${var_sudo:-} install -o "${docker_uid}" -g "${docker_gid}" -m 660 -d "${docker_secrets}"; fi
150 | # if [[ ! -d "${docker_swarm}" ]]; then ${var_sudo:-} install -o "${docker_uid}" -g "${docker_gid}" -m 755 -d "${docker_swarm}"; fi
151 | fnc_create_directory "${docker_folder}" "${perms_main}" # 755
152 | ${var_sudo:-} chmod g+s "${docker_folder}"
153 | fnc_create_directory "${docker_appdata}" "${perms_data}" # 660
154 | fnc_create_directory "${docker_compose}" "${perms_conf}" # 664
155 | fnc_create_directory "${docker_swarm}" "${perms_conf}" # 664
156 | fnc_create_directory "${docker_scripts}" "${perms_main}" # 775
157 | fnc_create_directory "${docker_secrets}" "${perms_data}" # 660
158 | ## create symlink from $HOME/docker to $docker_folder
159 | if [[ ! -d "$HOME/docker" ]]; then ln -s "${docker_folder}" "$HOME/docker"; fi
160 | ## update the docker_dir variable in this script
161 | ${var_sudo:-} sed -i "s|docker_dir=/opt/docker|docker_dir=${docker_folder}|g" "${docker_scripts}/docker_scripts_setup.sh";
162 | }
163 | fnc_download_scripts(){
164 | # fnc_check_sudo
165 | # download all script files from the qnap-homelab repo to the $docker_scripts directory
166 | ${var_sudo:-} wget -qO - https://api.github.com/repos/qnap-homelab/docker-scripts/tarball/master | ${var_sudo:-} tar -xzf - -C "${docker_scripts}" --strip=1
167 | echo -e " ${grn:?}Successfully${def:?} downloaded docker helper scripts."
168 |
169 | # copy .vars_docker.example to .vars_docker.env
170 | ${var_sudo:-} install -o "${docker_uid}" -g "${docker_gid}" -m "${perms_conf}" "${docker_scripts}/.vars_docker.example" "${docker_scripts}/.vars_docker.env";
171 |
172 | ## update .vars_docker.env with variables input or changed via user input in this script
173 | ${var_sudo:-} sed -i "s|var_uid=1000|var_uid=${docker_uid}|g" "${docker_scripts}/.vars_docker.env";
174 | ${var_sudo:-} sed -i "s|var_gid=1000|var_gid=${docker_gid}|g" "${docker_scripts}/.vars_docker.env";
175 | ${var_sudo:-} sed -i "s|data_dir=/mnt/data|data_dir=${data_dir}|g" "${docker_scripts}/.vars_docker.env";
176 | ${var_sudo:-} sed -i "s|docker_dir=/opt/docker|docker_dir=${docker_dir}|g" "${docker_scripts}/.vars_docker.env";
177 |
178 | # fix ownership of all files and folders inside $docker_scripts
179 | ${var_sudo:-} chown -R "${docker_uid}":"${docker_gid}" -R "${docker_scripts}";
180 | }
181 | fnc_script_prep(){
182 | ## get distribution common name
183 | var_distro="$(awk -F'=' '/^ID=/ { gsub("\"","",$2); print tolower($2) } ' /etc/*-release 2> /dev/null)"
184 | ## check for `docker` folder and link or create if not present
185 | case ${var_distro} in
186 | "qts"|"quts")
187 | unset exit_code
188 | if [[ ! -d "/share/docker" ]] ; then
189 | echo -e " ${red:?}ERROR${def:?}: You must first create the '${cyn:?}docker${def:?}' (${ylw:?}all lowercase${def:?}) Shared Folder in QTS before running this script."
190 | exit_code=1;
191 | fi
192 | if [[ ! -f "/opt/etc/profile" ]] ; then
193 | echo -e " ${red:?}ERROR${def:?}: You must install the '${cyn:?}entware-std${def:?}' from myqnap.org before running this script."
194 | exit_code=1;
195 | fi
196 | if [[ exit_code -eq 1 ]]; then exit 1; fi
197 | data_dir=/share/Multimedia
198 | docker_dir=/share/docker
199 | fnc_variable_input
200 | fnc_docker_dir_setup
201 | ## create symlink from docker_folder to /share/docker for qnap nas only
202 | if [[ -d "/share/docker" ]] && [[ ! -d "${docker_folder}" ]]; then ln -s "/share/docker" "${docker_folder}"; fi
203 | # [[ -d "${docker_folder}" ]] && ln -s "/share/docker" "${docker_folder}"
204 | ## check if /opt/etc/profile automatically loads docker scripts
205 | source="/opt/docker/scripts/docker_commands_list.sh";
206 | line="[ -f ${source} ] && . ${source}";
207 | file="/opt/etc/profile";
208 | grep -qxF "${line}" "${file}" || echo "${line}" >> "${file}";
209 | # ln -s "${file}" "${docker_scripts}"/.profile ## create a symlink to /opt/etc/profile
210 | ;;
211 | *)
212 | data_dir=/mnt/data
213 | docker_dir=/opt/docker
214 | fnc_variable_input
215 | fnc_docker_dir_setup
216 | ;;
217 | esac
218 | ## check if ~/.bashrc automatically loads docker scripts
219 | source="${docker_scripts}/docker_commands_list.sh";
220 | line="[ -f ${source} ] && . ${source}";
221 | file="$HOME/.bashrc";
222 | grep -sqxF "${line}" "${file}" || echo "${line}" >> "${file}";
223 | # create /opt/docker if not present
224 | if [ ! -d "${docker_folder}" ] ; then
225 | # fnc_check_sudo
226 | ${var_sudo:-} install -o "${docker_uid}" -g "${docker_gid}" -m 755 "${docker_folder}";
227 | fi
228 | # ## create symlink from $HOME/docker to docker_folder
229 | # if [[ -d "${docker_folder}" ]] && [[ ! -d "$HOME/docker" ]]; then ln -s "${docker_folder}" "$HOME/docker"; fi
230 | }
231 |
232 | ## script intro message
233 | fnc_intro_scripts_setup
234 |
235 | ## script execution logic
236 | fnc_check_sudo
237 | fnc_script_prep
238 | fnc_download_scripts
239 |
240 | ## script completion message
241 | fnc_outro_scripts_setup
242 |
--------------------------------------------------------------------------------
/docker_service_error.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # function definitions
7 | fnc_help(){
8 | echo -e "${blu:?}[-> This script lists 'current state' for the indicated '${cyn:?}stackname_${cyn:?}servicename${blu:?}' <-]${def:?} "
9 | echo -e " -"
10 | echo -e " - SYNTAX: # dve ${cyn:?}-option${def:?}"
11 | echo -e " - VALID OPTION(S):"
12 | echo -e " - ${cyn:?}-h │ --help ${def:?}| Displays this help message."
13 | echo -e " -"
14 | echo -e " - SYNTAX: # dve ${cyn:?}appname${def:?}"
15 | echo -e " - SYNTAX: # dve ${cyn:?}appname${def:?} ${cyn:?}-option${def:?}"
16 | echo -e " - VALID OPTION(S):"
17 | echo -e " - ${cyn:?}-l │ --long ${def:?}| Displays '${cyn:?}docker service ps --no-trunk ${cyn:?}appname${def:?}' output with non-truncated entries."
18 | echo -e " -"
19 | echo -e " - NOTE: ${cyn:?}appname${def:?} MUST consist of '${cyn:?}stackname_${cyn:?}servicename${def:?}' as defined in the .yml file. ex: 'traefik_app' or 'traefik_whoami'"
20 | echo
21 | exit 1 # Exit script after printing help
22 | }
23 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
24 | fnc_service_basic(){ docker service ps "${1}"; }
25 | fnc_service_check(){ docker service ps "${1}" --format "{{.Error}}"; }
26 | fnc_service_short(){ docker service ps "${1}" --format "table {{.ID}}\t{{.Name}}\t{{.Node}}\t{{.CurrentState}}\t{{.Ports}}"; }
27 | fnc_service_error(){ docker service ps "${1}" --no-trunc --format "table {{.ID}}\t{{.Name}}\t{{.Node}}\t{{.CurrentState}}\t{{.Error}}"; }
28 |
29 | # determine script output according to option entered
30 | case "${1}" in
31 | (-*)
32 | case "${1}" in
33 | ("-h"|"-help"|"--help") fnc_help ;;
34 | (*) fnc_invalid_syntax ;;
35 | esac
36 | ;;
37 | (*)
38 | case "${2}" in
39 | ("-l"|"--long") fnc_service_basic "${1}" ;;
40 | (*)
41 | if [[ ! "$(fnc_service_check "${1}")" ]]
42 | then fnc_service_short "${1}"
43 | else fnc_service_error "${1}"
44 | fi
45 | ;;
46 | esac
47 | ;;
48 | esac
49 |
--------------------------------------------------------------------------------
/docker_service_logs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # function definitions
7 | fnc_help(){
8 | echo -e "${blu:?}[-> This script lists logs for the indicated '${cyn:?}stackname_${cyn:?}servicename${blu:?}' <-]${def:?} "
9 | echo -e " -"
10 | echo -e " - SYNTAX: # dvl ${cyn:?}-option${def:?}"
11 | echo -e " - VALID OPTION(S):"
12 | echo -e " - ${cyn:?}-h │ --help ${def:?}| Displays this help message."
13 | echo -e " -"
14 | echo -e " - SYNTAX: # dvl ${cyn:?}appname${def:?}"
15 | echo -e " - SYNTAX: # dvl ${cyn:?}appname${def:?} ${cyn:?}-option${def:?}"
16 | echo -e " - VALID OPTION(S):"
17 | echo -e " - ${cyn:?}-l │ --long ${def:?}| Displays '${cyn:?}docker service ps --no-trunk ${cyn:?}appname${def:?}' output with non-truncated entries."
18 | echo
19 | echo -e " - NOTE: ${cyn:?}appname${def:?} MUST consist of '${cyn:?}stackname_${cyn:?}servicename${def:?}' as defined in the .yml file. ex: 'traefik_app' or 'traefik_whoami'"
20 | echo
21 | exit 1 # Exit script after printing help
22 | }
23 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
24 | fnc_service_logs(){ docker service logs "${1}"; }
25 | fnc_service_logs_long(){ docker service logs --no-trunc "${1}"; }
26 |
27 | # determine script output according to option entered
28 | case "${1}" in
29 | ("") fnc_invalid_syntax ;;
30 | (-*)
31 | case "${1}" in
32 | ("-h"|"-help"|"--help") fnc_help ;;
33 | (*) fnc_invalid_syntax ;;
34 | esac
35 | ;;
36 | (*)
37 | case "${2}" in
38 | ("-l"|"--long") fnc_service_logs_long "{$1}" ;;
39 | (*) fnc_service_logs "${1}" ;;
40 | esac
41 | ;;
42 | esac
43 |
--------------------------------------------------------------------------------
/docker_stack_bounce.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 | # source /opt/docker/swarm/stackslist-swarm.conf
6 |
7 | # script variable definitions
8 | unset bounce_list IFS
9 |
10 | # function definitions
11 | fnc_help(){
12 | echo -e "${blu:?}[-> This script bounces (removes then re-deploys) a single or pre-defined list of Docker Swarm stack <-]${def:?}"
13 | echo -e " -"
14 | echo -e " - SYNTAX: # dsb ${cyn:?}stack_name${def:?}"
15 | echo -e " - SYNTAX: # dsb ${cyn:?}-option${def:?}"
16 | echo -e " - VALID OPTIONS:"
17 | echo -e " - ${cyn:?}-a | --all ${def:?}│ Bounces all stacks with a corresponding folder inside the '${ylw:?}${docker_swarm}/${def:?}' path."
18 | echo -e " - ${cyn:?}-d | --default ${def:?}│ Bounces the 'default' array of stacks defined in '${ylw:?}${docker_secrets}/${cyn:?}stackslist-swarm.conf${def:?}'"
19 | echo -e " - ${cyn:?}-p | --preset ${def:?}│ Bounces the 'preset' array of stacks defined in '${ylw:?}${docker_secrets}/${cyn:?}stackslist-swarm.conf${def:?}'"
20 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message."
21 | echo
22 | exit 1 # Exit script after printing help
23 | }
24 | fnc_script_intro(){ echo -e "${blu:?}[-> STOP THEN RESTART LISTED CONTAINERS <-]${def:?}"; echo -e "${cyn:?} -> ${bounce_list[*]} ${def:?}"; echo; }
25 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> no containers exist to bounce${def:?}"; }
26 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
27 | fnc_list_all(){ IFS=$'\n'; bounce_list=( $(docker stack ls --format {{.Name}}) ); }
28 | fnc_list_preset(){ IFS=$'\n'; bounce_list=( "${stacks_preset[@]}" ); }
29 | fnc_list_default(){ IFS=$'\n'; bounce_list=( "${stacks_default[@]}" ); }
30 | fnc_docker_stack_stop(){ sh ${docker_scripts}/docker_stack_stop.sh "${bounce_list[@]}"; }
31 | fnc_docker_stack_start(){ sh ${docker_scripts}/docker_stack_start.sh "${bounce_list[@]}"; }
32 | fnc_script_outro(){ echo -e "[-- ${grn:?}BOUNCE (REMOVE & REDEPLOY) STACK SCRIPT COMPLETE${def:?} --]"; echo; }
33 |
34 | # determine script output according to option entered
35 | case "${1}" in
36 | (-*)
37 | case "${1}" in
38 | ("-h"|"-help"|"--help") fnc_help ;;
39 | ("-a"|"--all") fnc_list_all ;;
40 | ("-d"|"--default") fnc_list_default ;;
41 | ("-p"|"--preset") fnc_list_preset ;;
42 | (*) fnc_invalid_syntax ;;
43 | esac
44 | ;;
45 | (*) bounce_list=("$@") ;;
46 | esac
47 |
48 | # # display script intro
49 | # fnc_script_intro
50 | # remove all stacks in list defined above
51 | fnc_docker_stack_stop
52 | # wait 4 sec for ports to fall off assignment
53 | sleep 4
54 | # (re)deploy all stacks in list defined above
55 | fnc_docker_stack_start
56 | # # display script outro
57 | # fnc_script_outro
--------------------------------------------------------------------------------
/docker_stack_folders.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # function definitions
7 | fnc_help(){
8 | echo -e "${blu:?}[-> This script creates ${cyn:?}Drauku's${blu:?} folder structure for the listed stack(s). <-]${def:?}"
9 | echo -e " - ${blu:?}(modified from ${cyn:?}gkoerk's${blu:?} famously awesome folder structure for stacks.)${def:?}"
10 | echo -e " -"
11 | echo -e " - Enter up to nine(9) swarm_stacks in a single command, separated by a 'space' character: "
12 | echo -e " - SYNTAX: dsf ${cyn:?}swarm_stack1${def:?} ${cyn:?}swarm_stack2${def:?} ... ${cyn:?}swarm_stack9${def:?}"
13 | echo -e " - SYNTAX: dsf ${cyn:?}-option${def:?}"
14 | echo -e " - VALID OPTIONS:"
15 | # echo -e " - ${cyn:?}-d │ --delete ${def:?}│ ${red:?}Deletes${def:?} all sub-folders and files in ${ylw:?}${docker_appdata}/${cyn:?}swarm_stack${def:?} & ${ylw:?}${docker_swarm}/${cyn:?}swarm_stack${def:?}"
16 | # echo -e " - ${cyn:?}-r │ --reset ${def:?}│ ${red:?}Deletes${def:?} all files contained in ${ylw:?}${docker_appdata}/${cyn:?}swarm_stack${def:?}"
17 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message."
18 | echo -e " -"
19 | echo -e " - NOTE: The below folder structure is created for each 'swarm_stack' entered with this command:"
20 | echo -e " - ${ylw:?}${docker_appdata}/${cyn:?}swarm_stack${def:?}"
21 | echo -e " - ${ylw:?}${docker_swarm}/${cyn:?}swarm_stack${def:?}"
22 | # echo -e " - ${ylw:?}${swarm_runtime}/${cyn:?}swarm_stack${def:?}"
23 | # echo -e " - ${ylw:?}/share/swarm/secrets/${cyn:?}swarm_stack${def:?}"
24 | echo
25 | exit 1 # Exit script after printing help
26 | }
27 | fnc_script_intro(){ echo -e "${blu:?}[-> CREATE DOCKER SWARM FOLDER STRUCTURE FOR LISTED STACKS <-]${def:?}"; }
28 | fnc_script_outro(){ echo -e "${grn:?} -> FOLDER STRUCTURE CREATED${def:?} FOR LISTED CONTAINERS: "; echo -e " -> ${cyn:?}$1, $2, $3, $4, $5, $6, $7, $8, $9 ${def:?}"; echo; }
29 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> between 1 and 9 names must be entered for this command to work${def:?}"; exit 1; }
30 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
31 | fnc_folder_ownership_msg(){ echo -e " -> ${grn:?}FOLDER OWNERSHIP UPDATED ${def:?}"; echo; }
32 | fnc_folder_ownership_update(){ chown -R ${var_uid}:${var_gid} ${swarm_folder}; chmod 600 -c {$docker_appdata,$docker_swarm}/{$1,$2,$3,$4,$5,$6,$7,$8,$9}; }
33 | fnc_docker_appdata_folders(){ mkdir -p ${docker_appdata}/{$1,$2,$3,$4,$5,$6,$7,$8,$9}; }
34 | fnc_docker_swarm_folders(){ mkdir -p ${docker_swarm}/{$1,$2,$3,$4,$5,$6,$7,$8,$9}; }
35 | fnc_swarm_runtime_folders(){ mkdir -p ${swarm_runtime}/{$1,$2,$3,$4,$5,$6,$7,$8,$9}; }
36 | fnc_swarm_secrets_folders(){ mkdir -p ${swarm_secrets}/{$1,$2,$3,$4,$5,$6,$7,$8,$9}; }
37 | fnc_swarm_folders_create(){ mkdir -p {$docker_appdata,$docker_swarm}/{$1,$2,$3,$4,$5,$6,$7,$8,$9}; }
38 | fnc_swarm_delete_folders(){ rmdir {$docker_appdataa,$docker_swarm}/{$2,$3,$4,$5,$6,$7,$8,$9}; }
39 | fnc_swarm_delete_appdata(){
40 | rm -i ${docker_appdata}/{$2,$3,$4,$5,$6,$7,$8,$9};
41 | while read -r -p " - Also delete the ${ylw:?}${docker_appdata}/${cyn:?}swarm_stack${def:?} folder? [(Y)es/(N)o] " input; do
42 | case "${input}" in
43 | ([yY]|[yY][eE][sS]) fnc_swarm_delete_folders $2 $3 $4 $5 $6 $7 $8 $9 ;;
44 | ([nN]|[nN][oO]) break ;;
45 | (*) fnc_invalid_input ;;
46 | esac
47 | done;
48 | }
49 | fnc_swarm_delete_configs(){
50 | rm -i {$docker_appdata,$docker_swarm}/{$2,$3,$4,$5,$6,$7,$8,$9};
51 | while read -r -p " - Also delete the ${ylw:?}${docker_swarm}/${cyn:?}swarm_stack${def:?} folder? [(Y)es/(N)o] " input; do
52 | case "${input}" in
53 | ([yY]|[yY][eE][sS]) fnc_swarm_delete_folders $2 $3 $4 $5 $6 $7 $8 $9 ;;
54 | ([nN]|[nN][oO]) break ;;
55 | (*) fnc_invalid_input ;;
56 | esac
57 | done;
58 | }
59 |
60 | # output determination logic
61 | case "${1}" in
62 | ("") fnc_nothing_to_do ;;
63 | (-*) # validate and perform option
64 | case "${1}" in
65 | ("-h"|"-help"|"--help")
66 | fnc_help ;;
67 | ("-d"|"-del"|"--delete")
68 | fnc_swarm_delete_configs $2 $3 $4 $5 $6 $7 $8 $9 ;;
69 | ("-r"|"-res"|"--reset")
70 | fnc_swarm_delete_appdata $2 $3 $4 $5 $6 $7 $8 $9 ;;
71 | (*)
72 | fnc_invalid_syntax ;;
73 | esac
74 | ;;
75 | (*)
76 | case "${2}" in
77 | (-*)
78 | # tmpvar="${2}"; 2="${1}"; 1="${tmpvar}"; unset tmpvar IFS;
79 | tmp2="${2}"; set -- "${1}"; set -- "${tmp2}"; unset tmp2 IFS;
80 | case "${1}" in
81 | ("-h"|"-help"|"--help")
82 | fnc_help ;;
83 | ("-d"|"-del"|"--delete")
84 | fnc_swarm_delete_configs $2 $3 $4 $5 $6 $7 $8 $9 ;;
85 | ("-r"|"-res"|"--reset")
86 | fnc_swarm_delete_appdata $2 $3 $4 $5 $6 $7 $8 $9 ;;
87 | (*)
88 | fnc_invalid_syntax ;;
89 | esac
90 | fnc_swarm_folders_create $1 $2 $3 $4 $5 $6 $7 $8 $9
91 | # Create folder structure
92 | # fnc_swarm_appdata_folders $1 $2 $3 $4 $5 $6 $7 $8 $9
93 | # fnc_swarm_configs_folders $1 $2 $3 $4 $5 $6 $7 $8 $9
94 | # fnc_swarm_runtime_folders $1 $2 $3 $4 $5 $6 $7 $8 $9 # disabled due to not being used
95 | # fnc_swarm_secrets_folders $1 $2 $3 $4 $5 $6 $7 $8 $9 # disabled due to not being used
96 | # fnc_folder_ownership_update $1 $2 $3 $4 $5 $6 $7 $8 $9
97 | # fnc_folder_ownership_msg
98 | # fnc_script_outro
99 | esac
100 | ;;
101 | esac
102 |
--------------------------------------------------------------------------------
/docker_stack_start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 | # source /opt/docker/swarm/stackslist-swarm.conf
6 |
7 | # script variable definitions
8 | unset config_list IFS
9 | unset deploy_list IFS
10 |
11 | # function definitions
12 | fnc_help(){
13 | echo -e "${blu:?}[-> This script deploys a single stack or a pre-defined list of Docker Swarm stack <-]${def:?}"
14 | echo -e " -"
15 | echo -e " - SYNTAX: # dsd ${cyn:?}stack_name${def:?}"
16 | echo -e " - SYNTAX: # dsd ${cyn:?}-option${def:?}"
17 | echo -e " - VALID OPTIONS:"
18 | echo -e " - ${cyn:?}-a │ --all ${def:?}│ Deploys all stacks with a corresponding .yml config file inside the '${ylw:?}${docker_swarm}/${def:?}' path."
19 | echo -e " - ${cyn:?}-d │ --default ${def:?}│ Deploys the '${cyn:?}default${def:?}' array of stacks defined in '${ylw:?}${docker_vars}/${cyn:?}swarm_stacks.conf${def:?}'"
20 | echo -e " - ${cyn:?}-p │ --preset ${def:?}│ Deploys the '${cyn:?}preset${def:?}' array of stacks defined in '${ylw:?}${docker_vars}/${cyn:?}swarm_stacks.conf${def:?}'"
21 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message."
22 | echo
23 | exit 1 # Exit script after printing help
24 | }
25 | fnc_deploy_all(){ IFS=$'\n'; deploy_list=( $(cd "${docker_swarm}" && find -maxdepth 1 -type d -not -path '*/\.*' | sed 's/^\.\///g') ); }
26 | fnc_deploy_bounce(){ IFS=$'\n'; deploy_list=("${bounce_list[@]}"); }
27 | fnc_deploy_preset(){ IFS=$'\n'; deploy_list=("${stacks_preset[@]}"); }
28 | fnc_deploy_default(){ IFS=$'\n'; deploy_list=("${stacks_default[@]}"); }
29 | fnc_deploy_list_cleanup(){
30 | if [[ ! "${bounce_list[*]}" ]]; then fnc_deploy_all
31 | for stack in "${!deploy_list[@]}"; do
32 | if [[ "${deploy_list[stack]}" = "." ]]; then unset deploy_list[stack]; fi
33 | if [[ -f "${docker_swarm}/${deploy_list[stack]}/${deploy_list[stack]}${conftype}.yml" ]]; then config_list="${config_list} ${deploy_list[stack]}"; fi
34 | done
35 | unset deploy_list IFS; IFS=$'\n'; deploy_list=("${config_list[@]}"); unset config_list IFS
36 | else fnc_deploy_bounce
37 | fi;
38 | }
39 |
40 | # determine script output according to option entered
41 | case "${1}" in
42 | (-*)
43 | case "${1}" in
44 | ("-h"|"-help"|"--help")
45 | fnc_help
46 | ;;
47 | ("-a"|"--all")
48 | if [[ "${bounce_list[*]}" = "" ]]; then
49 | IFS=$'\n'; deploy_list=( $(cd "${docker_swarm}" && find -maxdepth 1 -type d -not -path '*/\.*' | sed 's/^\.\///g') );
50 | for stack in "${!deploy_list[@]}"; do
51 | if [[ "${deploy_list[stack]}" = "." ]]; then unset deploy_list[stack]; fi
52 | if [[ -f "${docker_swarm}/${deploy_list[stack]}/${deploy_list[stack]}${conftype}.yml" ]];
53 | then config_list="${config_list} ${deploy_list[stack]}"
54 | fi
55 | done
56 | unset deploy_list IFS
57 | IFS=$'\n'; deploy_list=("${config_list[@]}");
58 | unset config_list IFS
59 | else fnc_deploy_bounce
60 | fi
61 | ;;
62 | ("-p"|"--preset")
63 | fnc_deploy_preset
64 | ;;
65 | ("-d"|"--default")
66 | fnc_deploy_default
67 | ;;
68 | (*)
69 | echo -e "${ylw:?} >> INVALID OPTION SYNTAX -- USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1 ;;
70 | esac
71 | ;;
72 | (*)
73 | deploy_list=("$@")
74 | ;;
75 | esac
76 |
77 | # remove duplicate entries in deploy_list
78 | # echo -e "${blu:?}[-> DEPLOYING LISTED STACK(S) <-]${def:?}"
79 | deploy_list=(`for stack in "${deploy_list[@]}" ; do echo "${stack}" ; done | sort -u`)
80 | if [[ ! "$(docker network ls --filter name="${var_net_rproxy}" -q)" ]]; then
81 | docker network create --driver=overlay --subnet=${var_subnet_rproxy} --attachable ${var_net_rproxy}
82 | # Pause until 'network create' operation is finished
83 | while [[ ! "$(docker network ls --filter name=${var_net_rproxy} -q)" ]]; do sleep 1; done
84 | echo -e " -> '${cyn:?}${var_net_rproxy}${def:?}' OVERLAY NETWORK ${grn:?}CREATED${def:?}"
85 | echo
86 | fi
87 |
88 | # perform stack setup and deployment tasks
89 | for stack in "${deploy_list[@]}"; do
90 | # check if indicated stack configuration file exists, otherwise exit
91 | if [[ -f "${docker_swarm}/${stack}/${conftype}.yml" ]]; then
92 | # echo -e "${cyn:?} -> DEPLOY '${cyn:?}${stack}${cyn:?}' STACK <-${def:?}"
93 | # check if required folders exist, create if missing
94 | if [[ ! -d "${docker_appdata}/${stack}" || ! -d "${docker_swarm}/${stack}" ]]; then
95 | echo -e "Creating ${ylw:?}Required folders${def:?}"
96 | . "${docker_scripts}/docker_stack_folders.sh" "${stack}"
97 | fi
98 | # check for required traefik files, create if missing
99 | if [[ "${stack}" = [tT][rR][aA][eE][fF][iI][kK] ]]; then
100 | # create required letsencrypt certificate file if not already made
101 | if [[ ! -f "${docker_appdata}/traefik/acme.json" ]]; then
102 | echo -e "Creating ${ylw:?}Required cert file${def:?}"
103 | mkdir -p "${docker_appdata}/traefik"
104 | touch "${docker_appdata}/traefik/acme.json"
105 | chmod 600 "${docker_appdata}/traefik/acme.json"
106 | fi
107 | # check if required log files exist, create if missing
108 | if [[ ! -f "${docker_appdata}/${stack}/access.log" || ! -f "${docker_appdata}/${stack}/${stack}.log" ]]; then
109 | echo -e "Creating ${ylw:?}Required log file(s)${def:?}"
110 | touch "${docker_appdata}/${stack}/{access.log,${stack}.log"}
111 | chmod 600 "${docker_appdata}/${stack}/{access.log,${stack}.log"}
112 | fi
113 | fi
114 | # deploy the requested stack
115 | # docker stack deploy "${stack}" -c "${docker_swarm}/${stack}/${conftype}.yml" --prune
116 | docker stack deploy "${stack}" -c "${docker_swarm}/${stack}/${conftype}.yml" --prune
117 | sleep 1
118 | if [[ ! "$(docker service ls --filter name="${stack}" -q)" ]]; then
119 | echo -e " ${red:?}ERROR${def:?}: '${cyn:?}${stack}${def:?}' ${ylw:?}*NOT* DEPLOYED${def:?}"; echo
120 | else
121 | # Pause until stack is deployed
122 | while [ ! "$(docker service ls --filter label=com.docker.stack.namespace=$stack -q)" ];
123 | do sleep 1; done
124 | echo -e "${grn:?} ++ '${cyn:?}$stack${grn:?}' STACK ${grn:?}DEPLOYED${grn:?} ++ ${def:?}"; echo
125 | fi
126 | else echo -e " ${red:?}ERROR${def:?}: '${cyn:?}${stack}${def:?}' ${ylw:?}CONFIG FILE DOES NOT EXIST${def:?}"; echo
127 | fi
128 | done
129 |
130 | # print script complete message
131 | # echo
132 | # echo -e "${grn:?}[>> STACK DEPLOY SCRIPT COMPLETE <<]${def:?}"
133 | # echo
--------------------------------------------------------------------------------
/docker_stack_stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 | # source /opt/docker/swarm/.swarm_stacks.conf
6 |
7 | # script variable definitions
8 | unset remove_list IFS
9 |
10 | # function definitions
11 | fnc_help(){
12 | echo -e "${blu:?}[-> This script removes a single or pre-defined list of Docker Swarm stack(s) <-]${def:?}"
13 | echo -e " -"
14 | echo -e " - SYNTAX: # dsr ${cyn:?}stack_name${def:?}"
15 | echo -e " - SYNTAX: # dsr ${cyn:?}-option${def:?}"
16 | echo -e " - VALID OPTIONS:"
17 | echo -e " - ${cyn:?}-a | --all ${def:?}│ ${ylw:?}CAUTION${def:?}: Removes ${BLD}all${def:?} stacks currently listed with 'docker stack ls' command."
18 | echo -e " - ${cyn:?}-d | --default ${def:?}│ Removes the '${cyn:?}default${def:?}' array of stacks defined in '${ylw:?}${docker_vars}/${cyn:?}swarm_stacks.conf${def:?}'"
19 | echo -e " - ${cyn:?}-p | --preset ${def:?}│ Removes the '${cyn:?}preset${def:?}' array of stacks defined in '${ylw:?}${docker_vars}/${cyn:?}swarm_stacks.conf${def:?}'"
20 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message."
21 | echo
22 | exit 1 # Exit script after printing help
23 | }
24 | fnc_script_intro(){ echo -e "${blu:?}[-> REMOVE THE INDICATED DOCKER STACK(S) <-]${def:?}"; }
25 | fnc_script_outro(){ echo -e "${grn:?}[>> STACK REMOVE SCRIPT COMPLETE <<]${def:?}"; echo; }
26 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> between 1 and 9 names must be entered for this command to work${def:?}"; exit 1; }
27 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
28 |
29 | # fnc_stack_remove_list(){ ; }
30 |
31 | fnc_docker_service_list(){ docker service ls --filter label=com.docker.stack.namespace=$stack -q; }
32 | fnc_docker_network_list(){ docker network ls --filter label=com.docker.stack.namespace=$stack -q; }
33 |
34 | fnc_msg_no_stacks(){ echo -e "${ylw:?} -> no docker stacks to remove${def:?}"; echo; }
35 | fnc_stack_remove_error(){ echo -e " ${red:?}ERROR: ${ylw:?}STACK NAME${def:?} '${cyn:?}$stack${def:?}' ${ylw:?}NOT FOUND${def:?} "; echo; }
36 | fnc_stack_remove_success(){ echo -e "${red:?} -- '${cyn:?}$stack${red:?}' STACK ${red:?}REMOVED${red:?} -- ${def:?}"; echo; }
37 |
38 | # determine script output according to option entered
39 | case "${1}" in
40 | (-*)
41 | case "${1}" in
42 | ("-h"|"-help"|"--help") fnc_help ;;
43 | ("-a"|"--all") IFS=$'\n'; remove_list=("$(docker stack ls --format {{.Name}})") ;;
44 | ("-d"|"--default") IFS=$'\n'; remove_list=("${stacks_default[@]}") ;;
45 | ("-p"|"--preset") IFS=$'\n'; remove_list=("${stacks_preset[@]}") ;;
46 | (*) fnc_invalid_syntax ;;
47 | esac
48 | ;;
49 | (*) remove_list=("$@") ;;
50 | esac
51 |
52 | # Remove indicated stacks
53 | # echo -e "${blu:?}[-> REMOVING LISTED STACK(S) <-]${def:?}"
54 | # de-duplicate and remove carriage returns in remove_list entries
55 | remove_list=(`for stack in "${remove_list[@]}"; do echo "${stack}"; done | sort -u`)
56 | # echo " -> ${remove_list[@]}"; echo
57 |
58 | # Remove indicated stack(s)
59 | if [[ ! "${remove_list}" ]]
60 | then fnc_msg_no_stacks
61 | else
62 | for stack in "${remove_list[@]}"; do
63 | if [ ! "$(fnc_docker_service_list)" ];
64 | then fnc_stack_remove_error
65 | else # echo -e "${cyn:?} -> REMOVE '${cyn:?}$stack${cyn:?}' STACK <-${def:?}"
66 | docker stack rm "$stack"
67 | #[ -f "${docker_swarm}/${stack}/.env" ] && rm -f "${docker_swarm}/${stack}/.env"
68 | # Pause until stack is removed
69 | while [ "$(fnc_docker_service_list)" ] || [ "$(fnc_docker_network_list)" ]
70 | do sleep 1;
71 | done
72 | fnc_stack_remove_success
73 | fi
74 | done
75 | fi
76 |
77 | # fnc_script_outro
--------------------------------------------------------------------------------
/docker_swarm_init.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # script variable definitions
7 | unset deploy_list IFS
8 |
9 | # function definitions
10 | fnc_help(){
11 | echo -e "${blu:?}[-> This script performs Docker Swarm initialization tasks on QNAP Container Station architecture. <-]${def:?}"
12 | echo -e " -"
13 | echo -e " - SYNTAX: # dwinit"
14 | echo -e " - SYNTAX: # dwinit ${cyn:?}-option${def:?}"
15 | echo -e " - VALID OPTIONS:"
16 | echo -e " - ${cyn:?}stackname ${def:?}│ Creates the Docker Swarm, then deploys the '${cyn:?}stackname${def:?}' swarm stack if a config file exists."
17 | echo -e " - ${cyn:?}-a | --all ${def:?}│ Creates the Docker Swarm, then deploys all stacks with a corresponding folder inside the '${ylw:?}${docker_swarm}/${def:?}' path."
18 | echo -e " - ${cyn:?}-d | --default ${def:?}│ Creates the Docker Swarm, then deploys the 'default' array of stacks defined in '${ylw:?}${docker_vars}/${cyn:?}swarm_stacks.conf${def:?}'"
19 | echo -e " - ${cyn:?}-p | --preset ${def:?}│ Creates the Docker Swarm, then deploys the 'preset' array of stacks defined in '${ylw:?}${docker_vars}/${cyn:?}swarm_stacks.conf${def:?}'"
20 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message."
21 | echo
22 | exit 1 # Exit script after printing help
23 | }
24 | fnc_script_intro(){ echo -e "${blu:?}[-> INITIALIZE DOCKER SWARM AND INSTALL INDICATED STACKS <-]${def:?}"; }
25 | fnc_script_outro(){ echo -e "${grn:?}[-> DOCKER SWARM INITIALIZATION SCRIPT COMPLETE <-]${def:?}"; echo; }
26 | fnc_invalid_input(){ echo -e "${ylw:?}INVALID INPUT${def:?}: Must be any case-insensitive variation of '(Y)es' or '(N)o'."; }
27 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
28 | fnc_nothing_to_do(){ echo -e " >> ${ylw:?}SWARM STACKS WILL NOT BE DEPLOYED${def:?} << "; echo; }
29 | fnc_deploy_query(){ echo -e "Do you want to deploy the '-${cyn:?}default${def:?}' list of Docker Swarm stacks?"; }
30 | fnc_deploy_stack(){ if [ ! "${deploy_list}" ] || [ "${deploy_list}" = "-n" ]; then fnc_nothing_to_do; else sh "${docker_scripts}"/docker_stack_start.sh "${deploy_list}"; fi; }
31 | fnc_traefik_query(){ echo -e " - Should ${cyn:?}traefik${def:?} still be installed (${ylw:?}recommended${def:?})?"; }
32 | fnc_folder_creation(){ if [[ ! -d "${docker_folder}/{scripts,secrets,swarm,compose}" ]]; then mkdir -pm 600 "${docker_folder}"/{scripts,secrets,swarm/{appdata,configs},compose/{appdata,configs}}; fi; }
33 | fnc_folder_owner(){ chown -R ${var_user}:${var_group} ${swarm_folder}; echo "FOLDER OWNERSHIP UPDATED"; echo; }
34 | fnc_folder_auth(){ chmod -R 600 ${swarm_folder}; echo "FOLDER PERMISSIONS UPDATED"; echo; }
35 | fnc_swarm_init(){ docker swarm init --advertise-addr "${var_host_ip}"; }
36 | fnc_swarm_verify(){ while [[ "$(docker stack ls)" != "NAME SERVICES ORCHESTRATOR" ]]; do sleep 1; done; }
37 | # fnc_swarm_check(){ while [[ ! "$(docker stack ls --format "{{.Name}}")" ]]; do sleep 1; done; }
38 | fnc_swarm_success(){ echo; echo -e " >> ${grn:?}DOCKER SWARM INITIALIZED SUCCESSFULLY${def:?} << "; echo; }
39 | fnc_swarm_error(){
40 | docker network ls
41 | echo
42 | echo -e " >> THE ABOVE LIST MUST INCLUDE THE '${cyn:?}docker_gwbridge${def:?}' AND '${cyn:?}${var_net_rproxy}${def:?}' NETWORKS"
43 | echo -e " >> IF EITHER OF THOSE NETWORKS ARE NOT LISTED, YOU MUST LEAVE, THEN RE-INITIALIZE THE SWARM"
44 | echo -e " >> IF YOU HAVE ALREADY ATTEMPTED TO RE-INITIALIZE, ASK FOR HELP HERE: ${mgn:?} https://discord.gg/KekSYUE ${def:?}"
45 | echo
46 | echo -e " >> ${ylw:?}DOCKER SWARM STACKS WILL NOT BE DEPLOYED${def:?} << "
47 | echo
48 | echo -e " -- ${red:?}ERROR${def:?}: DOCKER SWARM SETUP WAS ${ylw:?}NOT SUCCESSFUL${def:?} -- "
49 | exit 1 # Exit script here
50 | }
51 | fnc_network_gwbridge(){
52 | docker network rm docker_gwbridge
53 | docker network create --driver bridge --scope local --opt encrypted --subnet 172.20.0.0/16 --gateway 172.20.0.254 \
54 | --opt com.docker.network.bridge.enable_icc=false \
55 | --opt com.docker.network.bridge.enable_ip_masquerade=true \
56 | --opt com.docker.network.bridge.name=docker_gwbridge \
57 | docker_gwbridge
58 | }
59 | # docker network rm ingress
60 | # docker network create --driver overlay --opt encrypted --ingress --subnet 10.27.0.0/16 --gateway 10.27.0.254 ingress
61 | # docker network create --driver overlay --opt encrypted --scope swarm --subnet=172.27.0.0/16 --gateway=172.27.0.254 --attachable docker_socket
62 | # docker network create --driver overlay --opt encrypted --scope swarm --subnet=172.27.1.0/16 --gateway=172.27.1.254 --attachable external_edge
63 | # docker network create --driver overlay --opt encrypted --scope swarm --subnet=172.27.2.0/16 --gateway=172.27.2.254 --attachable reverse_proxy
64 | fnc_network_init(){ # copy fnc_network_check from docker/scripts/docker_system_network.sh
65 | docker network rm ingress && docker network create --driver overlay --opt encrypted --ingress --subnet "${var_subnet_ingress}" --gateway "${var_gateway_ingress}" ${var_net_ingress};
66 | docker network create --driver overlay --opt encrypted --scope swarm --subnet "${var_subnet_socket}" --gateway "${var_gateway_socket}" --attachable "${var_net_socket}";
67 | docker network create --driver overlay --opt encrypted --scope swarm --subnet "${var_subnet_rproxy}" --gateway "${var_gateway_rproxy}" --attachable "${var_net_rproxy}";
68 | docker network create --driver overlay --opt encrypted --scope swarm --subnet "${var_subnet_exedge}" --gateway "${var_gateway_exedge}" --attachable "${var_net_exedge}";
69 | }
70 | fnc_network_check_dockersocket(){ docker network ls --filter name="${var_net_socket}" -q; }
71 | fnc_network_check_proxynet(){ docker network ls --filter name="${var_net_rproxy}" -q; }
72 | fnc_network_check_gwbridge(){ docker network ls --filter name=docker_gwbridge -q; }
73 | fnc_network_verify(){
74 | unset increment IFS;
75 | while [[ ! "$(fnc_network_check_proxynet)" ]] || [[ ! "$(fnc_network_check_gwbridge)" ]];
76 | do sleep 1;
77 | increment=$((increment+1)); # should it be '$increment++'?
78 | if [[ $increment -gt 10 ]];
79 | then fnc_swarm_error;
80 | fi;
81 | done;
82 | }
83 | fnc_network_success(){ echo; echo -e " ++ ${grn:?}CREATED '${cyn:?}docker_gwbridge${grn:?}' AND '${cyn:?}${var_net_rproxy}${grn:?}' NETWORKS${def:?} ++ "; }
84 |
85 | # fnc_script_intro
86 |
87 | # determine script output according to option entered
88 | case "${1}" in
89 | ("") fnc_deploy_query
90 | while read -r -p " [(Y)es/(N)o] " input; do
91 | case "${input}" in
92 | ([yY]|[yY][eE][sS]) deploy_list="--default"; break ;;
93 | ([nN]|[nN][oO]) fnc_traefik_query
94 | while read -r -p " [(Y)es/(N)o] " confirm; do
95 | case "${confirm}" in
96 | ([yY]|[yY][eE][sS]) deploy_list="traefik"; break ;;
97 | ([nN]|[nN][oO]) break ;;
98 | (*) fnc_invalid_input ;;
99 | esac
100 | done
101 | break ;;
102 | (*) fnc_invalid_input ;;
103 | esac
104 | done
105 | echo
106 | ;;
107 | (-*) # confirm entered option switch is valid
108 | case "${1}" in
109 | ("-h"|"-help"|"--help") fnc_help ;;
110 | ("-a"|"--all") deploy_list="${1}" ;;
111 | ("-d"|"--default") deploy_list="${1}" ;;
112 | ("-p"|"--preset") deploy_list="${1}" ;;
113 | ("-n"|"--none") deploy_list="-n" ;;
114 | (*) fnc_invalid_syntax ;;
115 | esac
116 | ;;
117 | (*) deploy_list=("$@") ;;
118 | esac
119 |
120 | fnc_folder_creation
121 | # fnc_folder_owner
122 | # fnc_folder_auth
123 |
124 | # must remove and recreate docker_gwbridge before swarm init to make it encrypted
125 | # fnc_network_gwbridge
126 | fnc_swarm_init
127 | fnc_swarm_verify
128 |
129 | fnc_network_init
130 | fnc_network_verify
131 | fnc_network_success
132 |
133 | fnc_swarm_success
134 |
135 | fnc_deploy_stack
136 |
137 | fnc_script_outro
138 |
139 |
140 |
141 | ## from docker_scripts_setup:
142 |
143 |
144 | # # Swarm initialization
145 | # #echo -e " -> INITIALIZING SWARM <- "
146 | # docker swarm init --advertise-addr "${var_host_ip}"
147 |
148 | # # Required networks creation verification
149 | # docker network create --driver=overlay --subnet=${var_subnet_rproxy} --attachable ${var_net_rproxy}
150 | # increment=0; # reset the increment variable
151 | # while [[ "$(docker network ls --filter name=traefik -q)" = "" ]] || [[ "$(docker network ls --filter name=gwbridge -q)" = "" ]]; do
152 | # sleep 1;
153 | # increment=$(($increment+1));
154 | # if [[ $increment -gt 10 ]]; then # max 10 seconds wait for network to be created
155 | # docker network ls
156 | # echo
157 | # echo -e " ->> THE ABOVE LIST MUST INCLUDE THE '${cyn:?}docker_gwbridge${def:?}' AND '${cyn:?}traefik_public${def:?}' NETWORKS"
158 | # echo -e " ->> IF EITHER OF THOSE NETWORKS ARE NOT LISTED, YOU MUST LEAVE, THEN RE-INITIALIZE THE SWARM"
159 | # echo -e " ->> IF YOU HAVE ALREADY ATTEMPTED TO RE-INITIALIZE, ASK FOR HELP HERE: ${mgn:?} https://discord.gg/KekSYUE ${def:?}"
160 | # echo
161 | # echo -e " ->> ${ylw:?}DOCKER SWARM STACKS WILL NOT BE DEPLOYED${def:?} << "
162 | # echo
163 | # echo -e " --- ${red:?}ERROR${def:?}: DOCKER SWARM SETUP WAS ${ylw:?}NOT SUCCESSFUL${def:?} -- "
164 | # exit 1 # Exit script here
165 | # fi
166 | # done
167 | # # while [[ "$(docker network ls --filter name=traefik_public -q)" = "" ]]; do sleep 1; done
168 | # # while [[ "$(docker network ls --filter name=docker_gwbridge -q)" = "" ]]; do sleep 1; done
169 | # echo
170 | # echo -e " ++ '${cyn:?}docker_gwbridge${def:?}' AND '${cyn:?}traefik_public${def:?}' NETWORKS ${grn:?}CREATED${def:?} ++ "
171 |
172 | # # Pause until swarm is initialized
173 | # while [[ "$(docker stack ls)" != "NAME SERVICES" ]]; do sleep 1; done
174 | # echo
175 | # echo -e " >> ${grn:?}SWARM INITIALIZED${def:?} << "
176 | # echo
177 |
178 | # # Stack deployment
179 | # if [[ "$1" = "" ]]; then
180 | # case "${input}" in
181 | # ([yY]|[yY][eE][sS])
182 | # . "${docker_scripts}"/docker_stack_start.sh -default
183 | # ;;
184 | # ([nN]|[nN][oO])
185 | # case "${confirm}" in
186 | # ([yY]|[yY][eE][sS])
187 | # . "${docker_scripts}"/docker_stack_start.sh traefik
188 | # ;;
189 | # (*) echo -e " >> ${ylw:?}DOCKER SWARM STACKS WILL NOT BE DEPLOYED${def:?} << " ;;
190 | # esac
191 | # ;;
192 | # esac
193 | # else
194 | # . "${docker_scripts}"/docker_stack_start.sh "$1"
195 | # fi
196 |
197 |
198 | # if [[ "$1" = "" ]] ; then
199 | # printf "Do you want to deploy the '-${cyn:?}default${def:?}' list of Docker Swarm stacks?"; read -r -p " [(Y)es/(N)o] " input
200 | # case $input in
201 | # ([yY]|[yY][eE][sS]) ;;
202 | # ([nN]|[nN][oO])
203 | # # Query if Traefik should still be deployed
204 | # printf " - Should ${cyn:?}traefik${def:?} still be installed (${ylw:?}recommended${def:?})?"; read -r -p " [(Y)es/(N)o] " confirm
205 | # case $input in
206 | # ([yY]|[yY][eE][sS]) ;;
207 | # ([nN]|[nN][oO]) ;;
208 | # (*) echo -e "${ylw:?}INVALID INPUT${def:?}: Must be any case-insensitive variation of 'yes' or 'no'." ;;
209 | # esac
210 | # ;;
211 | # (*) echo -e "${ylw:?}INVALID INPUT${def:?}: Must be any case-insensitive variation of 'yes' or 'no'." ;;
212 | # esac
213 | # echo
214 | # fi
215 |
216 |
--------------------------------------------------------------------------------
/docker_swarm_leave.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # function definitions
7 | fnc_help(){
8 | echo -e "${blu:?}[-> This script leaves a Docker Swarm environment and removes a list of stacks on QNAP Container Station architecture. <-]${def:?}"
9 | echo -e " -"
10 | echo -e " - SYNTAX: # dwlv"
11 | echo -e " - SYNTAX: # dwlv ${cyn:?}-option${def:?}"
12 | echo -e " - VALID OPTIONS:"
13 | echo -e " - ${cyn:?}-a | --all ${def:?}│ ${ylw:?}CAUTION${def:?}: Removes ${BLD}all${def:?} stacks currently listed with ${cyn:?}'docker stack ls'${def:?} command, then laves the Swarm."
14 | echo -e " - ${cyn:?}-n | --none ${def:?}│ Leaves the Docker Swarm, but Does ${BLD}*NOT*${def:?} remove any currently deployed stacks."
15 | echo -e " - ${cyn:?}-h | --help ${def:?}│ Displays this help message."
16 | echo
17 | exit 1 # Exit script after printing help
18 | }
19 | fnc_script_intro(){ echo -e "${blu:?}[-> LEAVING THE DOCKER SWARM AND REMOVING INDICATED STACKS <-]${def:?}"; }
20 | fnc_script_outro(){ echo -e "${grn:?}[-> DOCKER SWARM LEAVE SCRIPT COMPLETE <-]${def:?}"; echo; }
21 | fnc_nothing_to_do(){ echo -e "${ylw:?}[-> THIS NODE IS NOT PART OF A SWARM, CANNOT LEAVE NON-EXISTENT SWARM <-]${def:?}"; echo; }
22 | fnc_invalid_input(){ echo -e "${ylw:?}INVALID INPUT${def:?}: Must be any case-insensitive variation of '(Y)es' or '(N)o'."; }
23 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
24 | fnc_remove_all_query(){ echo -e " Do you want to remove all Docker Swarm stacks (${ylw:?}highly recommended${def:?})? "; }
25 | fnc_msg_suggest_cleaning(){ echo -e "${ylw:?} >> CLEANING THE DOCKER ENVIRONMENT (${cyn:?}dprn${ylw:?}/${cyn:?}dcln${ylw:?}) AFTER LEAVING A SWARM IS RECOMMENDED <<${def:?}"; echo; }
26 | fnc_msg_stack_not_removed(){ echo -e " >> ${ylw:?}DOCKER SWARM STACKS WILL NOT BE REMOVED${def:?} << "; }
27 | fnc_swarm_check(){ if [[ "$(docker swarm leave -f)" == "Error response from daemon: This node is not part of a swarm" ]]; then fnc_nothing_to_do; exit 1; fi; }
28 | fnc_swarm_leave_force(){ docker swarm leave -f; echo; }
29 | fnc_docker_stack_stop(){ sh ${docker_scripts}/docker_stack_stop.sh -all; }
30 | fnc_docker_system_prune(){ sh ${docker_scripts}/docker_system_prune.sh --all; }
31 | fnc_docker_system_cleanup(){ if [[ "$input" = "yes" ]]; then fnc_docker_system_prune; else fnc_msg_suggest_cleaning; fi; }
32 |
33 | # determine script output according to option entered
34 | case "${1}" in
35 | ("") # fnc_script_intro
36 | # fnc_swarm_check
37 | fnc_remove_all_query
38 | while read -r -p " [(Y)es/(N)o] " input; do
39 | case "${input}" in
40 | ([yY]|[yY][eE][sS]) break ;;
41 | ([nN]|[nN][oO]) break ;;
42 | (*) fnc_invalid_input ;;
43 | esac
44 | done
45 | echo
46 | ;;
47 | (-*) # confirm entered option is valid
48 | case "${1}" in
49 | ("-h"|"-help"|"--help") fnc_help ;;
50 | ("-a"|"--all") input="yes" ;;
51 | ("-n"|"--none") input="no" ;;
52 | (*) fnc_invalid_syntax ;;
53 | esac
54 | ;;
55 | esac
56 |
57 | # Remove stacks if input is Yes
58 | case $input in
59 | ([yY][eE][sS]|[yY]) fnc_docker_stack_stop ;;
60 | ([nN][oO]|[nN]) fnc_msg_stack_not_removed ;;
61 | esac
62 |
63 | # Leave the swarm
64 | fnc_swarm_leave_force
65 | fnc_docker_system_cleanup
66 | fnc_script_outro
67 |
--------------------------------------------------------------------------------
/docker_system_backup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # home\drauku\docker_backup.sh
3 | # USAGE: docker_backup.sh
4 | # DESCRIPTION: This script will create an archive of the local docker folders and copy it to a remote server.
5 | # AUTHOR: Drauku
6 |
7 | # SET THESE VARIABLES IN ADVANCE IF YOU DO NOT WANT TO ANSWER THE PROMPTS
8 | archive_target="" #"local"
9 | backup_path="" #"$docker_path/backup"
10 | server_ip="" #"192.168.1.150"
11 | username="" #"admin"
12 |
13 | query_docker_paths(){ # Query for the docker config file paths
14 | echo -e "\nThis script creates a docker folder archive and optionally copies the archive to a remote server."
15 | echo -e "NOTE: This host must be set up to use SSH keys with the remote host.\n"
16 | read -r -p "Enter the path to the docker config directory [~/.docker]: " docker_path
17 | docker_path=${docker_path:-~/.docker}
18 | }
19 |
20 | set_list_of_containers(){ # Set the list of containers to be stopped and backed up
21 | # Unset variable container_list
22 | unset container_list
23 |
24 | # Store the output of `docker container list` into `container_list`
25 | # TODO: determine which of these methods works best to populate `container_list`
26 | # IFS=$'\n' container_list=( $(docker container list --format "{{.Names}}") )
27 | IFS=$'\n' read -r -a container_list <<< "$(docker container list --format "{{.Names}}")"
28 | # mapfile -t container_list < <(docker container list --format "{{.Names}}")
29 | # container_list=(); while IFS= read -r line; do container_list+=("$line"); done < <(docker container list --format "{{.Names}}")
30 | # container_list=(); docker container list --format "{{.Names}}" | while IFS= read -r line; do container_list+=("$line"); done
31 |
32 | # Verify the listed containers should be stopped, exit script if not
33 | # echo -e "The below list of containers are currently running:"
34 | echo -e "\n ${container_list[*]}\n"
35 | while read -r -p "Would you like to stop the above list of currently running containers? [y]es / (n)o " stop_answer; do
36 | case "$stop_answer" in
37 | [nN][oO]|[nN])
38 | echo ">>> No changes made to the docker environment. Exiting script. <<>> Failed to create archive. Please verify adequate disk space. Starting containers back up. <<<"
86 | fi
87 |
88 | # start all containers
89 | if manage_containers start; then
90 | echo ">>> Successfully restarted containers. <<<"
91 | else
92 | echo -e "\n>>> Failed to restart containers. Please restart containers manually. <<<\n"
93 | return 1
94 | fi
95 | else
96 | echo -e "\n>>> Failed to stop containers. Please stop containers manually. <<<\n"
97 | return 1
98 | fi
99 | }
100 |
101 |
102 | # copy the archive to a remote server
103 | archive_copy_to_server(){ # USAGE: archive_copy_to_server
104 | if scp "$backup_path/docker-backup-$backup_date.tar.gz" "$username"@"$server_ip":"$backup_path"; then
105 | # remove the local copy of the archive if the scp task completed successfully
106 | rm "$backup_path/docker-backup-$backup_date.tar.gz"
107 | echo ">>> Successfully copied archive to remote server. <<<"
108 | else
109 | echo -e ">>> Failed to copy archive to remote server. <<<\n"
110 | fi
111 | }
112 |
113 | # script output logic
114 |
115 | # query for the docker config file paths
116 | [ -z "$docker_path" ] && query_docker_paths
117 |
118 | # Set the list of containers to be stopped and backed up
119 | set_list_of_containers
120 |
121 | # query for the destination IP
122 | [ -z "$archive_target" ] && query_backup_destination
123 |
124 | # create a tar archive from all docker config file directories
125 | archive_create
126 |
127 | # copy the archive to a remote server if desired
128 | [ -z "$archive_target" ] && archive_copy_to_server
129 |
--------------------------------------------------------------------------------
/docker_system_clean.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # function definitions
7 | fnc_help_system_clean(){
8 | echo -e "${blu:?}[-> This script cleans (removes) '${cyn:?}container${blu:?}' ${cyn:?}images${def:?}, ${cyn:?}volumes${def:?} and ${CUR}unused${def:?} ${cyn:?}networks${def:?} <-]${def:?} "
9 | echo -e " -"
10 | echo -e " - SYNTAX: # dclean"
11 | echo -e " - SYNTAX: # dclean ${cyn:?}-option${def:?}"
12 | echo -e " - VALID OPTION(S):"
13 | echo -e " - ${cyn:?}-a │ --all ${def:?}│ Stops all containers then removes all ${cyn:?}container${blu:?} ${cyn:?}images${def:?}, ${cyn:?}volumes${def:?} and ${cyn:?}networks${def:?}"
14 | echo -e " - ${cyn:?}-c │ --containers ${def:?}│ Stops all containers then removes all ${CUR}exited ${cyn:?}container${def:?}"
15 | echo -e " - ${cyn:?}-i │ --images ${def:?}│ Stops all containers then removes all ${CUR}dangling ${cyn:?}images${def:?}"
16 | echo -e " - ${cyn:?}-n │ --networks ${def:?}│ Stops all containers then removes all ${CUR}unused ${cyn:?}networks${def:?}"
17 | echo -e " - ${cyn:?}-v │ --volumes ${def:?}│ Stops all containers then removes all ${cyn:?}volumes${def:?}"
18 | echo -e " -"
19 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message"
20 | echo
21 | exit 1 # Exit script after printing help
22 | }
23 | case "$1" in ("-h"|*"help"*) fnc_help_system_clean ;; esac
24 |
25 | fnc_script_intro(){ echo -e "${blu:?}[- ${ylw:?}STARTING${blu:?} CLEANUP OF THE DOCKER SYSTEM (CONTAINERS, IMAGES, VOLUMES, NETWORKS) -]${def:?}"; }
26 | fnc_script_outro(){ echo -e "${blu:?}[- DOCKER SYSTEM CLEANUP ${grn:?}COMPLETED${blu:?} -]${def:?}"; echo; }
27 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> No cleanup to be done.${def:?}"; }
28 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE ${cyn:?}-help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
29 | fnc_operation_message(){ echo -e "${blu:?}[-> REMOVE UNUSED DOCKER ${mgn:?}${operation_type}${def:?}"; }
30 | fnc_clean_volumes(){
31 | fnc_operation_message;
32 | #docker volume ls -qf dangling=true | xargs -r docker volume rm;
33 | VOLUMES_DANGLING=$(docker volume ls -qf dangling=true);
34 | if [[ ! ${VOLUMES_DANGLING} = "" ]];
35 | then docker volume rm ${VOLUMES_DANGLING};
36 | else echo -e " - ${ylw:?}No dangling volumes to remove.${def:?}";
37 | fi
38 | echo
39 | }
40 | fnc_clean_networks(){
41 | fnc_operation_message;
42 | #docker network ls | grep "bridge";
43 | NETWORKS_BRIDGED="$(docker network ls | grep "bridge" | awk '/ / { print $1 }')";
44 | if [[ ! ${NETWORKS_BRIDGED} = "" ]];
45 | then docker network rm ${NETWORKS_BRIDGED};
46 | else echo -e " - No disconnected, bridged networks to remove.";
47 | fi
48 | echo
49 | }
50 | fnc_clean_images(){
51 | fnc_operation_message;
52 | #docker images
53 | IMAGES_DANGLING=$(docker images --filter "dangling=true" -q --no-trunc);
54 | # IMAGES_DANGLING="$(docker images --filter "dangling=false" -q)";
55 | if [[ ! ${IMAGES_DANGLING} = "" ]]
56 | then docker rmi ${IMAGES_DANGLING};
57 | else echo -e " - ${ylw:?}No dangling images to remove.${def:?}";
58 | fi
59 | #docker images | grep "none"
60 | IMAGES_NONE=$(docker images | grep "none" | awk '/ / { print $3 }');
61 | if [[ ! ${IMAGES_NONE} = "" ]];
62 | then docker rmi ${IMAGES_NONE};
63 | else echo -e " - ${ylw:?}No unassigned images to remove.${def:?}";
64 | fi
65 | echo
66 | }
67 | fnc_clean_containers(){
68 | fnc_operation_message;
69 | #docker ps
70 | #docker ps -a
71 | CONTAINERS_EXITED=$(docker ps -qa --no-trunc --filter "status=exited");
72 | if [[ ! ${CONTAINERS_EXITED} = "" ]];
73 | then docker rm ${CONTAINERS_EXITED};
74 | else echo -e " - ${ylw:?}No exited containers to remove.${def:?}";
75 | fi
76 | echo
77 | }
78 |
79 | # option logic action determination
80 | case "${1}" in
81 | ("")
82 | fnc_invalid_syntax
83 | ;;
84 | (-*) # validate entered option exists
85 | # fnc_script_intro
86 | case "${1}" in
87 | ("-a"|"--all")
88 | operation_type="containers"; fnc_clean_containers
89 | operation_type="images"; fnc_clean_images
90 | # operation_type="networks"; fnc_clean_networks
91 | # operation_type="volumes"; fnc_clean_volumes
92 | ;;
93 | ("-c"|"--containers")
94 | operation_type="containers"; fnc_clean_containers
95 | ;;
96 | ("-i"|"--images")
97 | operation_type="images"; fnc_clean_images
98 | ;;
99 | ("-n"|"--networks")
100 | operation_type="networks"; fnc_clean_networks
101 | ;;
102 | ("-v"|"--volumes")
103 | operation_type="volumes"; fnc_clean_volumes
104 | ;;
105 | (*)
106 | fnc_invalid_syntax
107 | ;;
108 | esac
109 | ;;
110 | (*)
111 | fnc_invalid_syntax
112 | ;;
113 | esac
114 |
115 | fnc_script_outro
--------------------------------------------------------------------------------
/docker_system_image.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # function definitions
7 | fnc_help(){
8 | echo -e "${blu:?}[-> This script displays '${cyn:?}docker image${blu:?}' information. <-]${def:?} "
9 | echo -e " -"
10 | echo -e " - SYNTAX: # dimage"
11 | echo -e " - SYNTAX: # dimage ${cyn:?}-option${def:?}"
12 | echo -e " - VALID OPTION(S):"
13 | echo -e " - ${cyn:?}-a │ --all ${def:?}│ "
14 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message"
15 | echo
16 | exit 1 # Exit script after printing help
17 | }
18 |
--------------------------------------------------------------------------------
/docker_system_network.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # external variable sources
4 | source /opt/docker/scripts/.color_codes.conf
5 | source /opt/docker/scripts/.vars_docker.env
6 |
7 | # function definitions
8 | fnc_script_intro(){ echo -e "${blu:?}[-> LISTING CURRENT DOCKER NETWORKS <-]${def:?}";}
9 | fnc_script_outro(){ echo; exit 1; }
10 | fnc_help_system_clean(){
11 | echo -e "${blu:?}[-> This script allows the user to manage docker ${cyn:?}networks${def:?} <-]${def:?} "
12 | echo -e " -"
13 | echo -e " - SYNTAX: # dyn"
14 | echo -e " - SYNTAX: # dyn ${cyn:?}-option${def:?}"
15 | echo -e " - VALID OPTION(S):"
16 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message"
17 | fnc_script_outro
18 | }
19 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE '${cyn:?}--help${ylw:?}' OPTION TO DISPLAY PROPER SYNTAX${def:?} <<" && fnc_script_outro; }
20 | fnc_network_list(){ docker network ls; }
21 | fnc_network_check(){ docker network ls -q --filter name="$1"; }
22 | fnc_network_swarm_verify(){
23 | unset increment IFS;
24 | while [[ ! "$(fnc_network_check "${var_net_socket}")" ]] || [[ ! "$(fnc_network_check "${var_net_rproxy}")" ]] || [[ ! "$(fnc_network_check "docker_gwbridge")" ]];
25 | do sleep 1;
26 | increment=$((increment+1));
27 | if [[ $increment -gt 10 ]];
28 | then fnc_swarm_error;
29 | fi;
30 | done;
31 | }
32 | fnc_network_create(){
33 | # if [ "${scope}" = "swarm" ] && [[ ! "$(fnc_network_check "ingress")" = "" ]]; then docker network rm ingress; fi;
34 | # if [ "${scope}" = "swarm" ]; then docker network create --ingress --driver "${driver}" --opt encrypted --subnet "10.0.0.0/16" --gateway "10.0.0.254" ingress; fi;
35 | # if [ "${scope}" = "local" ] && [[ ! "$(fnc_network_check "docker_gwbridge")" = "" ]]; then docker network rm "docker_gwbridge"; fi;
36 | case "${scope}" in
37 | "local")
38 | if [[ ! "$(fnc_network_check "docker_gwbridge")" = "" ]]; then docker network rm "docker_gwbridge"; fi;
39 | ;;
40 | "swarm")
41 | if [[ ! "$(fnc_network_check "ingress")" = "" ]]; then docker network rm ingress; fi;
42 | # docker network create --ingress --driver overlay --opt encrypted --subnet "10.27.0.0/16" --gateway "10.27.0.254" "ingress";
43 | docker network create --ingress --driver overlay --opt encrypted --subnet "${var_subnet_ingress}" --gateway "${var_gateway_ingress}" "${var_net_ingress}";
44 | ;;
45 | *)
46 | echo -e "${ylw:?} >> ERROR: ${red:?}INVALID NETWORK SCOPE${ylw:?} Please notify the script author <<${def:?}" && fnc_script_outro;
47 | ;;
48 | esac
49 | docker network create --scope "${scope}" --driver "${driver}" --opt encrypted --subnet "${var_subnet_exedge}" --gateway "${var_gateway_exedge}" --attachable "${var_net_exedge}";
50 | docker network create --scope "${scope}" --driver "${driver}" --opt encrypted --subnet "${var_subnet_rproxy}" --gateway "${var_gateway_rproxy}" --attachable "${var_net_rproxy}";
51 | docker network create --scope "${scope}" --driver "${driver}" --opt encrypted --subnet "${var_subnet_socket}" --gateway "${var_gateway_socket}" --attachable "${var_net_socket}";
52 | unset "${scope}";
53 | unset "${driver}";
54 | echo -e "\n>> DOCKER NETWORK(s) ${grn:?}CREATED${def:?} <<" && fnc_script_outro;
55 | }
56 | fnc_network_remove(){
57 | docker network rm "${*}";
58 | }
59 |
60 | # output determination logic
61 | case "${1}" in
62 | (""|"-l"|"--list")
63 | fnc_script_intro;
64 | fnc_network_list;
65 | fnc_script_outro;
66 | ;;
67 | (-*)
68 | case "${1}" in
69 | ("-h"|"-help"|"--help")
70 | fnc_help_system_clean;
71 | ;;
72 | ("-c"|"--compose")
73 | driver="bridge"
74 | scope="local"
75 | fnc_network_create;
76 | ;;
77 | ("-d"|"-r"|"--delete"|"--remove")
78 | fnc_network_remove "${1}";
79 | ;;
80 | ("-w"|"-s"|"--swarm")
81 | driver="overlay"
82 | scope="swarm"
83 | fnc_network_create;
84 | ;;
85 | (*)
86 | fnc_invalid_syntax;
87 | ;;
88 | esac
89 | ;;
90 | (*)
91 | fnc_invalid_syntax;
92 | ;;
93 | esac
--------------------------------------------------------------------------------
/docker_system_prune.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # function definitions
7 | fnc_help(){
8 | echo -e "${blu:?}[-> This script prunes (removes) '${cyn:?}container${blu:?}' ${cyn:?}images${def:?}, ${cyn:?}volumes${blu:?} and ${CUR}unused${def:?} ${cyn:?}networks${blu:?} <-]${def:?} "
9 | echo -e " -"
10 | echo -e " - SYNTAX: # dprn"
11 | echo -e " - SYNTAX: # dprn ${cyn:?}-option${def:?}"
12 | echo -e " - VALID OPTION(S):"
13 | echo -e " - ${cyn:?}-a │ --all ${def:?}│ Stops all containers then removes all '${cyn:?}container${blu:?}' ${cyn:?}images${def:?}, ${cyn:?}volumes${def:?} and ${CUR}unused${def:?} ${cyn:?}networks${def:?}"
14 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message"
15 | echo
16 | exit 1 # Exit script after printing help
17 | }
18 | fnc_intro(){ echo -e "${blu:?}[-> PRUNING THE DOCKER SYSTEM <-]${def:?}"; }
19 | fnc_outro(){ echo -e "${grn:?}[-- DOCKER SYSTEM PRUNE COMPLETE --]${def:?}"; echo; }
20 | fnc_prune(){ docker system prune --all --force --volumes; }
21 | fnc_container_list(){ docker container ls --all --quiet; }
22 | fnc_container_stop(){ docker stop $(fnc_container_list); }
23 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
24 | fnc_invalid_input(){ echo -e "${ylw:?}INVALID INPUT${def:?}: Must be any case-insensitive variation of '(Y)es' or '(N)o'."; }
25 | fnc_nothing_to_do(){ echo -e " - ${ylw:?}nothing to prune from the docker environment${def:?}"; }
26 | fnc_query_remove_all(){ echo -e "Are you sure you want to ${red:?}STOP${def:?} and ${ylw:?}REMOVE${def:?} all containers?"; }
27 |
28 | # Script start notification
29 | fnc_intro
30 |
31 | # Script logic and execution
32 | case "${1}" in
33 | (-*)
34 | case "${1}" in
35 | ("-h"|"-help"|"--help") fnc_help ;;
36 | ("-a"|"--all")
37 | if [[ "$(fnc_container_list)" ]]; then
38 | fnc_query_remove_all
39 | while read -r -p " [(Y)es/(N)o] " input; do
40 | case "${input}" in
41 | ([yY]|[yY][eE][sS]) fnc_container_stop && echo && fnc_prune && break;;
42 | ([nN]|[nN][oO]) break ;;
43 | (*) fnc_invalid_input ;;
44 | esac
45 | done
46 | else fnc_nothing_to_do
47 | fi
48 | ;;
49 | (*) fnc_invalid_syntax ;;
50 | esac
51 | ;;
52 | (*) fnc_prune ;;
53 | esac
54 |
55 | # Script completion notice
56 | echo
57 | # fnc_outro
--------------------------------------------------------------------------------
/docker_system_stats.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # function definitions
7 | fnc_help(){
8 | echo -e "${blu:?}[-> This script displays system resources used by current docker stacks/containers. <-]${def:?} "
9 | echo -e " -"
10 | echo -e " - SYNTAX: # dls"
11 | echo -e " - SYNTAX: # dls ${cyn:?}-option${def:?}"
12 | echo -e " - VALID OPTION(S):"
13 | echo -e " - ${cyn:?}-l | --live ${def:?}│ Displays a live-updating resource usage table for current docker services."
14 | echo -e " - ${cyn:?}-p | --part ${def:?}│ Displays a resource usage table for current docker services."
15 | echo -e " - ${cyn:?}-h | --help ${def:?}│ Displays this help message."
16 | echo
17 | exit 1 # Exit script after printing help
18 | }
19 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE -${cyn:?}help${ylw:?} OPTION TO DISPLAY PROPER SYNTAX <<${def:?}"; exit 1; }
20 | fnc_stats_full(){ docker stats --format "table {{.Container}}\t{{.Name}}\t{{.CPUPerc}} {{.MemPerc}} {{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"; }
21 | fnc_stats_part(){ docker stats --format "table {{.Name}}\t{{.CPUPerc}} {{.MemPerc}}\t{{.MemUsage}}\t{{.NetIO}}"; }
22 |
23 | # determine script output according to option entered
24 | case "${1}" in
25 | ("") fnc_stats_part ;;
26 | (-*)
27 | case "${1}" in
28 | ("-h"|"-help"|"--help") fnc_help ;;
29 | ("-l"|"--live") fnc_stats_full ;;
30 | ("-p"|"--part") fnc_stats_part ;;
31 | (*) fnc_invalid_syntax ;;
32 | esac
33 | ;;
34 | (*) fnc_stats_full ;;
35 | esac
36 |
--------------------------------------------------------------------------------
/docker_system_volume.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # external variable sources
3 | source /opt/docker/scripts/.color_codes.conf
4 | source /opt/docker/scripts/.vars_docker.env
5 |
6 | # function definitions
7 | fnc_help(){
8 | echo -e "${blu:?}[-> This script lists all docker ${cyn:?}volumes${def:?} <-]${def:?} "
9 | echo -e " -"
10 | echo -e " - SYNTAX: # dlv"
11 | echo -e " - SYNTAX: # dlv ${cyn:?}-option${def:?}"
12 | echo -e " - VALID OPTION(S):"
13 | echo -e " - ${cyn:?}-h │ --help ${def:?}│ Displays this help message"
14 | echo
15 | exit 1 # Exit script after printing help
16 | }
17 | fnc_script_intro(){ echo -e "${blu:?}[-> LISTING UNUSED DOCKER VOLUMES <-]${def:?}";}
18 | fnc_script_outro(){ echo; }
19 | fnc_nothing_to_do(){ echo -e "${ylw:?} -> no volumes exist${def:?}"; }
20 | fnc_invalid_syntax(){ echo -e "${ylw:?} >> INVALID OPTION SYNTAX, USE THE '--${cyn:?}help${ylw:?}' OPTION TO DISPLAY PROPER SYNTAX${def:?} <<"; exit 1; }
21 | fnc_docker_volumes_check(){ docker volume ls -qf dangling=true; }
22 | fnc_docker_volumes_list(){ docker volume ls; }
23 |
24 | # output determination logic
25 | case "${1}" in
26 | ("")
27 | fnc_script_intro
28 | if [ "$(fnc_docker_volumes_check)" ]
29 | then fnc_docker_volumes_list
30 | else fnc_nothing_to_do
31 | fi
32 | fnc_script_outro
33 | ;;
34 | (-*)
35 | case "${1}" in
36 | ("-h"|"-help"|"--help") fnc_help ;;
37 | (*) fnc_invalid_syntax ;;
38 | esac
39 | esac
40 |
--------------------------------------------------------------------------------