Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ RUN ve/bin/pip install --no-cache-dir gunicorn
COPY --from=build-frontend /home/node/dist specifyweb/frontend/static/js
COPY --chown=specify:specify specifyweb /opt/specify7/specifyweb
COPY --chown=specify:specify manage.py /opt/specify7/
COPY --chown=specify:specify docker-entrypoint.sh /opt/specify7/
COPY --chown=specify:specify Makefile /opt/specify7/
COPY --chown=specify:specify specifyweb.wsgi /opt/specify7/

Expand Down Expand Up @@ -124,8 +123,6 @@ ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8
ENV DJANGO_SETTINGS_MODULE='settings'

ENTRYPOINT ["/opt/specify7/docker-entrypoint.sh"]

EXPOSE 8000


Expand Down Expand Up @@ -156,6 +153,8 @@ FROM run-common AS run

RUN mv specifyweb.wsgi specifyweb_wsgi.py

CMD ["ve/bin/gunicorn", "-w", "3", "-b", "0.0.0.0:8000", "-t", "300", "specifyweb_wsgi"]
COPY --chown=specify:specify docker-entrypoint.sh /opt/specify7/
ENTRYPOINT ["/opt/specify7/docker-entrypoint.sh"]
CMD ["sp7start"]


98 changes: 83 additions & 15 deletions docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,16 +1,84 @@
#!/bin/bash
set -e

if [ "$1" = 've/bin/gunicorn' ] || [ "$1" = 've/bin/python' ]; then
echo "Updating static files in /volumes/static-files/."
rsync -a --delete specifyweb/frontend/static/ /volumes/static-files/frontend-static
cd /opt/specify7
echo "Applying Django migrations."
set +e
# The following commands are prone to failing
# See https://github.com/specify/specify7/issues/789 and https://github.com/specify/docker-compositions/issues/7
ve/bin/python manage.py migrate notifications
ve/bin/python manage.py migrate workbench
set -e
fi
exec "$@"

# This entry point script implements a multi-mode image as described in
# https://aws.amazon.com/blogs/opensource/demystifying-entrypoint-cmd-docker/
#
# It supports the following commands:
#
# sp7start -- This is the default CMD. When the container is invoked
# this way it checks if any Django migrations need to be
# performed. If so it refuses to start and issues instructions to
# do the migrations. Otherwise it performs a normal Specify 7 start
# up.
#
# sp7migrate -- When the container is invoked with this command it
# executes any outstanding migrations.
#
# sp7migrate-and-start -- This command executes any migrations and
# then starts Specify 7. It is less safe than doing the migrations
# independently but is convenient in testing scenarios.
#
# sp7worker -- This command starts the container in worker mode and
# is intended to simplify docker-compose.yml files.
#
# Any other command is executed as is.
#
# For the sp7start and sp7worker commands, any arguments are passed through to
# the underlying gunicorn or celery command, respectively.


set -euf -o pipefail

sp7start () {
echo "Updating static files in /volumes/static-files/."
rsync -a --delete specifyweb/frontend/static/ /volumes/static-files/frontend-static

echo "Starting Specify 7."
exec ve/bin/gunicorn -w 3 -b 0.0.0.0:8000 -t 300 specifyweb_wsgi "$@"
}

sp7migrate () {
echo "Applying Django migrations."
ve/bin/python manage.py migrate notifications
ve/bin/python manage.py migrate workbench
}

case "$1" in
"sp7start" )
shift

if (ve/bin/python manage.py showmigrations notifications workbench | grep -q '\[ \]'); then
printf "\n\nSpecify 7 cannot start because Django migrations need to be applied.\n\n"
printf "Apply the migrations by:\n"
printf "1. Stopping any process that could be accessing your database \"$DATABASE_NAME\".\n"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to clarify that the database container should not be stopped?

Alternatively, this command would start the container if it wasn't running

docker container start DATABASE_CONTAINER
docker-compose run --rm specify7 sp7migrate

printf "2. Backing up the database \"$DATABASE_NAME\".\n"
printf "3. Applying the migrations by running \"docker-compose run --rm THIS-CONTAINER sp7migrate\".\n"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like docker-compose run requires SERVICE name, instead of CONTAINER name.
The service name is specify7, so this command would look like this:
docker-compose run --rm specify7 sp7migrate

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for reference, I received the following exception when trying to run a migration on a all-in-one composition, having forgotten to put any database into the seed-database folder.

Applying Django migrations.
[24/Nov/2021 18:47:27] [WARNING] [specifyweb.specify.load_datamodel:248] missing table or relationship setting dependent field: Deaccession.deaccessionpreparations
Operations to perform:
  Apply all migrations: notifications
Running migrations:
  Applying notifications.0001_initial...Traceback (most recent call last):
  File "/opt/specify7/ve/lib/python3.6/site-packages/django/db/backends/utils.py", line 84, in _execute
    return self.cursor.execute(sql, params)
  File "/opt/specify7/ve/lib/python3.6/site-packages/django/db/backends/mysql/base.py", line 71, in execute
    return self.cursor.execute(query, args)
  File "/opt/specify7/ve/lib/python3.6/site-packages/MySQLdb/cursors.py", line 250, in execute
    self.errorhandler(self, exc, value)
  File "/opt/specify7/ve/lib/python3.6/site-packages/MySQLdb/connections.py", line 50, in defaulterrorhandler
    raise errorvalue
  File "/opt/specify7/ve/lib/python3.6/site-packages/MySQLdb/cursors.py", line 247, in execute
    res = self._query(query)
  File "/opt/specify7/ve/lib/python3.6/site-packages/MySQLdb/cursors.py", line 412, in _query
    rowcount = self._do_query(q)
  File "/opt/specify7/ve/lib/python3.6/site-packages/MySQLdb/cursors.py", line 375, in _do_query
    db.query(q)
  File "/opt/specify7/ve/lib/python3.6/site-packages/MySQLdb/connections.py", line 276, in query
    _mysql.connection.query(self, query)
_mysql_exceptions.OperationalError: (1005, 'Can\'t create table `specify`.`notifications_message` (errno: 150 "Foreign key constraint is incorrectly formed")')

else
sp7start "$@"
fi
;;

"sp7migrate" )
shift

sp7migrate
;;

"sp7migrate-and-start" )
shift

sp7migrate
sp7start "$@"
;;

"sp7worker" )
shift

echo "Starting Specify 7 Worker."
exec ve/bin/celery -A specifyweb worker -l INFO --concurrency=1 "$@"
;;

*)
exec "$@"
;;
esac