From 0987c432f5d7989efd61b8646e2345adea181d7f Mon Sep 17 00:00:00 2001 From: Lukas Holecek Date: Apr 24 2019 08:17:57 +0000 Subject: [PATCH 1/5] Add docker-compose for development Signed-off-by: Lukas Holecek --- diff --git a/.gitignore b/.gitignore index 8d60068..6eb554c 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,4 @@ greenwave-test-cache.dbm* # Other .vagrant/ .vscode/ +docker/home/ diff --git a/Dockerfile b/Dockerfile index 4960881..871dd0b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,4 +35,5 @@ RUN pip3 install . --no-deps RUN rm -rf ./fedmsg.d USER 1001 EXPOSE 8080 -ENTRYPOINT docker/install-ca.sh && gunicorn-3 --workers 8 --bind 0.0.0.0:8080 --access-logfile=- --enable-stdio-inheritance greenwave.wsgi:app +ENTRYPOINT ["docker/docker-entrypoint.sh"] +CMD ["/usr/bin/gunicorn-3", "--workers", "8", "--bind", "0.0.0.0:8080", "--access-logfile", "-", "--enable-stdio-inheritance", "greenwave.wsgi:app"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f879809 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,132 @@ +version: '2.1' +services: + dev: + build: . + user: ${DEV_USER_ID:-1000} + working_dir: /code + environment: + HOME: /home/dev + PATH: /home/dev/.local/bin:/usr/bin + GREENWAVE_TEST_URL: http://dev:8080/ + WAIVERDB_TEST_URL: http://waiverdb:5004/ + RESULTSDB_TEST_URL: http://resultsdb:5001/ + PYTEST_ADDOPTS: "-o cache_dir=/home/dev/.pytest_cache" + command: + - "/bin/bash" + - "-c" + - | + set -e + + # Check if UID is same as owner of the mounted home directory + # (avoids creating files with wrong owner). + real_dev_id="$$(stat --format %u ~)" + if [[ $$real_dev_id != $$UID ]]; then + echo "Set correct DEV_USER_ID in .env file (should be same as owner of docker/home)." + exit 1 + fi + + exec /usr/bin/gunicorn-3 \ + --reload \ + --bind=0.0.0.0:8080 \ + --access-logfile=- \ + --enable-stdio-inheritance \ + greenwave.wsgi:app + volumes: + - ./:/code:ro,z + - ../waiverdb:/waiverdb:ro,z + - ../resultsdb:/resultsdb:ro,z + - ./docker/home:/home/dev:Z + - ./docker/greenwave-settings.py:/etc/greenwave/settings.py:ro,z + - ./conf/policies/:/etc/greenwave/policies/:ro,z + ports: + - 8080:8080 + depends_on: + - memcached + - resultsdb + - waiverdb + + resultsdb-db: + image: postgres:9.5.2 + restart: always + environment: + POSTGRES_USER: resultsdb + POSTGRES_PASSWORD: resultsdb + POSTGRES_DB: resultsdb + POSTGRES_INITDB_ARGS: "--auth='ident' --auth='trust'" + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 30s + timeout: 30s + retries: 3 + + resultsdb: + build: + context: ../resultsdb + dockerfile: openshift/Dockerfile + command: + - "/bin/bash" + - "-c" + - | + set -e + resultsdb init_db + exec mod_wsgi-express-3 start-server /usr/share/resultsdb/resultsdb.wsgi \ + --user apache --group apache \ + --port 5001 --threads 5 \ + --include-file /etc/httpd/conf.d/resultsdb.conf \ + --log-level info \ + --log-to-terminal \ + --access-log \ + --startup-log + volumes: + - ./docker/resultsdb-settings.py:/etc/resultsdb/settings.py:ro,z + - ./docker/resultsdb.conf:/etc/httpd/conf.d/resultsdb.conf:ro,z + ports: + - 5001:5001 + depends_on: + resultsdb-db: + condition: service_healthy + + waiverdb-db: + image: postgres:9.5.2 + restart: always + environment: + POSTGRES_USER: waiverdb + POSTGRES_PASSWORD: waiverdb + POSTGRES_DB: waiverdb + POSTGRES_INITDB_ARGS: "--auth='ident' --auth='trust'" + + waiverdb: + image: "quay.io/factory2/waiverdb:latest" + working_dir: /code + environment: + DATABASE_PASSWORD: waiverdb + SECRET_KEY: waiverdb + command: + - "/bin/bash" + - "-c" + - | + set -e + python3 waiverdb/manage.py wait-for-db + python3 waiverdb/manage.py db upgrade + exec /usr/bin/gunicorn-3 \ + --reload \ + --bind=0.0.0.0:5004 \ + --access-logfile=- \ + --enable-stdio-inheritance \ + waiverdb.wsgi:app + volumes: + - ../waiverdb:/code:ro,z + - ./docker/waiverdb-settings.py:/etc/waiverdb/settings.py:ro,z + - ./docker/client_secrets.json:/etc/secret/client_secrets.json:ro,z + ports: + - 5004:5004 + user: '0' + depends_on: + - waiverdb-db + + memcached: + image: "docker.io/modularitycontainers/memcached" + +networks: + default: + driver: bridge diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml deleted file mode 100644 index 29f13bd..0000000 --- a/docker/docker-compose.yml +++ /dev/null @@ -1,69 +0,0 @@ -version: '2.1' -services: - rdb: - image: postgres:9.5.2 - restart: always - environment: - POSTGRES_USER: resultsdb - POSTGRES_PASSWORD: resultsdb - POSTGRES_DB: resultsdb - POSTGRES_INITDB_ARGS: "--auth='ident' --auth='trust'" - healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] - interval: 30s - timeout: 30s - retries: 3 - - resultsdb: - image: "quay.io/factory2/resultsdb:latest" - volumes: - - ./resultsdb-settings.py:/etc/resultsdb/settings.py:ro,Z - - ./resultsdb.conf:/etc/httpd/conf.d/resultsdb.conf:ro,Z - ports: - - 5001:5001 - depends_on: - rdb: - condition: service_healthy - - wdb: - image: postgres:9.5.2 - restart: always - environment: - POSTGRES_USER: waiverdb - POSTGRES_PASSWORD: waiverdb - POSTGRES_DB: waiverdb - POSTGRES_INITDB_ARGS: "--auth='ident' --auth='trust'" - - waiverdb: - image: "quay.io/factory2/waiverdb:latest" - environment: - DATABASE_PASSWORD: waiverdb - SECRET_KEY: waiverdb - entrypoint: /bin/sh -i -c "waiverdb wait-for-db && waiverdb db upgrade && python3-gunicorn --bind 0.0.0.0:5004 --access-logfile=- waiverdb.wsgi:app" - volumes: - - ./waiverdb-settings.py:/etc/waiverdb/settings.py:ro,Z - - ./client_secrets.json:/etc/secret/client_secrets.json:ro,Z - ports: - - 5004:5004 - user: '0' - depends_on: - - wdb - - gmemcached: - image: "docker.io/modularitycontainers/memcached" - - greenwave: - image: "quay.io/factory2/greenwave:latest" - volumes: - - ./greenwave-settings.py:/etc/greenwave/settings.py:ro,Z - - ../conf/policies/:/etc/greenwave/policies/:ro,Z - depends_on: - - gmemcached - - resultsdb - - waiverdb - ports: - - 8080:8080 - -networks: - default: - driver: bridge diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh new file mode 100755 index 0000000..1f316cf --- /dev/null +++ b/docker/docker-entrypoint.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -e + +# CA_URL is the URL of a custom root CA certificate to be installed at run-time +: ${CA_URL:=} + +main() { + # installing CA certificate + if [ -n "${CA_URL}" ] && [ ! -f "/tmp/.ca-imported" ]; then + # Since update-ca-trust doesn't work as a non-root user, let's just append to the bundle directly + curl --silent --show-error --location "${CA_URL}" >> /etc/pki/tls/certs/ca-bundle.crt + # Create a file so we know not to import it again if the container is restarted + touch /tmp/.ca-imported + fi +} + +main +exec "$@" diff --git a/docker/greenwave-settings.py b/docker/greenwave-settings.py index 8dd4df2..8ba9cfd 100644 --- a/docker/greenwave-settings.py +++ b/docker/greenwave-settings.py @@ -5,13 +5,14 @@ DEBUG = False POLICIES_DIR = '/etc/greenwave/policies/' WAIVERDB_API_URL = 'http://waiverdb:5004/api/v1.0' RESULTSDB_API_URL = 'http://resultsdb:5001/api/v2.0' +GREENWAVE_API_URL = 'http://dev:8080/api/v1.0' CACHE = { # 'backend': "dogpile.cache.null", 'backend': "dogpile.cache.memcached", 'expiration_time': 1, # 1 is 1 second, keep to see that memcached # service is working 'arguments': { - 'url': 'gmemcached:11211', + 'url': 'memcached:11211', 'distributed_lock': True } } diff --git a/docker/home/README.md b/docker/home/README.md new file mode 100644 index 0000000..dc51045 --- /dev/null +++ b/docker/home/README.md @@ -0,0 +1 @@ +This directory is used as home for dev user with docker-compose. diff --git a/docker/install-ca.sh b/docker/install-ca.sh deleted file mode 100755 index fd600cc..0000000 --- a/docker/install-ca.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash -set -e - -if [ -n "${CA_URL}" ] && [ ! -f "/tmp/.imported" ]; then - # Since update-ca-trust doesn't work as a non-root user, let's just append to the bundle directly - curl --silent --show-error "${CA_URL}" >> /etc/pki/tls/certs/ca-bundle.crt - # Create a file so we know not to import it again if the container is restarted - touch /tmp/.imported -fi diff --git a/docker/resultsdb-settings.py b/docker/resultsdb-settings.py index 483375c..73bbe51 100644 --- a/docker/resultsdb-settings.py +++ b/docker/resultsdb-settings.py @@ -1,5 +1,5 @@ SECRET_KEY = 'resultsdb' -SQLALCHEMY_DATABASE_URI = 'postgresql+psycopg2://resultsdb:resultsdb@rdb:5432/resultsdb' +SQLALCHEMY_DATABASE_URI = 'postgresql+psycopg2://resultsdb:resultsdb@resultsdb-db:5432/resultsdb' FILE_LOGGING = False LOGFILE = '/var/log/resultsdb/resultsdb.log' SYSLOG_LOGGING = False @@ -9,3 +9,4 @@ RUN_PORT = 5001 MESSAGE_BUS_PUBLISH = False MESSAGE_BUS_PLUGIN = 'fedmsg' MESSAGE_BUS_KWARGS = {'modname': 'resultsdb'} +ADDITIONAL_RESULT_OUTCOMES = ('RUNNING', 'QUEUED') diff --git a/docker/resultsdb.conf b/docker/resultsdb.conf new file mode 100644 index 0000000..49618ea --- /dev/null +++ b/docker/resultsdb.conf @@ -0,0 +1,3 @@ + +# allow all methods + diff --git a/docker/waiverdb-settings.py b/docker/waiverdb-settings.py index 3d4d568..00edd9e 100644 --- a/docker/waiverdb-settings.py +++ b/docker/waiverdb-settings.py @@ -1,4 +1,4 @@ -DATABASE_URI = 'postgresql+psycopg2://waiverdb:waiverdb@wdb/waiverdb' +DATABASE_URI = 'postgresql+psycopg2://waiverdb:waiverdb@waiverdb-db/waiverdb' HOST = '0.0.0.0' PORT = 5004 #AUTH_METHOD = 'OIDC' diff --git a/docs/docker-compose.rst b/docs/docker-compose.rst index 609ad5e..b175699 100644 --- a/docs/docker-compose.rst +++ b/docs/docker-compose.rst @@ -1,8 +1,8 @@ Docker-compose for Greenwave =========================================== -virtualenv and docker-compose Quickstart ----------------------------------------- +Quickstart +---------- Start local development containers of ResultsDB and WaiverDB using ``docker-compose``. If you want the containers to run in the foreground, omit @@ -10,37 +10,20 @@ the ``-d`` flag. .. code-block:: console - $ sudo docker-compose -f docker/docker-compose.yml up -d resultsdb waiverdb + $ docker-compose up -d -Create a Python virtualenv: +Install development requirements: .. code-block:: console - $ mkvirtualenv greenwave -p python3 - $ pip install -r requirements.txt - $ pip install -r dev-requirements.txt + $ docker-compose exec dev pip3 install --user -r dev-requirements.txt -r requirements.txt + $ docker-compose exec dev pip3 install --user -r ../resultsdb/requirements.txt -Create a local configuration file: +You can run the unit and functional tests with the following command: .. code-block:: console - $ cp conf/settings.py.example conf/settings.py - -Run the development server: - -.. code-block:: console - - $ DEV=true FLASK_ENV=development python3 run-dev-server.py - -You can run the unit tests, which live in the ``greenwave.tests`` package, with -the following command: - -.. code-block:: console - - $ pytest greenwave/tests/ - -The functional tests will not work this setup since they require ResultsDB, -WaiverDB, and Postgresql to be running locally. + $ docker-compose exec dev pytest Rationale --------- From 8efdcf09fd0e2202342a5454728e230ae7065767 Mon Sep 17 00:00:00 2001 From: Lukas Holecek Date: Apr 24 2019 08:17:57 +0000 Subject: [PATCH 2/5] Move command and environment sections from docker-compose Signed-off-by: Lukas Holecek --- diff --git a/docker-compose.yml b/docker-compose.yml index f879809..9ef68d4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,33 +4,8 @@ services: build: . user: ${DEV_USER_ID:-1000} working_dir: /code - environment: - HOME: /home/dev - PATH: /home/dev/.local/bin:/usr/bin - GREENWAVE_TEST_URL: http://dev:8080/ - WAIVERDB_TEST_URL: http://waiverdb:5004/ - RESULTSDB_TEST_URL: http://resultsdb:5001/ - PYTEST_ADDOPTS: "-o cache_dir=/home/dev/.pytest_cache" - command: - - "/bin/bash" - - "-c" - - | - set -e - - # Check if UID is same as owner of the mounted home directory - # (avoids creating files with wrong owner). - real_dev_id="$$(stat --format %u ~)" - if [[ $$real_dev_id != $$UID ]]; then - echo "Set correct DEV_USER_ID in .env file (should be same as owner of docker/home)." - exit 1 - fi - - exec /usr/bin/gunicorn-3 \ - --reload \ - --bind=0.0.0.0:8080 \ - --access-logfile=- \ - --enable-stdio-inheritance \ - greenwave.wsgi:app + env_file: docker/dev.env + command: ["bash", "-c", "./docker/dev-command.sh"] volumes: - ./:/code:ro,z - ../waiverdb:/waiverdb:ro,z @@ -48,11 +23,7 @@ services: resultsdb-db: image: postgres:9.5.2 restart: always - environment: - POSTGRES_USER: resultsdb - POSTGRES_PASSWORD: resultsdb - POSTGRES_DB: resultsdb - POSTGRES_INITDB_ARGS: "--auth='ident' --auth='trust'" + env_file: docker/resultsdb-db.env healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres"] interval: 30s @@ -63,21 +34,9 @@ services: build: context: ../resultsdb dockerfile: openshift/Dockerfile - command: - - "/bin/bash" - - "-c" - - | - set -e - resultsdb init_db - exec mod_wsgi-express-3 start-server /usr/share/resultsdb/resultsdb.wsgi \ - --user apache --group apache \ - --port 5001 --threads 5 \ - --include-file /etc/httpd/conf.d/resultsdb.conf \ - --log-level info \ - --log-to-terminal \ - --access-log \ - --startup-log + command: ["bash", "-c", "/start.sh"] volumes: + - ./docker/resultsdb-command.sh:/start.sh:ro,z - ./docker/resultsdb-settings.py:/etc/resultsdb/settings.py:ro,z - ./docker/resultsdb.conf:/etc/httpd/conf.d/resultsdb.conf:ro,z ports: @@ -89,33 +48,16 @@ services: waiverdb-db: image: postgres:9.5.2 restart: always - environment: - POSTGRES_USER: waiverdb - POSTGRES_PASSWORD: waiverdb - POSTGRES_DB: waiverdb - POSTGRES_INITDB_ARGS: "--auth='ident' --auth='trust'" + env_file: docker/waiverdb-db.env waiverdb: image: "quay.io/factory2/waiverdb:latest" working_dir: /code - environment: - DATABASE_PASSWORD: waiverdb - SECRET_KEY: waiverdb - command: - - "/bin/bash" - - "-c" - - | - set -e - python3 waiverdb/manage.py wait-for-db - python3 waiverdb/manage.py db upgrade - exec /usr/bin/gunicorn-3 \ - --reload \ - --bind=0.0.0.0:5004 \ - --access-logfile=- \ - --enable-stdio-inheritance \ - waiverdb.wsgi:app + env_file: docker/waiverdb.env + command: ["bash", "-c", "/start.sh"] volumes: - ../waiverdb:/code:ro,z + - ./docker/waiverdb-command.sh:/start.sh:ro,z - ./docker/waiverdb-settings.py:/etc/waiverdb/settings.py:ro,z - ./docker/client_secrets.json:/etc/secret/client_secrets.json:ro,z ports: diff --git a/docker/dev-command.sh b/docker/dev-command.sh new file mode 100755 index 0000000..2a014f3 --- /dev/null +++ b/docker/dev-command.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -e + +# Check if UID is same as owner of the mounted home directory +# (avoids creating files with wrong owner). +real_dev_id="$(stat --format %u ~)" +if [[ $real_dev_id != "$UID" ]]; then + echo "Set correct DEV_USER_ID in .env file (should be same as owner of docker/home)." + exit 1 +fi + +exec /usr/bin/gunicorn-3 \ + --reload \ + --bind=0.0.0.0:8080 \ + --access-logfile=- \ + --enable-stdio-inheritance \ + greenwave.wsgi:app diff --git a/docker/dev.env b/docker/dev.env new file mode 100644 index 0000000..a7cd506 --- /dev/null +++ b/docker/dev.env @@ -0,0 +1,6 @@ +HOME=/home/dev +PATH=/home/dev/.local/bin:/usr/bin +GREENWAVE_TEST_URL=http://dev:8080/ +WAIVERDB_TEST_URL=http://waiverdb:5004/ +RESULTSDB_TEST_URL=http://resultsdb:5001/ +PYTEST_ADDOPTS="-o cache_dir=/home/dev/.pytest_cache" diff --git a/docker/resultsdb-command.sh b/docker/resultsdb-command.sh new file mode 100755 index 0000000..0e05fe9 --- /dev/null +++ b/docker/resultsdb-command.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -e +resultsdb init_db +exec mod_wsgi-express-3 start-server /usr/share/resultsdb/resultsdb.wsgi \ + --user apache --group apache \ + --port 5001 --threads 5 \ + --include-file /etc/httpd/conf.d/resultsdb.conf \ + --log-level info \ + --log-to-terminal \ + --access-log \ + --startup-log diff --git a/docker/resultsdb-db.env b/docker/resultsdb-db.env new file mode 100644 index 0000000..7330e00 --- /dev/null +++ b/docker/resultsdb-db.env @@ -0,0 +1,4 @@ +POSTGRES_USER=resultsdb +POSTGRES_PASSWORD=resultsdb +POSTGRES_DB=resultsdb +POSTGRES_INITDB_ARGS=--auth=ident --auth=trust diff --git a/docker/waiverdb-command.sh b/docker/waiverdb-command.sh new file mode 100755 index 0000000..e4bda54 --- /dev/null +++ b/docker/waiverdb-command.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -e +python3 waiverdb/manage.py wait-for-db +python3 waiverdb/manage.py db upgrade +exec /usr/bin/gunicorn-3 \ + --reload \ + --bind=0.0.0.0:5004 \ + --access-logfile=- \ + --enable-stdio-inheritance \ + waiverdb.wsgi:app diff --git a/docker/waiverdb-db.env b/docker/waiverdb-db.env new file mode 100644 index 0000000..2109fef --- /dev/null +++ b/docker/waiverdb-db.env @@ -0,0 +1,4 @@ +POSTGRES_USER=waiverdb +POSTGRES_PASSWORD=waiverdb +POSTGRES_DB=waiverdb +POSTGRES_INITDB_ARGS=--auth=ident --auth=trust diff --git a/docker/waiverdb.env b/docker/waiverdb.env new file mode 100644 index 0000000..1a6bc3b --- /dev/null +++ b/docker/waiverdb.env @@ -0,0 +1,2 @@ +DATABASE_PASSWORD=waiverdb +SECRET_KEY=waiverdb From 81053a1b9800e669653e23a165d4511294cf291d Mon Sep 17 00:00:00 2001 From: Lukas Holecek Date: Apr 24 2019 08:17:57 +0000 Subject: [PATCH 3/5] Omit mounting and installing unneeded dev dependencies Signed-off-by: Lukas Holecek --- diff --git a/docker-compose.yml b/docker-compose.yml index 9ef68d4..1de27aa 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,8 +8,6 @@ services: command: ["bash", "-c", "./docker/dev-command.sh"] volumes: - ./:/code:ro,z - - ../waiverdb:/waiverdb:ro,z - - ../resultsdb:/resultsdb:ro,z - ./docker/home:/home/dev:Z - ./docker/greenwave-settings.py:/etc/greenwave/settings.py:ro,z - ./conf/policies/:/etc/greenwave/policies/:ro,z @@ -56,7 +54,7 @@ services: env_file: docker/waiverdb.env command: ["bash", "-c", "/start.sh"] volumes: - - ../waiverdb:/code:ro,z + - ../waiverdb:/code:ro,Z - ./docker/waiverdb-command.sh:/start.sh:ro,z - ./docker/waiverdb-settings.py:/etc/waiverdb/settings.py:ro,z - ./docker/client_secrets.json:/etc/secret/client_secrets.json:ro,z diff --git a/docs/docker-compose.rst b/docs/docker-compose.rst index b175699..4847888 100644 --- a/docs/docker-compose.rst +++ b/docs/docker-compose.rst @@ -16,8 +16,7 @@ Install development requirements: .. code-block:: console - $ docker-compose exec dev pip3 install --user -r dev-requirements.txt -r requirements.txt - $ docker-compose exec dev pip3 install --user -r ../resultsdb/requirements.txt + $ docker-compose exec dev pip3 install --user -r dev-requirements.txt You can run the unit and functional tests with the following command: From 73915f45c8a1c0e823de12a5952224fb1f993a00 Mon Sep 17 00:00:00 2001 From: Lukas Holecek Date: Apr 24 2019 08:17:57 +0000 Subject: [PATCH 4/5] Document workaround for mismatching pyc files Signed-off-by: Lukas Holecek --- diff --git a/docs/docker-compose.rst b/docs/docker-compose.rst index 4847888..871d5cb 100644 --- a/docs/docker-compose.rst +++ b/docs/docker-compose.rst @@ -24,6 +24,20 @@ You can run the unit and functional tests with the following command: $ docker-compose exec dev pytest +You could encounter following error when executing the application or tests in +both in and outside the container. + +.. code-block:: console + + ImportError while loading conftest '/code/conftest.py'. + py._path.local.LocalPath.ImportMismatchError: ('conftest', '/home/user/proj/greenwave/conftest.py', local('/code/conftest.py')) + +To resolve this, run this command in the project directory: + +.. code-block:: console + + $ find -name '*.pyc' -delete + Rationale --------- From 5de57315d3b3e19bd59092ae8f63aa932ca5054b Mon Sep 17 00:00:00 2001 From: Lukas Holecek Date: Apr 24 2019 08:41:23 +0000 Subject: [PATCH 5/5] Document docker-compose flag --force-recreate Signed-off-by: Lukas Holecek --- diff --git a/docs/docker-compose.rst b/docs/docker-compose.rst index 871d5cb..2129a0e 100644 --- a/docs/docker-compose.rst +++ b/docs/docker-compose.rst @@ -6,7 +6,8 @@ Quickstart Start local development containers of ResultsDB and WaiverDB using ``docker-compose``. If you want the containers to run in the foreground, omit -the ``-d`` flag. +the ``-d`` flag. If you want to create the containers again (after some code +changes) add ``--force-recreate`` flag. .. code-block:: console