arangodb-docker
arangodb-docker copied to clipboard
docker-entrypoint-initdb.d is nice, but how about docker-entrypoint-upgradedb.d?
When extending the ArangoDB docker image as a base image to dockerize a Foxx service (or anything else really) it's extremely useful to be able to just stuff /docker-entrypoint-initdb.d full of shell scripts doing things like
foxx install /myapp /myapp.zip -H $ARANGO_INIT_ENDPOINT
to get the database up and started. However this is only useful for a first-time run. Once the database is initialised, changes to these shell scripts or arangosh JS scripts won't have any effect.
If you want to deploy a new version of your Foxx service or run some migrations, there's no way to d that automatically as part of upgrading to a new version of your image (e.g. using docker-compose).
I ended up having to wrap the existing entrypoint script with my own like so:
#!/bin/sh
set -e
# This is the opposite of the check in entrypoint.sh:
# i.e. only proceed if the DB was already initialised
if [ -f /var/lib/arangodb3/SERVER ]; then
export ARANGO_INIT_ENDPOINT=tcp://127.0.0.1:8999
# Upgrade ArangoDB if the base image changed to a new semver minor
# See #72 for thoughts on this
arangod --config /etc/arangodb3/arangod.conf \
--server.endpoint $ARANGO_INIT_ENDPOINT \
--database.auto-upgrade true
# Start up the DB in init mode, again
arangod --config /etc/arangodb3/arangod.conf \
--server.endpoint $ARANGO_INIT_ENDPOINT \
--server.authentication false \
--log.file /tmp/init-log \
--log.foreground-tty false &
pid="$!"
counter=0
ARANGO_UP=0
while [ "$ARANGO_UP" = "0" ]; do
if [ $counter -gt 0 ]; then
sleep 1
fi
if [ "$counter" -gt 100 ]; then
echo "ArangoDB didn't start correctly during init"
cat /tmp/init-log
exit 1
fi
let counter=counter+1
ARANGO_UP=1
arangosh \
--server.endpoint=$ARANGO_INIT_ENDPOINT \
--server.authentication false \
--javascript.execute-string "db._version()" \
> /dev/null 2>&1 || ARANGO_UP=0
done
# Now we can upgrade the service
foxx upgrade /myapp /myapp.zip -H $ARANGO_INIT_ENDPOINT
# Wind the db down again
if ! kill -s TERM "$pid" || ! wait "$pid"; then
echo >&2 'ArangoDB Init failed.'
exit 1
fi
fi
# Proceed normally with the original entrypoint.sh of the base image
. /arango-entrypoint.sh $@
This is tedious and unwieldy. But I think we could generalise this.
Why not extend the entrypoint.sh so that on non-initial runs (i.e. if the SERVER file already exists) we check if a special directory like /docker-entrypoint-upgradedb.d (or whatever) is non-empty, and then just do what we're doing for the files in docker-entrypoint-initdb.d?
This would mean users no longer have to mess with the entrypoint and could just create a dockerfile like this for dockerizing a single Foxx service:
FROM arangodb:3.6.1
COPY myapp.zip /myapp.zip
RUN echo 'foxx install /myapp /myapp.zip -H http://127.0.0.1:$ARANGO_INIT_PORT' > /docker-entrypoint-initdb.d/install-myapp.sh
RUN echo 'foxx upgrade /myapp /myapp.zip -H http://127.0.0.1:$ARANGO_INIT_PORT' > /docker-entrypoint-upgradedb.d/upgrade-myapp.sh
And it would "just work" (TM).
/cc @joerg84
This is a papercut I ran into while using docker with Foxx myself. The workaround is clunky and fragile. I don't think it would be too complicated to extend the entrypoint.sh to simplify users' dockerfiles to what I show in the end with no other dependencies.
Adding the --database.auto-upgrade true option to the entrypoint script would be really helpful if you're interested in keeping your engine up-to-date and want to keep your existing database working in an easy way.
Thumbs up for this!
I am been bitten by this. And my lack of knowledge makes it harder to know the easiest way to run a upgrade...