From ce91cc8a0a66cb5a2f23c8234aa732e305029c38 Mon Sep 17 00:00:00 2001
From: Benjamin Bertrand <benjamin.bertrand@esss.se>
Date: Fri, 8 Sep 2017 11:02:07 +0200
Subject: [PATCH] Refactor and clean compose files

- use same postgres container for dev and test
  (create 2 different databases)
- use docker-compose.override.yml to avoid duplication
- ignore more files not needed in the docker image

By default docker-compose reads both docker-compose.yml and
docker-compose.override.yml.
In docker-compose.override.yml we mount the current directory as
a volume for development.

To test the image we only use docker-compose.yml:
- don't force port 5432 to the outside world to avoid conflict
- do not mount the current directory
---
 .dockerignore                |  8 ++++++--
 .env                         |  2 +-
 Jenkinsfile                  |  4 ++--
 Makefile                     | 19 ++++++++++++-------
 README.rst                   | 28 ++++++++++++++++++++--------
 docker-compose-test.yml      | 21 ---------------------
 docker-compose.override.yml  | 19 +++++++++++++++++++
 docker-compose.yml           | 17 ++++-------------
 postgres/create-test-db.sh   |  7 +++++++
 tests/functional/conftest.py |  2 +-
 10 files changed, 72 insertions(+), 55 deletions(-)
 delete mode 100644 docker-compose-test.yml
 create mode 100644 docker-compose.override.yml
 create mode 100755 postgres/create-test-db.sh

diff --git a/.dockerignore b/.dockerignore
index ab16628..bfa3cc3 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1,6 +1,10 @@
 .git
-*.swp
-__pycache__
+**/*.swp
+**/__pycache__
 settings*.cfg
 client
 data
+postgres
+Jenkinsfile
+Makefile
+docker-compose*.yml
diff --git a/.env b/.env
index 8aff1d7..b6c313d 100644
--- a/.env
+++ b/.env
@@ -1,4 +1,4 @@
 POSTGRES_USER=ics
 POSTGRES_PASSWORD=icspwd
 POSTGRES_DB=inventory_db
-PGDATA_VOLUME=./data/dev
+PGDATA_VOLUME=./data
diff --git a/Jenkinsfile b/Jenkinsfile
index 655d801..98c2a9b 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -22,10 +22,10 @@ pipeline {
         }
         stage('Test') {
             steps {
-                sh 'make db_test'
+                sh 'make db_image'
                 /* let the time to postgres to start */
                 sh 'sleep 5'
-                sh 'make test'
+                sh 'make test_image'
             }
         }
         stage('Push') {
diff --git a/Makefile b/Makefile
index 4de5afe..b4656cf 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-.PHONY: help build tag push refresh release db_dev initdb db_test test
+.PHONY: help build tag push refresh release db initdb test db_image test_image
 
 OWNER := europeanspallationsource
 GIT_TAG := $(shell git describe --always)
@@ -24,7 +24,7 @@ push: ## push the latest and git tag image
 
 clean: ## remove the image with git tag and the test database
 	-docker rmi $(OWNER)/$(IMAGE):$(GIT_TAG)
-	-docker rm -f inventory_postgres_test
+	-docker rm -f inventory_postgres
 
 refresh: ## pull the latest image from Docker Hub
 # skip if error: image might not be on dockerhub yet
@@ -36,14 +36,19 @@ release: refresh \
 	push
 release: ## build, tag, and push all stacks
 
-db_dev: ## start postgres for development
+db: ## start postgres for development
 	docker-compose up -d postgres
 
 initdb: ## initialize the dev database
 	docker-compose run --rm web flask initdb
 
-db_test: ## start postgres for test
-	docker-compose -f docker-compose-test.yml up -d postgres_test
+test:  ## run the tests (on current directory)
+	docker-compose run --rm web pytest --cov=app -v
 
-test:  ## run the tests
-	docker-compose -f docker-compose-test.yml run --rm web_test
+db_image: ## start postgres to test the latest image
+# Pass docker-compose.yml to skip docker-compose.override.yml
+	docker-compose -f docker-compose.yml up -d postgres
+
+test_image:  ## run the tests (on the latest image)
+# Pass docker-compose.yml to skip docker-compose.override.yml
+	docker-compose -f docker-compose.yml run --rm web
diff --git a/README.rst b/README.rst
index 89f675c..68e6022 100644
--- a/README.rst
+++ b/README.rst
@@ -11,14 +11,14 @@ You can use docker for development:
 
 1. Clone the repository
 
-2. Create the database. Data will be stored under "./data/dev" by default.
+2. Create the database. Data will be stored under "./data" by default.
    You can export the PGDATA_VOLUME variable to use another directory::
 
     # Start only postgres so it has time to initialize
     $ docker-compose up -d postgres
     or
-    $ make db_dev
-    # Create the database
+    $ make db
+    # Initialize the database
     $ docker-compose run --rm web flask initdb
     or
     $ make initdb
@@ -30,25 +30,37 @@ You can use docker for development:
 4. Open your browser and go to `http://localhost:8000
    <http://localhost:8000>`_.
 
+5. To run the tests::
+
+    $ make test
+
 
 Once the database has been created, you only need to run `docker-compose
 up` to start the app.
 
+
 Testing
 -------
 
-1. Create the database. Data will be stored under "./data/test"::
+By default docker-compose reads both docker-compose.yml and docker-compose.override.yml.
+In docker-compose.override.yml, the current directory is mounted as a volume.
+This is great for development.
+
+To test the built image, we should only use the docker-compose.yml (and ignore
+docker-compose.override.yml).
+
+1. Create the database::
 
     # Start only postgres so it has time to initialize
-    $ docker-compose -f docker-compose-test.yml up -d postgres_test
+    $ docker-compose -f docker-compose.yml up -d postgres
     or
-    $ make db_test
+    $ make db_image
 
 2. Run the tests::
 
-    $ docker-compose -f docker-compose-test.yml run --rm web_test
+    $ docker-compose -f docker-compose.yml run --rm web
     or
-    $ make test
+    $ make test_image
 
 
 Backup & restore
diff --git a/docker-compose-test.yml b/docker-compose-test.yml
deleted file mode 100644
index ed71ab4..0000000
--- a/docker-compose-test.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-version: '2'
-services:
-  web_test:
-    image: europeanspallationsource/ics-inventory:latest
-    container_name: inventory_web_test
-    build: .
-    command: pytest --cov=app -v
-    volumes:
-      - .:/app
-    depends_on:
-      - postgres_test
-  postgres_test:
-    image: postgres:9.6
-    container_name: inventory_postgres_test
-    expose:
-      - "5432"
-    environment:
-      POSTGRES_USER: ics
-      POSTGRES_PASSWORD: icstest
-      POSTGRES_DB: inventory_db_test
-      PGDATA: /var/lib/postgresql/data/pgdata
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
new file mode 100644
index 0000000..2551d30
--- /dev/null
+++ b/docker-compose.override.yml
@@ -0,0 +1,19 @@
+version: '2'
+services:
+  web:
+    build: .
+    environment:
+      LOCAL_SETTINGS: /app/settings.cfg
+      FLASK_APP: /app/wsgi.py
+      FLASK_DEBUG: 1
+    command: flask run --host 0.0.0.0 --port 8000
+    ports:
+      - "8000:8000"
+    volumes:
+      - .:/app
+  postgres:
+    ports:
+      - "5432:5432"
+    volumes:
+      - ./postgres/create-test-db.sh:/docker-entrypoint-initdb.d/create-test-db.sh
+      - ${PGDATA_VOLUME}:/var/lib/postgresql/data/pgdata
diff --git a/docker-compose.yml b/docker-compose.yml
index d6f7922..3d94e01 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -3,25 +3,16 @@ services:
   web:
     image: europeanspallationsource/ics-inventory:latest
     container_name: inventory_web
-    build: .
-    environment:
-      LOCAL_SETTINGS: /app/settings.cfg
-      FLASK_APP: /app/wsgi.py
-      FLASK_DEBUG: 1
-    command: flask run --host 0.0.0.0 --port 8000
-    ports:
-      - "8000:8000"
-    volumes:
-      - .:/app
+    command: pytest --cov=app -v
     depends_on:
       - postgres
   postgres:
     image: postgres:9.6
     container_name: inventory_postgres
-    ports:
-      - "5432:5432"
+    expose:
+      - "5432"
     volumes:
-      - ${PGDATA_VOLUME}:/var/lib/postgresql/data/pgdata
+      - ./postgres/create-test-db.sh:/docker-entrypoint-initdb.d/create-test-db.sh
     environment:
       POSTGRES_USER: ${POSTGRES_USER}
       POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
diff --git a/postgres/create-test-db.sh b/postgres/create-test-db.sh
new file mode 100755
index 0000000..da67a98
--- /dev/null
+++ b/postgres/create-test-db.sh
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+set -e
+
+psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" -d "$POSTGRES_DB" <<-EOSQL
+    CREATE DATABASE inventory_db_test;
+EOSQL
diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py
index 2147fdb..cd74317 100644
--- a/tests/functional/conftest.py
+++ b/tests/functional/conftest.py
@@ -22,7 +22,7 @@ def app(request):
     config = {
         'TESTING': True,
         'WTF_CSRF_ENABLED': False,
-        'SQLALCHEMY_DATABASE_URI': 'postgresql://ics:icstest@postgres_test/inventory_db_test',
+        'SQLALCHEMY_DATABASE_URI': 'postgresql://ics:icspwd@postgres/inventory_db_test',
         'INVENTORY_LDAP_GROUPS': {
             'admin': 'Inventory Admin',
             'create': 'Inventory User',
-- 
GitLab