Manage Script, Resource Limits, OnlyOffice Changes (#14)

* Create explicit file for cron, add two automations from fixes.

* Merge the OnlyOffice project into the Nextcloud project. Enhance comments and changelog. Make the container names consistent.

* Found the link. :)

* Add more variables.

* Add a TBD file for mail server.

* Create new script which will replace most the existing single purpose management scripts.

* Add limit to DNS so that if Internet goes out it does not max system resources.

* Prevent OnlyOffice from getting too hungry.

* Ensure Reverse Proxy always has at least some resources.

* Separate build. Add stats -s and combination option -A.

* Make script config file aware. Add comments.

* Add more comments.

* Fix comments.

* Further determine resource allocations.

* Also avoid checking for cron's call to the program.

* Add clean and log parameters. Some clean up.

* Update setups to have DIR first.

* Remove files taken over by manage script.

* Cleaning comments and output.
This commit is contained in:
Hyperling 2023-09-01 05:50:29 -07:00 committed by GitHub
parent fbad19dc51
commit f56b3da23d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 379 additions and 141 deletions

View File

@ -15,3 +15,12 @@ services:
ports:
- "53:53/udp"
- "53:53/tcp"
deploy:
mode: global
resources:
limits:
cpus: '0.50'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M

View File

@ -10,3 +10,9 @@ services:
restart: always
ports:
- 8317:8080
deploy:
mode: global
resources:
limits:
cpus: '0.25'
memory: 256M

View File

21
Config/Nextcloud/cron.sh Executable file
View File

@ -0,0 +1,21 @@
#!/bin/bash
# 2023-08-25 Hyperling
# Put the cron command in a script as well as other automation.
# This should be added to root's crontab with the full path, such as:
# */5 * * * * /opt/Docker/Config/Nextcloud/cron.ksh
# Check if a job is already going.
PROG="$(basename -- "${BASH_SOURCE[0]}")"
RUNNING=`ps -ef | grep $PROG | grep -v grep | grep -v $$ | grep -v "sh -c" | wc -l`
if (( $RUNNING > 0 )); then
exit $RUNNING
fi
# 2023-08-25 From crontab.
docker exec -u www-data nc-app php cron.php --define apc.enable_cli=1
# 2023-08-25 From fixes.sh, keep ownership correct and apps up to date.
docker exec -it nc-app chown -Rc www-data:www-data .
docker exec -itu www-data nc-app ./occ app:update --all
exit 0

View File

@ -3,19 +3,25 @@
# https://hub.docker.com/_/nextcloud
# Changelog:
# 2023-07-16 Change from mariadb:10.5 to 10.6.
# 2023-08-20 Add Redis. (https://markontech.com/docker/setup-nextcloud-with-redis-using-docker/)
# 2023-08-21 Got NC to work with OO after specifying the Advanced parameters!
# OO Address: https://FQDN-For-Reverse-Proxied-OO-Server
# OO Secret: Contents-Of-$JWT_SECRET
# OO Header:
# OO Internal Address: http://docker-server-ip:8000
# NC Internal Address: http://docker-server-ip:8080
# 2023-07-16
# Change from mariadb:10.5 to 10.6.
# 2023-08-20
# Add Redis. (https://markontech.com/docker/setup-nextcloud-with-redis-using-docker/)
# 2023-08-21
# Got NC to work with OO after specifying the Advanced parameters!
# 2023-08-26
# Try combining OnlyOffice to here again. It has been on its own since
# 2023-07-25 but isn't being used for anything else. OO is slow to respond
# and upgrades can no longer be done separately but this keeps it all easier
# to maintain and may allow the internal address to be based on container
# name instead of the docker hosts's IP.
version: '3'
services:
db:
## MariaDB ##
nc-db:
container_name: nc-db
image: mariadb:10.6
restart: always
@ -27,29 +33,75 @@ services:
- MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD
- MYSQL_USER=$MYSQL_USER
- MYSQL_PASSWORD=$MYSQL_PASSWORD
deploy:
mode: global
resources:
limits:
cpus: '0.50'
memory: 1G
reservations:
cpus: '0.25'
memory: 256M
redis:
## Redis ##
nc-redis:
container_name: nc-redis
image: redis
restart: always
command: redis-server --requirepass $REDIS_HOST_PASSWORD
deploy:
mode: global
resources:
limits:
cpus: '0.25'
memory: 128M
app:
## OnlyOffice ##
nc-oo:
container_name: nc-oo
image: onlyoffice/documentserver
restart: always
ports:
- 8081:80
environment:
- JWT_SECRET=$JWT_SECRET
deploy:
mode: global
resources:
limits:
cpus: '0.75'
memory: 1G
## Nextcloud ##
nc-app:
container_name: nc-app
image: nextcloud
restart: always
ports:
- 8080:80
links:
- db
- redis
- nc-db
- nc-redis
- nc-oo
volumes:
- ../../Volumes/Nextcloud/nextcloud:/var/www/html
environment:
- NEXTCLOUD_ADMIN_USER=$NEXTCLOUD_ADMIN_USER
- NEXTCLOUD_ADMIN_PASSWORD=$NEXTCLOUD_ADMIN_PASSWORD
- PHP_MEMORY_LIMIT=$PHP_MEMORY_LIMIT
- PHP_UPLOAD_LIMIT=$PHP_UPLOAD_LIMIT
- MYSQL_HOST=$MYSQL_HOST
- MYSQL_DATABASE=$MYSQL_DATABASE
- MYSQL_USER=$MYSQL_USER
- MYSQL_PASSWORD=$MYSQL_PASSWORD
- PHP_UPLOAD_LIMIT=$PHP_UPLOAD_LIMIT
- REDIS_HOST=$REDIS_HOST
- REDIS_HOST_PASSWORD=$REDIS_HOST_PASSWORD
deploy:
mode: global
resources:
limits:
cpus: '2.00'
# No memory limit.
reservations:
cpus: '0.50'
memory: 512M

View File

@ -1,18 +1,55 @@
# Example environment file for Nextcloud stack, should be copied as `.env`.
# Example environment file for Nextcloud stack, should be copied as `.env`. The
# variables here only apply to the compose file. If you need it passed to a
# container then it also needs specified in its `environment:` operator.
#
# ** All usernames and passwords need changed before running in production! **
#
# Full guide on the Nextcloud parameters which may be supplied:
# https://github.com/docker-library/docs/blob/master/nextcloud/README.md#auto-configuration-via-environment-variables
#
## Nextcloud ##
#
NEXTCLOUD_ADMIN_USER=nc_admin
NEXTCLOUD_ADMIN_PASSWORD=SuperDuperSecretPassword
PHP_MEMORY_LIMIT=2G
PHP_UPLOAD_LIMIT=5G
## MySQL ##
#
## MariaDB ##
#
# Should load automatically the first run. Then config.php is the source of
# truth for these values. So, if something like the DB password is changed,
# updating it here will have no effect. This is only used for the install.
MYSQL_HOST=db
MYSQL_HOST=nc-db
MYSQL_DATABASE=nextcloud
MYSQL_ROOT_PASSWORD=ChangeMe
MYSQL_USER=nc
MYSQL_PASSWORD=changeme
## REDIS ##
#
## Redis ##
#
# Installs automagically if both of these parameters are supplied.
REDIS_HOST=redis
REDIS_HOST=nc-redis
REDIS_HOST_PASSWORD=someredispassword
#
## OnlyOffice ##
#
# How Nextcloud's ONLYOFFICE Admin Settings should be set up:
# OO Address: https://FQDN-For-Reverse-Proxied-OO-Server
# OO Secret: Contents-Of-$JWT_SECRET
# OO Header:
# OO Internal Address: http://docker-server-ip:8081 ?OR http://nc-oo:8081?
# NC Internal Address: http://docker-server-ip:8080 ?OR http://nc-app:8080?
#
# Documentation which references the variable(s) below, Nextcloud link does not cover them:
# https://helpcenter.onlyoffice.com/installation/docs-configure-jwt.aspx
# Secret key which is used above in the Nextcloud ONLYOFFICE Administration UI.
JWT_SECRET=abc123

View File

@ -10,10 +10,6 @@ docker exec -itu www-data nc-app ./occ db:add-missing-columns
docker exec -itu www-data nc-app ./occ db:add-missing-indices
docker exec -itu www-data nc-app ./occ db:add-missing-primary-keys
docker exec -itu www-data nc-app ./occ db:convert-filecache-bigint
docker exec -it nc-app chown -Rc www-data:www-data .
# 2023-02-12 Just for good measure.
docker exec -itu www-data nc-app ./occ app:update --all
# 2023-07-02
# This maybe used to exist, but make sure that Files app is correct.

View File

@ -1,15 +0,0 @@
# 2023-07-25
# OnlyOffice server, primarily used for Nextcloud.
version: '3'
services:
app:
container_name: oo-app
image: onlyoffice/documentserver
restart: always
ports:
- 8000:80
- 4443:443
environment:
- JWT_SECRET=$JWT_SECRET

View File

@ -1,6 +0,0 @@
# Example environment file for OnlyOffice, should be copied as `.env`.
## Relating to the Nextcloud Admin Settings UI ##
# Secret
JWT_SECRET=abc123

View File

@ -20,6 +20,15 @@ services:
- ../../Volumes/ReverseProxy/letsencrypt:/etc/nginx/letsencrypt
- ../../Volumes/ReverseProxy/letsencrypt-certs:/etc/nginx/certs
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
deploy:
mode: global
resources:
limits:
cpus: '1.00'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M
certbot:
container_name: rp-certbot
@ -29,3 +38,12 @@ services:
- ../../Volumes/ReverseProxy/letsencrypt:/etc/letsencrypt
- ../../Volumes/ReverseProxy/letsencrypt-certs:/etc/letsencrypt/nginx
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; cp -rL /etc/letsencrypt/live/* /etc/letsencrypt/nginx/; sleep 12h & wait $${!}; done;'"
deploy:
mode: global
resources:
limits:
cpus: '0.50'
memory: 256M
reservations:
cpus: '0.25'
memory: 128M

View File

@ -1,16 +0,0 @@
#!/bin/bash
# 2023-08-21 Hyperling
# Clean all unused images and containers.
# https://docs.docker.com/config/pruning/
# Very helpful during development, nice in a long-running production as well.
# usage: clean.sh
docker image prune -a
docker container prune
docker volume prune
docker network prune
exit 0

View File

@ -5,14 +5,9 @@
## Setup ##
DIR="`dirname $0`"
PROG=`basename $0`
if [[ $DIR == *"."* ]]; then
DIR="`pwd`"
fi
if [[ -z $DOCKER_HOME ]]; then
DOCKER_HOME="$DIR/.."
fi
DIR="$(dirname -- "${BASH_SOURCE[0]}")"
PROG="$(basename -- "${BASH_SOURCE[0]}")"
source $DIR/../source.env
dir=logs
date_format="+%Y%m%d-%H%M%S"

214
bin/manage.sh Executable file
View File

@ -0,0 +1,214 @@
#!/bin/bash
# 2023-08-26 Hyperling
# Combine all programs which loop over Config into one which takes parameters.
## Setup ##
DIR="$(dirname -- "${BASH_SOURCE[0]}")"
PROG="$(basename -- "${BASH_SOURCE[0]}")"
source $DIR/../source.env
## Functions ##
function usage() {
# Function to give the usage of the program.
# Parameters:
# 1) The exit code used when leaving.
exit_code=$1
echo ""
echo -n "Usage: $PROG [-A ( -u | -d | -b | -p | -c | -s )] " 1>&2
echo "[-i CONTAINER] [-l CONTAINER] [-h]" 1>&2
cat <<- EOF
Manage all docker compose subprojects based on parameters. If no
options are given then 'docker ps' is performed and the program exits.
Parameters - Standalone:
(ALL)
-A : Equivalent of specifying '-udbpcs' for a full upgrade service.
(UP)
-u : Start all containers with 'up -d'.
(DOWN)
-d : Stop and take down all containers with 'down'.
(BUILD)
-b : Do a 'build' for containers with a 'Dockerfile'.
(PULL)
-p : Update all containers with 'pull'.
(CLEAN)
-c : Remove any abandoned Docker objects using the 'prune' commands.
(STATS)
-s : Tune in to the 'stats' of how each container is running.
Parameters - Specifying CONTAINER:
Variable can be either the container ID or container name. If (UP) is
also provided then the container does not need to be active, otherwise
the container must be running so that it can be accessed.
(INTERACT)
-i CONTAINER : Remote into CONTAINER with 'exec -it CONTAINER sh'.
(LOGS)
-l CONTAINER : Follow the logs of CONTAINER with 'logs -f CONTAINER'.
Parameters - Other:
(HELP)
-h : Display this message.
EOF
exit $exit_code
}
function check_container() {
# Ensure a container which will be accessed is either running or starting.
# Parameters:
# 1) CONTAINER, either as ID or Name.
# 2) WHy the container is being checked.
container_to_check="$1"
reason_to_check="$2"
exists=`docker ps | grep -c $container_to_check`
if [[ ( $exists == 0 && -z $up ) || ( -n $down && -z $up ) ]]; then
echo -n "ERROR: $container_to_check was requested for " 1>&2
echo "$reason_to_check but it is not up or going to be up." 1>&2
exit 2
fi
return
}
## Parameters ##
while getopts ':Audbpcsi:l:h' opt; do
case $opt in
A) all="Y" ;;
u) up="Y" ;;
d) down="Y" ;;
b) build="Y" ;;
p) pull="Y" ;;
c) clean="Y" ;;
s) stats="Y" ;;
i) interact="$OPTARG" ;;
l) logs="$OPTARG" ;;
h) usage 0 ;;
*) echo "ERROR: Parameter '$OPTARG' not recognized." 1>&2 && usage 1 ;;
esac
done
# This is done outside the getopts for readability.
if [[ -n $all ]]; then
up="Y"; down="Y"; build="Y"; pull="Y"; clean="Y"; stats="Y"
fi
## Validations ##
# Script will behave poorly if not run with admin privileges.
if [[ $LOGNAME != "root" ]]; then
echo "*************************************************************"
echo "WARNING: Script is intended for root. Please su or sudo/doas."
echo -e "*************************************************************\n"
fi
# Options which only work if the container exists or is going to be started.
if [[ -n $interact ]]; then
check_container $interact interaction
fi
if [[ -n $logs ]]; then
check_container $logs logs
fi
## Main ##
# If no parameters are passed, list all the containers which are running.
if [[ -z $up && -z $down && -z $build && -z $pull && -z $clean
&& -z $interact && -z $logs && -z $stats
]]; then
docker ps
exit 0
fi
# Otherwise, loop through all the subproject configurations.
if [[ -n $up || -n $down || -n $build || -n $pull ]]; then
cd $DOCKER_HOME/Config
for dir in `ls`; do
# If this is a directory, enter it, otherwise skip to the next listing.
[ -d $dir ] && cd $dir || continue
echo ""
pwd
# Ensure .env files exist so that all compose variables are populated.
if [[ -e ./env.example && ! -e ./.env ]]; then
echo "WARNING: .env file was not found, copying example as placeholder."
cp -v env.example .env
fi
# Ensure all configuration files have been created.
if [[ -d ./config ]]; then
ls ./config/*.example 2>/dev/null | while read example; do
real=${example//.example/}
if [[ ! -e $real ]]; then
echo "WARNING: $real was not found, copying $example."
cp -v $example $real
fi
done
fi
# Shut off container.
if [[ $down == "Y" ]]; then
[ -e docker-compose.yml ] && docker compose down
fi
# Update container from remote source such as Docker Hub.
if [[ $pull == "Y" ]]; then
[ -e docker-compose.yml ] && docker compose pull
fi
# Execute commands within the container's Dockerfile.
if [[ $build == "Y" ]]; then
[ -e Dockerfile ] && docker compose build
fi
# Run the container as a daemon.
if [[ $up == "Y" ]]; then
[ -e docker-compose.yml ] && docker compose up -d
fi
cd ..
done
fi
# Dive into a container for running ad hoc commands.
if [[ -n $interact ]]; then
echo -e "\n*** Hopping into $interact ***"
docker exec -it $interact sh
fi
# Clean every type of Docker object which can be abandoined by Compose.
if [[ -n $clean ]]; then
echo -e "\n*** Cleaning Abandoned Objects ***"
docker image prune -a
docker container prune
docker volume prune
docker network prune
fi
# Follow the logs of a container.
if [[ -n $logs ]]; then
echo -e "\n*** Following Logs of $logs ***"
docker logs -f $logs
fi
# Watch a top-level performance and resource monitor.
if [[ -n $stats ]]; then
echo -e "\n*** Tuning Into Stats ***"
docker stats
fi
exit 0

View File

@ -1,31 +0,0 @@
#!/bin/bash
# 2022-08-05 Hyperling
# Start all containers.
# usage: start.sh
## Setup ##
DIR="`dirname $0`"
PROG=`basename $0`
if [[ $DIR == *"."* ]]; then
DIR="`pwd`"
fi
if [[ -z $DOCKER_HOME ]]; then
DOCKER_HOME="$DIR/.."
fi
## Main ##
echo "Starting all containers."
cd $DOCKER_HOME/Config
for dir in `ls`; do
[ -d $dir ] && cd $dir || continue
echo ""
pwd
[ -e Dockerfile ] && docker compose build
[ -e docker-compose.yml ] && docker compose up -d
cd ..
done
exit 0

View File

@ -1,30 +0,0 @@
#!/bin/bash
# 2022-08-05 Hyperling
# Stop all containers.
# usage: stop.sh
## Setup ##
DIR="`dirname $0`"
PROG=`basename $0`
if [[ $DIR == *"."* ]]; then
DIR="`pwd`"
fi
if [[ -z $DOCKER_HOME ]]; then
DOCKER_HOME="$DIR/.."
fi
## Main ##
echo "Stopping all containers."
cd $DOCKER_HOME/Config
for dir in `ls`; do
[ -d $dir ] && cd $dir || continue
echo ""
pwd
[ -e docker-compose.yml ] && docker compose down
cd ..
done
exit 0

View File

@ -1,12 +0,0 @@
#!/bin/bash
# 2022-09-25 Hyperling
# Script to update a docker compose image.
docker compose down
docker compose pull &&
docker compose build &&
docker compose up -d &&
exit 0
echo "ERROR: Did not update or start correctly." &&
exit 1