diff --git a/Dockerfile b/Dockerfile
index cea19f3..87a1883 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,6 +6,8 @@ ENV NEXTCLOUD_EXEC_USER=www-data
ENV NEXTCLOUD_CONTAINER_NAME=
ENV NEXTCLOUD_PROJECT_NAME=
ENV NEXTCLOUD_CRON_MINUTE_INTERVAL=15
+ENV NEXTCLOUD_EXEC_SHELL=bash
+ENV NEXTCLOUD_EXEC_SHELL_ARGS=-c
COPY scripts/*.sh /
COPY scripts/cron-scripts /cron-scripts
diff --git a/README.md b/README.md
index e5169ff..f791104 100644
--- a/README.md
+++ b/README.md
@@ -77,6 +77,17 @@ how this all works.
in the tasks being executed using the Nextcloud container's running user. Specifically, the
`--user` option will *not* be provided to the `docker exec` command.
+* `NEXTCLOUD_EXEC_SHELL`
+ Allows specifying a custom shell program that will be used to execute cron tasks inside the
+ Nextcloud container. This shell program *must* exist inside the Nextcloud container itself
+ (validation happens on start up to ensure this). The default value if not specified is `bash`.
+
+* `NEXTCLOUD_EXEC_SHELL_ARGS`
+ Allows custom arguments to be passed to the shell program specified by `NEXTCLOUD_EXEC_SHELL`. See
+ the detailed documentation provided later on in this document for more information. At minimum,
+ the arguments passed to your shell program must allow for the execution of a series of string
+ commands. The default value if not specified is `-c`.
+
* `DEBUG`
Enables more verbose logging in core scripts. Useful only for development. To get more verbose
output in your own custom cron scripts, use `set -x` in the actual script.
@@ -103,15 +114,15 @@ in addition to the default `cron.php` task. To add your custom tasks, follow the
1. Write a shell script that runs the commands that will be part of your task. This shell script
must have the `.sh` extension. An example of the contents of such a script is below. As an
optional security measure, do not make this shell script executable. The contents of the file are
- piped into `bash`, so the executable bit is not used.
+ piped into `sh`, so the executable bit and shebang line are not used or required.
```sh
- #!/usr/bin/env bash
php -f /var/www/html/cron.php
```
-2. Mount this shell script inside the `/cron-scripts` directory. Here's an example if you're using
- `docker-compose.yml`:
+2. Mount this shell script inside the `/cron-scripts` directory. You may also choose to *replace*
+ this directory, but bear in mind that you will not be running the built-in cron tasks in that
+ case. Here's an example if you're using `docker-compose.yml`:
```yml
services:
@@ -139,11 +150,42 @@ services:
As an optional safety measure, mount the directory or files as read-only (via the `:ro` at the end).
The container should not modify the files, but it doesn't hurt to be explicitly strict.
+### Customizing the Shell
+
+By default, all cron task scripts in the `/cron-scripts` directory are executed with `bash`.
+However, not all Nextcloud containers have `bash`. In this case, you may want to override it with a
+shell like `sh`. You can accomplish this (as well as customizing the arguments passed to the shell)
+with `NEXTCLOUD_EXEC_SHELL` and `NEXTCLOUD_EXEC_SHELL_ARGS`.
+
+The shell args are used when passing the contents of script files to the shell executable inside the
+Nextcloud container. Customizing the args might be necessary depending on the shell program you
+choose, or you may want to leverage options for debugging purposes (See "Debugging" section for
+examples).
+
+> **NOTE**
+> The arguments that are passed to the shell program must, at least, allow the execution of a string
+> of commands. See the documentation on your chosen shell for which arguments these should be.
+
+Here is an example of how you would override `bash` for `sh` using `docker-compose.yml` (again,
+greatly simplified for example purposes; this is not a complete YAML):
+
+```yml
+services:
+ cron:
+ image: rcdailey/nextcloud-cronjob
+ environment:
+ - NEXTCLOUD_EXEC_SHELL=sh
+ - NEXTCLOUD_EXEC_SHELL_ARGS=-c
+```
+
+Note that `-c` is the default for `NEXTCLOUD_EXEC_SHELL_ARGS`, so it isn't necessary to specify it
+above. However, it is explicitly specified for example purposes.
+
### Notes
* All cron task shell scripts run at the same interval defined by `NEXTCLOUD_CRON_MINUTE_INTERVAL`.
* Modification of your own shell scripts on the host do not require that you restart/recreate the
- container.
+ container (only when volume mappings change in the YAML file).
## Debugging
@@ -161,3 +203,17 @@ Started crond
> Running Script: run_cron_php.sh
> Done
```
+
+You can leverage `NEXTCLOUD_EXEC_SHELL_ARGS` to get more verbose output from your scripts. For
+example, for `bash` you can specify `-x` for debug mode. So you could use this in your YAML:
+
+```yml
+services:
+ cron:
+ image: rcdailey/nextcloud-cronjob
+ environment:
+ - NEXTCLOUD_EXEC_SHELL_ARGS=-xc
+```
+
+Note the addition of `-x` in the arguments. This will provide line-by-line output for each cron task
+shell script executed.
diff --git a/scripts/cron-scripts/run-cron-php.sh b/scripts/cron-scripts/run-cron-php.sh
index 7cd1f8e..ffd5169 100644
--- a/scripts/cron-scripts/run-cron-php.sh
+++ b/scripts/cron-scripts/run-cron-php.sh
@@ -1,2 +1 @@
-#!/usr/bin/env bash
php -f /var/www/html/cron.php
diff --git a/scripts/cron-tasks.sh b/scripts/cron-tasks.sh
index e4c886b..597f675 100755
--- a/scripts/cron-tasks.sh
+++ b/scripts/cron-tasks.sh
@@ -2,16 +2,12 @@
set -e
[[ ! -z "$DEBUG" ]] && set -x
+source /nextcloud-exec.sh
+
echo "-------------------------------------------------------------"
echo " Executing Cron Tasks: $(date)"
echo "-------------------------------------------------------------"
-# If a user must be specified when executing the task, set up that option here.
-# You may also leave NEXTCLOUD_EXEC_USER blank, in which case it will not be used.
-if [[ -n "$NEXTCLOUD_EXEC_USER" ]]; then
- exec_user="--user $NEXTCLOUD_EXEC_USER"
-fi
-
# Obtain the ID of the container. We do this each iteration since the Nextcloud container may be
# recreated while the cron container is still running. We will need to check for a new container ID
# each time.
@@ -23,13 +19,17 @@ fi
echo "> Nextcloud Container ID: ${containerId}"
+run_scripts_in_dir() {
+ cd "$1"
+ for script in *.sh; do
+ echo "> Running Script: $script"
+ nextcloud_exec "$containerId" "$(< $script)"
+ done
+}
+
# Loop through all shell scripts and execute the contents of those scripts in the Nextcloud
# container. It's done this way so that the user may mount more scripts to be executed in addition
# to the default ones.
-cd /cron-scripts
-for script in *.sh; do
- echo "> Running Script: $script"
- docker exec $exec_user -i "$containerId" bash < $script
-done
+run_scripts_in_dir /cron-scripts
echo "> Done"
diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh
index 6351879..1bf14ca 100755
--- a/scripts/entrypoint.sh
+++ b/scripts/entrypoint.sh
@@ -2,6 +2,8 @@
set -e
[[ ! -z "$DEBUG" ]] && set -x
+source /nextcloud-exec.sh
+
if [[ -z "$NEXTCLOUD_CONTAINER_NAME" ]]; then
echo "NEXTCLOUD_CONTAINER_NAME is a required variable"
exit 1
@@ -24,6 +26,15 @@ else
echo "Found Nextcloud container with ID $containerId"
fi
+# Verify the chosen shell exists in the Nextcloud container
+if ! nextcloud_exec_no_shell "$containerId" sh -c "command -v \"$NEXTCLOUD_EXEC_SHELL\"" >/dev/null 2>&1
+then
+ echo "ERROR: Shell \"$NEXTCLOUD_EXEC_SHELL\" does not exist in the Nextcloud container"
+ exit 1
+else
+ echo "Chosen shell \"$NEXTCLOUD_EXEC_SHELL\" was found in the Nextcloud container"
+fi
+
echo "*/$NEXTCLOUD_CRON_MINUTE_INTERVAL * * * * /cron-tasks.sh" \
> /var/spool/cron/crontabs/root
diff --git a/scripts/nextcloud-exec.sh b/scripts/nextcloud-exec.sh
new file mode 100644
index 0000000..a6d978f
--- /dev/null
+++ b/scripts/nextcloud-exec.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+
+nextcloud_exec_no_shell() {
+ containerId="$1"; shift
+
+ # If a user must be specified when executing the task, set up that option here.
+ # You may also leave NEXTCLOUD_EXEC_USER blank, in which case it will not be used.
+ if [[ -n "$NEXTCLOUD_EXEC_USER" ]]; then
+ exec_user="--user $NEXTCLOUD_EXEC_USER"
+ fi
+
+ docker exec $exec_user -i "$containerId" "$@"
+}
+
+nextcloud_exec() {
+ containerId="$1"; shift
+ nextcloud_exec_no_shell "$containerId" "$NEXTCLOUD_EXEC_SHELL" $NEXTCLOUD_EXEC_SHELL_ARGS "$@"
+}
diff --git a/test/shell-test/docker-compose.yml b/test/shell-test/docker-compose.yml
new file mode 100644
index 0000000..d2508b2
--- /dev/null
+++ b/test/shell-test/docker-compose.yml
@@ -0,0 +1,20 @@
+version: '3'
+
+services:
+ app:
+ image: nextcloud:19-fpm-alpine
+
+ cronjob:
+ build: ../..
+ depends_on:
+ - app
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock:ro
+ - /etc/localtime:/etc/localtime:ro
+ environment:
+ - NEXTCLOUD_PROJECT_NAME=shell-test
+ - NEXTCLOUD_CONTAINER_NAME=app
+ - NEXTCLOUD_CRON_MINUTE_INTERVAL=1
+ - NEXTCLOUD_EXEC_SHELL=sh
+ - NEXTCLOUD_EXEC_SHELL_ARGS=-xc
+ - DEBUG=1