Skip to content

Instantly share code, notes, and snippets.

@khaledboka
Last active July 29, 2021 08:48
Show Gist options
  • Select an option

  • Save khaledboka/25d1263c8dbf465dfd227b08b81edcd5 to your computer and use it in GitHub Desktop.

Select an option

Save khaledboka/25d1263c8dbf465dfd227b08b81edcd5 to your computer and use it in GitHub Desktop.
How to connect GeoNode Docker to External Database

Connecting GeoNode Docker to an External Database

1. Make sure docker components are down

>_ docker-compose down

2. Disable GeoNode docker database and related commands

  • @docker-compose.yml comment out the db section

    # # PostGIS database.
    # db:
    #   # use geonode official postgis 11 image
    #   image: geonode/postgis:latest
    #   container_name: db4${COMPOSE_PROJECT_NAME}
    #   env_file:
    #     - ./scripts/docker/env/${DOCKER_ENV}/db.env
    #   volumes:
    #     - dbdata:/var/lib/postgresql/data
    #     - dbbackups:/pg_backups
    #   restart: on-failure
    #   # uncomment to enable remote connections to postgres
    #   #ports:
    #   #  - "5432:5432"
  • @docker-compose.yml comment out the related volumes section

    # dbdata:
    #   name: ${COMPOSE_PROJECT_NAME}-dbdata
    # dbbackups:
    #   name: ${COMPOSE_PROJECT_NAME}-dbbackups
  • @entrypoint.sh comment out the related "waitfordbs task done" section

    • Note 1: It is expected to have the external database up running before running, So no need to wait for the databases
    • Note 2: Please check how the script for wait for databases could be improved at the end on the file
    # /usr/local/bin/invoke waitfordbs > /usr/src/geonode/invoke.log 2>&1
    # echo "waitfordbs task done"
  • Rebuild django docker service

    >_ docker-compose build

3. As for the external PostgreSQL database it is expected to have the following parameters:

  • database user with password for connection
  • database name for geonode django tables
  • database name for geonode data tables
  • exposed database IP address
  • exposed database port
  • Docker containers network IP address

4. Prepare The External PostgreSQL Database:

Skip this part if it is already prepared

  • create database user <username> with <your_strong_password>

        >_ sudo -u postgres createuser -P <username>
  • Create databases for geonode django tables with name geonode

        >_ sudo -u postgres createdb -O <username> geonode
  • Create databases for geonode django tables with name geonode_data

        >_ sudo -u postgres createdb -O <username> geonode_data
  • Use PostGIS extension for the created databases

    Replace <username> with your username

    >_ sudo -u postgres psql -d geonode -c 'CREATE EXTENSION postgis;'
    >_ sudo -u postgres psql -d geonode -c 'GRANT ALL ON geometry_columns TO PUBLIC;'
    >_ sudo -u postgres psql -d geonode -c 'GRANT ALL ON spatial_ref_sys TO PUBLIC;'
    >_ sudo -u postgres psql -d geonode -c 'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO <username>;'
    
    >_ sudo -u postgres psql -d geonode_data -c 'CREATE EXTENSION postgis;'
    >_ sudo -u postgres psql -d geonode_data -c 'GRANT ALL ON geometry_columns TO PUBLIC;'
    >_ sudo -u postgres psql -d geonode_data -c 'GRANT ALL ON spatial_ref_sys TO PUBLIC;'
    >_ sudo -u postgres psql -d geonode_data -c 'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO <username>;'
  • Scenario 1: PostgreSQL service with docker service on the same host machine

    • Get the geonode docker network IP address:
      >_ docker network inspect geonode_default | grep Subnet
      # similar output:
      #       "Subnet": "172.21.0.0/16",
  • Scenario 2: PostgreSQL is running on separate host machine:

    • Get the host machine IP address:
    >_ ifconfig
  • Now, Having the IP address, Add two rules for both databases at /etc/postgres/<postgres_version_number>/pg_hba.conf

    # Syntax 
    # host DATABASE        USER         ADDRESS             METHOD
    # Ex
    # host geonode_data    geonode_user 172.21.0.0/16      md5 
    host   geonode         <username>   <ip_address>/16     md5
    host   geonode_data    <username>   <ip_address>/16     md5        
    
  • Restart postgresql database service

    >_ sudo service postgresql restart
  • Allow GeoNode docker to connect to the external database:

    • At geonode project dir, edit .env file
    • Replace with your username, password, ip_address, port
    • Replace database names if changed than geonode & geonode_data
        POSTGRES_USER=<username>
        POSTGRES_PASSWORD=<password>
        GEONODE_DATABASE=geonode
        GEONODE_DATABASE_PASSWORD=geonode
        GEONODE_GEODATABASE=geonode_data
        GEONODE_GEODATABASE_PASSWORD=geonode_data
        DATABASE_URL=postgis://<username>:<password>@<ip_address>:<port>/geonode
        GEODATABASE_URL=postgis://<username>:<password>@<ip_address>:<port>/geonode_data
    
    • Start the docker containers

    Expected to see the migrations running again

        >_ docker-compose up -d
    • Done!

Improvement suggestion for wait-for-databases-script

  • The following .env configuration will allow the user to have an external database without disabling wait-for-databases check part
  • @.env file, it is suggested to be like this
    POSTGRES_USER=postgres
    POSTGRES_PASSWORD=postgres
    GEONODE_DATABASE=geonode
    GEONODE_DATABASE_PASSWORD=geonode
    GEONODE_GEODATABASE=geonode_data
    GEONODE_GEODATABASE_PASSWORD=geonode_data
    GEONODE_DATABASE_SCHEMA=public
    GEONODE_GEODATABASE_SCHEMA=public
    
    GEONODE_DATABASE_HOST=db
    GEONODE_DATABASE_PORT=5432
    DATABASE_URL=postgis://$POSTGRES_USER:$POSTGRES_PASSWORD@$GEONODE_DATABASE_HOST:$GEONODE_DATABASE_PORT/$GEONODE_DATABASE
    
    GEONODE_GEODATABASE_HOST=db
    GEONODE_GEODATABASE_PORT=5432
    GEODATABASE_URL=postgis://$POSTGRES_USER:$POSTGRES_PASSWORD@$GEONODE_GEODATABASE_HOST:$GEONODE_GEODATABASE_PORT/$GEONODE_GEODATABASE
    
    GEONODE_DB_CONN_MAX_AGE=0GEONODE_GEODATABASE_HOST
    GEONODE_DB_CONN_TOUT=5
    DEFAULT_BACKEND_DATASTORE=datastore
    BROKER_URL=amqp://guest:guest@rabbitmq:5672/
    ASYNC_SIGNALS=True
    
  • @wait-for-databases.sh file it could be like this
    #!/bin/bash
    
    set -e
    
    shift
    
    until PGPASSWORD=${GEONODE_DATABASE_PASSWORD} psql -h "$GEONODE_DATABASE_HOST" -p "$GEONODE_DATABASE_PORT" -U ${GEONODE_DATABASE} -d ${GEONODE_DATABASE} -P "pager=off" -c '\l'; do
    >&2 echo "${GEONODE_DATABASE} is unavailable - sleeping"
    sleep 1
    done
    
    until PGPASSWORD=${GEONODE_GEODATABASE_PASSWORD} psql -h "$GEONODE_GEODATABASE_HOST" -p "$port" -U ${GEONODE_GEODATABASE_PORT} -d ${GEONODE_GEODATABASE} -P "pager=off" -c '\l'; do
    >&2 echo "${GEONODE_GEODATABASE} is unavailable - sleeping"
    sleep 1
    done
    
    >&2 echo "GeoNode databases are up - executing command"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment