Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow custom script execution on installation #1683

Conversation

Loxeno
Copy link

@Loxeno Loxeno commented Jan 26, 2022

Hi :)

Rebased #1260

First contribution ever using git, not sure if everything is ok so don't hesitate to tell me how to improve ;)

@skjnldsv
Copy link
Member

Could you rebase and only edit the entrypoint template in root and not the ones in the 21, 22, or 23 folder?

@Loxeno
Copy link
Author

Loxeno commented Apr 13, 2022

Hi,

I found another way to achieve what I wanted without any changes using NEXTCLOUD_UPDATE which allow running anything after docker-entrypoint.

It's hard to guess how this environment variable can do since there is no example in README.md .

This is how I do it :

docker-compose.yml :

  fpm:
    command: php-fpm
    configs:
      - source: nc-entrypoint-override
        target: /docker-entrypoint-override.sh
        mode: 0777
      - source: nc-entrypoint-override-postinstall
        target: /docker-entrypoint-override-postinstall.sh
        mode: 0777
    entrypoint: "/docker-entrypoint-override.sh"
    environment:
      - NEXTCLOUD_UPDATE=1

nc-entrypoint-override :

#!/bin/bash
set -eu

# usage: file_env VAR [DEFAULT]
#    ie: file_env 'XYZ_DB_PASSWORD' 'example'
# (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
#  "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
file_env() {
    local var="$1"
    local fileVar="${var}_FILE"
    local def="${2:-}"
    local varValue=$(env | grep -E "^${var}=" | sed -E -e "s/^${var}=//")
    local fileVarValue=$(env | grep -E "^${fileVar}=" | sed -E -e "s/^${fileVar}=//")
    if [ -n "${varValue}" ] && [ -n "${fileVarValue}" ]; then
        echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
        exit 1
    fi
    if [ -n "${varValue}" ]; then
        export "$var"="${varValue}"
    elif [ -n "${fileVarValue}" ]; then
        export "$var"="$(cat "${fileVarValue}")"
    elif [ -n "${def}" ]; then
        export "$var"="$def"
    fi
    unset "$fileVar"
}

sleep 30 # Need optimization
file_env OBJECTSTORE_S3_BUCKET
file_env OBJECTSTORE_S3_HOST
file_env OBJECTSTORE_S3_KEY
file_env OBJECTSTORE_S3_REGION
file_env OBJECTSTORE_S3_SECRET
file_env POSTGRES_HOST
file_env REDIS_HOST
file_env SMTP_NAME
file_env SMTP_PASSWORD

echo "Running entrypoint..."
exec /entrypoint.sh /docker-entrypoint-override-postinstall.sh $@

nc-entrypoint-override-postinstall :


#!/bin/bash
set -eu

run_as() {
    if [ "$(id -u)" = 0 ]; then
        su -p www-data -s /bin/sh -c "$1"
    else
        sh -c "$1"
    fi
}

if ! [ -n "$(run_as "php occ config:system:get configured")" ] ; then
	echo "Running post-install script..."

	if [ "${NEXTCLOUD_ENCRYPTION:-0}" -eq 1 ] ; then
		echo "Enabling encryption..."
		run_as "php occ app:enable encryption"
		run_as "php occ encryption:enable-master-key"
		run_as "php occ encryption:enable"
	fi
	
	if [ -n "${NEXTCLOUD_POSTINSTALL_APPS+x}" ] ; then
		echo "Installing apps..."
		for APP in $NEXTCLOUD_POSTINSTALL_APPS; do
			echo "Installing $APP"
			run_as "php occ app:install '$APP'"
		done
	fi

	if [ -n "${NEXTCLOUD_POSTINSTALL_USERS+x}" ] ; then
		echo "Importing users and groups from $NEXTCLOUD_POSTINSTALL_USERS..."

		OLDIFS=$IFS
		IFS=';'
		i=0

		while read -r username display_name email groups
		do
			export OC_PASS=$(/usr/bin/openssl rand -base64 12)
			
			run_as "php occ user:add --password-from-env --display-name '$display_name' $username"
			run_as "php occ user:setting '$username' settings email '$email'"

			if [ -n $groups ] ; then
				IFS=$OLDIFS
				for group in $groups ; do
					if ! [ "$(run_as "php occ group:list" | grep $group)" ] ; then
						run_as "php occ group:add -n $group"
					fi
					run_as "php occ group:adduser '$group' '$username'"
				done
				IFS=';'
			fi
		done < <(tail -n +2 $NEXTCLOUD_POSTINSTALL_USERS)
		IFS=$OLDIFS
	fi

	if [ -n "${NEXTCLOUD_POSTINSTALL_CUSTOMS+x}" ] ; then
		echo "Running postinstall customization..."
		run_as "$NEXTCLOUD_POSTINSTALL_CUSTOMS"
	fi

	run_as "php occ config:system:set configured --value=true"

	echo "Instance is now configured!"	
fi

exec "$@"

So I'm not sure if my previous changes are still needed.

@skjnldsv skjnldsv closed this Apr 13, 2022
@skjnldsv
Copy link
Member

Fair enough! Thanks :)

@tylerjharden
Copy link

@skjnldsv Any word on the official Nextcloud best practice for doing this?

From several GitHub issues and pull requests for installing/enabling apps from a derived Dockerimage, and following the Nextcloud example docker-compose setup for alpine with nginx-proxy and LE/ACME Companion, I went ahead and followed the custom entrypoint script found here from FUSS: https://gitlab.fuss.bz.it/fuss-team/fuss-nc/-/blob/476791f41dad509c677fc25e266a072074349c0e/nextcloud-fuss/configure-fuss.sh

When I run docker-compose up, the Nextcloud container just errors out on all calls to app:install telling me that Nextcloud is not installed. Am I missing something here? Do I still have to manually create a user from the Web UI, or can I do all this via Dockerfile / entrypoint.sh and docker-compose? We really need a fully automated CLI/API way of provisioning, theming, and setting up new Nextcloud instances for new users of our service, with no work required by the end-user.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants