mirror of
				https://github.com/nextcloud/all-in-one.git
				synced 2025-10-28 17:51:23 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			363 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			363 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
| #!/bin/bash
 | |
| 
 | |
| # Function to show text in green
 | |
| print_green() {
 | |
|     local TEXT="$1"
 | |
|     printf "%b%s%b\n" "\e[0;92m" "$TEXT" "\e[0m"
 | |
| }
 | |
| 
 | |
| # Function to show text in red
 | |
| print_red() {
 | |
|     local TEXT="$1"
 | |
|     printf "%b%s%b\n" "\e[0;31m" "$TEXT" "\e[0m"
 | |
| }
 | |
| 
 | |
| # Function to check if number was provided
 | |
| check_if_number() {
 | |
| case "${1}" in
 | |
|     ''|*[!0-9]*) return 1 ;;
 | |
|     *) return 0 ;;
 | |
| esac
 | |
| }
 | |
| 
 | |
| # Check if running as root user
 | |
| if [ "$EUID" != "0" ]; then
 | |
|     print_red "Container does not run as root user. This is not supported."
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| # Check that the CMD is not overwritten nor set
 | |
| if [ "$*" != "" ]; then
 | |
|     print_red "Docker run command for AIO is incorrect as a CMD option was given which is not expected."
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| # Check if socket is available and readable
 | |
| if ! [ -a "/var/run/docker.sock" ]; then
 | |
|     print_red "Docker socket is not available. Cannot continue."
 | |
|     echo "Please make sure to mount the docker socket into /var/run/docker.sock inside the container!"
 | |
|     echo "If you did this by purpose because you don't want the container to have access to the docker socket, see https://github.com/nextcloud/all-in-one/tree/main/manual-install."
 | |
|     exit 1
 | |
| elif ! mountpoint -q "/mnt/docker-aio-config"; then
 | |
|     print_red "/mnt/docker-aio-config is not a mountpoint. Cannot proceed!"
 | |
|     echo "Please make sure to mount the nextcloud_aio_mastercontainer docker volume into /mnt/docker-aio-config inside the container!"
 | |
|     echo "If you are on TrueNas SCALE, see https://github.com/nextcloud/all-in-one#can-i-run-aio-on-truenas-scale"
 | |
|     exit 1
 | |
| elif ! sudo -u www-data test -r /var/run/docker.sock; then
 | |
|     echo "Trying to fix docker.sock permissions internally..."
 | |
|     DOCKER_GROUP=$(stat -c '%G' /var/run/docker.sock)
 | |
|     DOCKER_GROUP_ID=$(stat -c '%g' /var/run/docker.sock)
 | |
|     # Check if a group with the same group id of /var/run/docker.socket already exists in the container
 | |
|     if grep -q "^$DOCKER_GROUP:" /etc/group; then
 | |
|         # If yes, add www-data to that group
 | |
|         echo "Adding internal www-data to group $DOCKER_GROUP"
 | |
|         usermod -aG "$DOCKER_GROUP" www-data
 | |
|     else
 | |
|         # Delete the docker group for cases when the docker socket permissions changed between restarts
 | |
|         groupdel docker &>/dev/null
 | |
| 
 | |
|         # If the group doesn't exist, create it
 | |
|         echo "Creating docker group internally with id $DOCKER_GROUP_ID"
 | |
|         groupadd -g "$DOCKER_GROUP_ID" docker
 | |
|         usermod -aG docker www-data
 | |
|     fi
 | |
|     if ! sudo -u www-data test -r /var/run/docker.sock; then
 | |
|         print_red "Docker socket is not readable by the www-data user. Cannot continue."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| 
 | |
| # Check if api version is supported
 | |
| if ! sudo -u www-data docker info &>/dev/null; then
 | |
|     print_red "Cannot connect to the docker socket. Cannot proceed."
 | |
|     echo "If SELinux is enabled on your host, see https://github.com/nextcloud/all-in-one#are-there-known-problems-when-selinux-is-enabled"
 | |
|     echo "If you are on TrueNas SCALE, see https://github.com/nextcloud/all-in-one#can-i-run-aio-on-truenas-scale"
 | |
|     exit 1
 | |
| fi
 | |
| API_VERSION_FILE="$(find ./ -name DockerActionManager.php | head -1)"
 | |
| API_VERSION="$(grep -oP 'const API_VERSION.*\;' "$API_VERSION_FILE" | grep -oP '[0-9]+.[0-9]+' | head -1)"
 | |
| # shellcheck disable=SC2001
 | |
| API_VERSION_NUMB="$(echo "$API_VERSION" | sed 's/\.//')"
 | |
| LOCAL_API_VERSION_NUMB="$(sudo -u www-data docker version | grep -i "api version" | grep -oP '[0-9]+.[0-9]+' | head -1 | sed 's/\.//')"
 | |
| if [ -n "$LOCAL_API_VERSION_NUMB" ] && [ -n "$API_VERSION_NUMB" ]; then
 | |
|     if ! [ "$LOCAL_API_VERSION_NUMB" -ge "$API_VERSION_NUMB" ]; then
 | |
|         print_red "Docker API v$API_VERSION is not supported by your docker engine. Cannot proceed. Please upgrade your docker engine if you want to run Nextcloud AIO!"
 | |
|         exit 1
 | |
|     fi
 | |
| else
 | |
|     echo "LOCAL_API_VERSION_NUMB or API_VERSION_NUMB are not set correctly. Cannot check if the API version is supported."
 | |
|     sleep 10
 | |
| fi
 | |
| 
 | |
| # Check Storage drivers
 | |
| STORAGE_DRIVER="$(docker info | grep "Storage Driver")"
 | |
| # Check if vfs is used: https://github.com/nextcloud/all-in-one/discussions/1467
 | |
| if echo "$STORAGE_DRIVER" | grep -q vfs; then
 | |
|     echo "$STORAGE_DRIVER"
 | |
|     echo "Warning: It seems like the storage driver vfs is used. This will lead to problems with disk space and performance and is disrecommended!"
 | |
| elif echo "$STORAGE_DRIVER" | grep -q fuse-overlayfs; then
 | |
|     echo "$STORAGE_DRIVER"
 | |
|     echo "Warning: It seems like the storage driver fuse-overlayfs is used. Please check if you can switch to overlay2 instead."
 | |
| fi
 | |
| 
 | |
| # Check if startup command was executed correctly
 | |
| if ! sudo -u www-data docker ps --format "{{.Names}}" | grep -q "^nextcloud-aio-mastercontainer$"; then
 | |
|     print_red "It seems like you did not give the mastercontainer the correct name? (The 'nextcloud-aio-mastercontainer' container was not found.)
 | |
| Using a different name is not supported since mastercontainer updates will not work in that case!
 | |
| If you are on docker swarm and try to run AIO, see https://github.com/nextcloud/all-in-one#can-i-run-this-with-docker-swarm"
 | |
|     exit 1
 | |
| elif ! sudo -u www-data docker volume ls --format "{{.Name}}" | grep -q "^nextcloud_aio_mastercontainer$"; then
 | |
|     print_red "It seems like you did not give the mastercontainer volume the correct name? (The 'nextcloud_aio_mastercontainer' volume was not found.)
 | |
| Using a different name is not supported since the built-in backup solution will not work in that case!"
 | |
|     exit 1
 | |
| elif ! sudo -u www-data docker inspect nextcloud-aio-mastercontainer | grep -q "nextcloud_aio_mastercontainer"; then
 | |
|     print_red "It seems like you did not attach the 'nextcloud_aio_mastercontainer' volume to the mastercontainer?
 | |
| This is not supported since the built-in backup solution will not work in that case!"
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| # Check for other options
 | |
| if [ -n "$NEXTCLOUD_DATADIR" ]; then
 | |
|     if [ "$NEXTCLOUD_DATADIR" = "nextcloud_aio_nextcloud_datadir" ]; then
 | |
|         sleep 1
 | |
|     elif ! echo "$NEXTCLOUD_DATADIR" | grep -q "^/" || [ "$NEXTCLOUD_DATADIR" = "/" ]; then
 | |
|         print_red "You've set NEXTCLOUD_DATADIR but not to an allowed value.
 | |
| The string must start with '/' and must not be equal to '/'. Also allowed is 'nextcloud_aio_nextcloud_datadir'.
 | |
| It is set to '$NEXTCLOUD_DATADIR'."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$NEXTCLOUD_MOUNT" ]; then
 | |
|     if ! echo "$NEXTCLOUD_MOUNT" | grep -q "^/" || [ "$NEXTCLOUD_MOUNT" = "/" ]; then
 | |
|         print_red "You've set NEXCLOUD_MOUNT but not to an allowed value.
 | |
| The string must start with '/' and must not be equal to '/'.
 | |
| It is set to '$NEXTCLOUD_MOUNT'."
 | |
|         exit 1
 | |
|     elif [ "$NEXTCLOUD_MOUNT" = "/mnt/ncdata" ] || echo "$NEXTCLOUD_MOUNT" | grep -q "^/mnt/ncdata/"; then
 | |
|         print_red "'/mnt/ncdata' and '/mnt/ncdata/' are not allowed as values for NEXTCLOUD_MOUNT."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$NEXTCLOUD_DATADIR" ] && [ -n "$NEXTCLOUD_MOUNT" ]; then
 | |
|     if [ "$NEXTCLOUD_DATADIR" = "$NEXTCLOUD_MOUNT" ]; then
 | |
|         print_red "NEXTCLOUD_DATADIR and NEXTCLOUD_MOUNT are not allowed to be equal."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$NEXTCLOUD_UPLOAD_LIMIT" ]; then
 | |
|     if ! echo "$NEXTCLOUD_UPLOAD_LIMIT" | grep -q '^[0-9]\+G$'; then
 | |
|         print_red "You've set NEXTCLOUD_UPLOAD_LIMIT but not to an allowed value.
 | |
| The string must start with a number and end with 'G'.
 | |
| It is set to '$NEXTCLOUD_UPLOAD_LIMIT'."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$NEXTCLOUD_MAX_TIME" ]; then
 | |
|     if ! echo "$NEXTCLOUD_MAX_TIME" | grep -q '^[0-9]\+$'; then
 | |
|         print_red "You've set NEXTCLOUD_MAX_TIME but not to an allowed value.
 | |
| The string must be a number. E.g. '3600'.
 | |
| It is set to '$NEXTCLOUD_MAX_TIME'."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$NEXTCLOUD_MEMORY_LIMIT" ]; then
 | |
|     if ! echo "$NEXTCLOUD_MEMORY_LIMIT" | grep -q '^[0-9]\+M$'; then
 | |
|         print_red "You've set NEXTCLOUD_MEMORY_LIMIT but not to an allowed value.
 | |
| The string must start with a number and end with 'M'.
 | |
| It is set to '$NEXTCLOUD_MEMORY_LIMIT'."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$APACHE_PORT" ]; then
 | |
|     if ! check_if_number "$APACHE_PORT"; then
 | |
|         print_red "You provided an Apache port but did not only use numbers.
 | |
| It is set to '$APACHE_PORT'."
 | |
|         exit 1
 | |
|     elif ! [ "$APACHE_PORT" -le 65535 ] || ! [ "$APACHE_PORT" -ge 1 ]; then
 | |
|         print_red "The provided Apache port is invalid. It must be between 1 and 65535"
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$APACHE_IP_BINDING" ]; then
 | |
|     if ! echo "$APACHE_IP_BINDING" | grep -q '^[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+$\|^[0-9a-f:]\+$'; then
 | |
|         print_red "You provided an ip-address for the apache container's ip-binding but it was not a valid ip-address.
 | |
| It is set to '$APACHE_IP_BINDING'."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$TALK_PORT" ]; then
 | |
|     if ! check_if_number "$TALK_PORT"; then
 | |
|         print_red "You provided an Talk port but did not only use numbers.
 | |
| It is set to '$TALK_PORT'."
 | |
|         exit 1
 | |
|     elif ! [ "$TALK_PORT" -le 65535 ] || ! [ "$TALK_PORT" -ge 1 ]; then
 | |
|         print_red "The provided Talk port is invalid. It must be between 1 and 65535"
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$APACHE_PORT" ] && [ -n "$TALK_PORT" ]; then
 | |
|     if [ "$APACHE_PORT" = "$TALK_PORT" ]; then
 | |
|         print_red "APACHE_PORT and TALK_PORT are not allowed to be equal."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$WATCHTOWER_DOCKER_SOCKET_PATH" ]; then
 | |
|     if ! echo "$WATCHTOWER_DOCKER_SOCKET_PATH" | grep -q "^/" || echo "$WATCHTOWER_DOCKER_SOCKET_PATH" | grep -q "/$"; then
 | |
|         print_red "You've set WATCHTOWER_DOCKER_SOCKET_PATH but not to an allowed value.
 | |
| The string must start with '/' and must not end with '/'.
 | |
| It is set to '$WATCHTOWER_DOCKER_SOCKET_PATH'."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$NEXTCLOUD_TRUSTED_CACERTS_DIR" ]; then
 | |
|     if ! echo "$NEXTCLOUD_TRUSTED_CACERTS_DIR" | grep -q "^/" || echo "$NEXTCLOUD_TRUSTED_CACERTS_DIR" | grep -q "/$"; then
 | |
|         print_red "You've set NEXTCLOUD_TRUSTED_CACERTS_DIR but not to an allowed value.
 | |
| It should be an absolute path to a directory that starts with '/' but not end with '/'.
 | |
| It is set to '$NEXTCLOUD_TRUSTED_CACERTS_DIR '."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$NEXTCLOUD_STARTUP_APPS" ]; then
 | |
|     if ! echo "$NEXTCLOUD_STARTUP_APPS" | grep -q "^[a-z0-9 _-]\+$"; then
 | |
|         print_red "You've set NEXTCLOUD_STARTUP_APPS but not to an allowed value.
 | |
| It needs to be a string. Allowed are small letters a-z, 0-9, spaces, hyphens and '_'.
 | |
| It is set to '$NEXTCLOUD_STARTUP_APPS'."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$NEXTCLOUD_ADDITIONAL_APKS" ]; then
 | |
|     if ! echo "$NEXTCLOUD_ADDITIONAL_APKS" | grep -q "^[a-z0-9 ._-]\+$"; then
 | |
|         print_red "You've set NEXTCLOUD_ADDITIONAL_APKS but not to an allowed value.
 | |
| It needs to be a string. Allowed are small letters a-z, digits 0-9, spaces, hyphens, dots and '_'.
 | |
| It is set to '$NEXTCLOUD_ADDITIONAL_APKS'."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS" ]; then
 | |
|     if ! echo "$NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS" | grep -q "^[a-z0-9 ._-]\+$"; then
 | |
|         print_red "You've set NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS but not to an allowed value.
 | |
| It needs to be a string. Allowed are small letters a-z, digits 0-9, spaces, hyphens, dots and '_'.
 | |
| It is set to '$NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS'."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| if [ -n "$AIO_COMMUNITY_CONTAINERS" ]; then
 | |
|     read -ra AIO_CCONTAINERS <<< "$AIO_COMMUNITY_CONTAINERS"
 | |
|     for container in "${AIO_CCONTAINERS[@]}"; do
 | |
|         if ! [ -d "/var/www/docker-aio/community-containers/$container" ]; then
 | |
|             print_red "The community container $container was not found!"
 | |
|             FAIL_CCONTAINERS=1
 | |
|         fi
 | |
|     done
 | |
|     if [ -n "$FAIL_CCONTAINERS" ]; then
 | |
|         print_red "You've set AIO_COMMUNITY_CONTAINERS but at least one container was not found.
 | |
| It is set to '$AIO_COMMUNITY_CONTAINERS'."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| 
 | |
| # Check DNS resolution
 | |
| # Prevents issues like https://github.com/nextcloud/all-in-one/discussions/565
 | |
| curl https://nextcloud.com &>/dev/null
 | |
| if [ "$?" = 6 ]; then
 | |
|     print_red "Could not resolve the host nextcloud.com."
 | |
|     echo "Most likely the DNS resolving does not work."
 | |
|     echo "You should be able to fix this by following https://dockerlabs.collabnix.com/intermediate/networking/Configuring_DNS.html"
 | |
|     echo "Apart from that, there has been this: https://github.com/nextcloud/all-in-one/discussions/2065"
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| # Check that no changes have been made to timezone settings since AIO only supports running in Etc/UTC timezone
 | |
| if [ -n "$TZ" ]; then
 | |
|     print_red "The environmental variable TZ has been set which is not supported by AIO since it only supports running in the default Etc/UTC timezone!"
 | |
|     echo "The correct timezone can be set in the AIO interface later on!"
 | |
|     # Disable exit since it seems to be by default set on unraid and we dont want to break these instances
 | |
|     # exit 1
 | |
| fi
 | |
| if mountpoint -q /etc/localtime; then
 | |
|     print_red "/etc/localtime has been mounted into the container which is not allowed because AIO only supports running in the default Etc/UTC timezone!"
 | |
|     echo "The correct timezone can be set in the AIO interface later on!"
 | |
|     exit 1
 | |
| fi
 | |
| if mountpoint -q /etc/timezone; then
 | |
|     print_red "/etc/timezone has been mounted into the container which is not allowed because AIO only supports running in the default Etc/UTC timezone!"
 | |
|     echo "The correct timezone can be set in the AIO interface later on!"
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| # Check if unsupported env are set (but don't exit as it would break many instances)
 | |
| if [ -n "$APACHE_DISABLE_REWRITE_IP" ]; then
 | |
|     print_red "The environmental variable APACHE_DISABLE_REWRITE_IP has been set which is not supported by AIO. Please remove it!"
 | |
| fi
 | |
| if [ -n "$NEXTCLOUD_TRUSTED_DOMAINS" ]; then
 | |
|     print_red "The environmental variable NEXTCLOUD_TRUSTED_DOMAINS has been set which is not supported by AIO. Please remove it!"
 | |
| fi
 | |
| if [ -n "$TRUSTED_PROXIES" ]; then
 | |
|     print_red "The environmental variable TRUSTED_PROXIES has been set which is not supported by AIO. Please remove it!"
 | |
| fi
 | |
| 
 | |
| # Add important folders
 | |
| mkdir -p /mnt/docker-aio-config/data/
 | |
| mkdir -p /mnt/docker-aio-config/session/
 | |
| mkdir -p /mnt/docker-aio-config/caddy/
 | |
| mkdir -p /mnt/docker-aio-config/certs/ 
 | |
| 
 | |
| # Adjust permissions for all instances
 | |
| chmod 770 -R /mnt/docker-aio-config
 | |
| chmod 777 /mnt/docker-aio-config
 | |
| chown www-data:www-data -R /mnt/docker-aio-config/data/
 | |
| chown www-data:www-data -R /mnt/docker-aio-config/session/
 | |
| chown www-data:www-data -R /mnt/docker-aio-config/caddy/
 | |
| chown root:root -R /mnt/docker-aio-config/certs/
 | |
| 
 | |
| # Don't allow access to the AIO interface from the Nextcloud container
 | |
| # Probably more cosmetic than anything but at least an attempt
 | |
| if ! grep -q '# nextcloud-aio-block' /etc/apache2/httpd.conf; then
 | |
|     cat << APACHE_CONF >> /etc/apache2/httpd.conf
 | |
| # nextcloud-aio-block-start
 | |
| <Location />
 | |
| order allow,deny
 | |
| deny from nextcloud-aio-nextcloud.nextcloud-aio
 | |
| allow from all
 | |
| </Location>
 | |
| # nextcloud-aio-block-end
 | |
| APACHE_CONF
 | |
| fi
 | |
| 
 | |
| # Adjust certs
 | |
| GENERATED_CERTS="/mnt/docker-aio-config/certs"
 | |
| TMP_CERTS="/etc/apache2/certs"
 | |
| mkdir -p "$GENERATED_CERTS"
 | |
| cd "$GENERATED_CERTS" || exit 1
 | |
| if ! [ -f ./ssl.crt ] && ! [ -f ./ssl.key ]; then
 | |
|     openssl req -new -newkey rsa:4096 -days 3650 -nodes -x509 -subj "/C=DE/ST=BE/L=Local/O=Dev/CN=nextcloud.local" -keyout ./ssl.key -out ./ssl.crt
 | |
| fi
 | |
| if [ -f ./ssl.crt ] && [ -f ./ssl.key ]; then
 | |
|     cd "$TMP_CERTS" || exit 1
 | |
|     rm ./ssl.crt
 | |
|     rm ./ssl.key
 | |
|     cp "$GENERATED_CERTS/ssl.crt" ./
 | |
|     cp "$GENERATED_CERTS/ssl.key" ./
 | |
| fi
 | |
| 
 | |
| print_green "Initial startup of Nextcloud All-in-One complete!
 | |
| You should be able to open the Nextcloud AIO Interface now on port 8080 of this server!
 | |
| E.g. https://internal.ip.of.this.server:8080
 | |
| 
 | |
| If your server has port 80 and 8443 open and you point a domain to your server, you can get a valid certificate automatically by opening the Nextcloud AIO Interface via:
 | |
| https://your-domain-that-points-to-this-server.tld:8443"
 | |
| 
 | |
| # Set the timezone to Etc/UTC
 | |
| export TZ=Etc/UTC
 | |
| 
 | |
| # Fix apache startup
 | |
| rm -f /var/run/apache2/httpd.pid
 | |
| 
 | |
| # Fix the Caddyfile format
 | |
| caddy fmt --overwrite /Caddyfile
 | |
| 
 | |
| # Fix caddy log 
 | |
| chmod 777 /root
 | |
| 
 | |
| # Start supervisord
 | |
| /usr/bin/supervisord -c /supervisord.conf
 |