HOWTO Platform
Describes how to setup your own instance of the OGC API Testbed platform. As a real-world example, the OGC API Sandbox (Playground) instance is presented below step-by-step.
See also another example: a pygeoapi server developed by the EU JRC.
1. Ubuntu Server
Info:
- setup or acquire a Linux Ubuntu server, minimal Ubuntu 20.4 LTS
- can be a VM/VPS or bare metal server, even a local VirtualBox (with Vagrant) instance
- Sandbox specs: 4CPU, 16RAM, 100GB but also strongly depends on the services one needs to run
- root access via SSH required
- DNS: create A-record
apisandbox.geonovum.nl
for IP address109.237.219.249
- OPTIONAL: DNS: if you need docs (not for Sandbox) create CNAME and set in
git/docs/docs/CNAME
- copy your SSH public key to
/root/.ssh/authorized_keys
, e.g.scp ~/.ssh/id_rsa.pub root@apisandbox.geonovum.nl:.ssh/authorized_keys
- test login with SSH key:
ssh root@apisandbox.geonovum.nl
- upgrade server to latest:
apt-get update && apt-get -y upgrade
2. Generate GitHub Repo
Create a GitHub repository from the Template repo github.com/Geonovum/ogc-api-sandbox.
Creating a repository from a template is similar to forking a repository, but there are important differences:
- A new fork includes the entire commit history of the parent repository, while a repository created from a template starts with a single commit.
- Commits to a fork don't appear in your contributions graph, while commits to a repository created from a template do appear in your contribution graph.
- A fork can be a temporary way to contribute code to an existing project, while creating a repository from a template starts a new project quickly.
Steps (see also here:
- login on GitHub
- go to github.com/Geonovum/ogc-api-testbed
- above file list press green button "Use this template"
- follow the steps indicated, if you want to serve docs on a separate domain indicate "Include all branches"
3. Prepare Local System
On your local system:
Install Ansible:
- have Python 3 (3.7 or better) installed
- OPTIONAL (but recommended) create a Python Virtualenv (for Ansible)
- install Ansible with
pip install ansible
2.9.* or higher - test:
ansible --version
- shows ansible 2.9.19 ... - test:
ansible-vault --version
shows ansible-vault 2.9.19 ...
More on Ansible below.
Install Git
client.
4. Clone New GitHub Repo
git clone https://github.com/Geonovum/ogc-api-sandbox.git
We will call the root dir of the cloned git repo on your system just git/
from here.
5. Setup Ansible
Most of the configuration that is specific to your new server
is stored under git/ansible/hosts
(Ansible inventories)
and git/ansible/vars
(variables and SSH keys).
Most files are encrypted with Ansible Vault
. You will need to
create your own (encrypted) version of these encrypted files.
For many files an example file is given.
Ansible Modules
Called "Roles" these are third-party Ansible components that help with specific tasks. Install these as follows:
cd git/ansible
ansible-galaxy install --roles-path ./roles -r requirements.yml
Ansible Hosts
The hostname is crucial to services functioning. Two steps:
- set content of
git/ansible/hosts/prod.yml
(Inventory) to
ogcapi:
hosts:
apisandbox:
ansible_port: 22
ansible_host: apisandbox.geonovum.nl
ansible_user: root
- set content of
git/services/env.sh
to:
#!/bin/bash
# Sets global env vars based on host-name
# Needed for various host-dependent configs, especiallly Traefik SSL-certs.
# Export and Defaults
# Assume a local deployment
export DEPLOY_ENV="local"
export TRAEFIK_SSL_ENDPOINT=
export TRAEFIK_SSL_DOMAIN="apisandbox.geonovum.nl"
export TRAEFIK_SSL_CERT_RESOLVER=
export TRAEFIK_USE_TLS="false"
export HOST_UID=$(id -u)
export HOST_GID=$(id -g)
export HOST_UID_GID="${HOST_UID}:${HOST_GID}"
# Set host-dependent vars
case "${HOSTNAME}" in
"apisandbox.geonovum.nl")
DEPLOY_ENV="prod"
;;
"apisandbox")
DEPLOY_ENV="prod"
;;
*)
echo "Default Local Host ${HOSTNAME}"
esac
if [[ ${DEPLOY_ENV} = "prod" ]]
then
source /etc/environment
TRAEFIK_SSL_ENDPOINT="https"
TRAEFIK_SSL_CERT_RESOLVER="le"
TRAEFIK_USE_TLS="true"
fi
So DEPLOY_ENV=prod
here is to discern with a deployment on localhost
(DEPLOY_ENV=local
, where .e.g. no https/SSL is used).
Create SSH Keys
These are used to invoke actions on the server both from GitHub Actions (via GitHub Sercrets) and from your local Ansible setup. Plus a set of authorized_keys for the admin SSH user.
- cd
git/ansible/vars
- create new SSH keypair (no password):
ssh-keygen -t rsa -q -N "" -f gh-key.rsa
Create authorized_keys
Create new git/ansible/vars/authorized_keys
with your public key and for others you want to give access to the admin SSH account,
plus gh-key.rsa.pub
.
cat gh-key.rsa.pub > authorized_keys
cat ~/.ssh/id.rsa.pub >> authorized_keys
cat id.rsa.pub.of.joe >> authorized_keys # etc
Adapt vars.yml
Create new git/ansible/vars/vars.yml
from example vars.example.yml
in that dir.
The first part of vars.yml
contains generix, less-secret, values.
Use variables where possible. Format is Python-Jinja2 template-like:
my_ssh_pubkey_file: ~/.ssh/id_rsa.pub
my_email: my@email.nl
my_admin_user: the_admin_username
my_admin_home: "/home/{{ my_admin_user }}"
my_git_home: "{{ my_admin_home }}/git"
my_github_repo: https://github.com/Geonovum/ogc-api-sandbox.git
var_dir: /var/ogcapi
logs_dir: "{{ var_dir }}/log"
services_home: "{{ my_git_home }}/services"
platform_home: "{{ my_git_home }}/platform"
pip_install_packages:
- name: docker
timezone: Europe/Amsterdam
ufw_open_ports: ['22', '80', '443', '5432']
The second part deals with more secret values, like usernames and passwords for services.
For most services indicated below with comment after #
. GHC_
denotes GeoHealthCheck (GHC) vars.
If you don't use GHC you can skip those.
etc_environment:
PG_DB: the_db # PostGIS service
PG_USER: the_user # PostGIS service
PG_PASSWORD: the_pw # PostGIS service
PGADMIN_EMAIL: the_user@the_user.nl # PGadmin service
PGADMIN_PASSWORD: the_pw # PGadmin service
GHC_SQLALCHEMY_DATABASE_URI: postgresql://the_user:the_pw@the_db:5432/the_db # PGadmin service
GHC_ADMIN_USER_NAME: the_user
GHC_ADMIN_USER_PASSWORD: the_pw
GHC_ADMIN_USER_EMAIL: the_user@the_user.nl
GHC_NOTIFICATIONS_EMAIL: the_user@the_user.com
GHC_SMTP_EMAIL: the_user@the_user.com
GHC_SMTP_SERVER: smtp.gmail.com
GHC_SMTP_PORT: 587
GHC_SMTP_TLS: True
GHC_SMTP_SSL: False
GHC_SMTP_USERNAME: the_user@the_user.com
GHC_SMTP_PASSWORD: the_pw
Create Ansible Vault Password
- global replace
~/.ssh/ansible-vault/ogc-api-testbed.txt
with~/.ssh/ansible-vault/ogc-api-sandbox.txt
ingit/ansible/README.md
- create strong password
- store in
~/.ssh/ansible-vault/ogc-api-sandbox.txt
for convenience
Set GitHub Secrets
Three secrets need to be set:
Go to GH repo Settings|Secrets and create these three secrets
- ANSIBLE_INVENTORY_PROD - with value from
git/ansible/hosts/prod.yml
- ANSIBLE_SSH_PRIVATE_KEY - with value from
git/ansible/vars/gh-key.rsa
- ANSIBLE_VAULT_PASSWORD - value from
~/.ssh/ansible-vault/ogc-api-sandbox.txt
Encrypt Ansible Files
VERY IMPORTANT. UNENCRYPTED FILES SHOULD NEVER BE CHECKED IN!!!
Using ansible-vault
with password encrypt these:
ansible-vault encrypt --vault-password-file ~/.ssh/ansible-vault/ogc-api-sandbox.txt vars.yml
ansible-vault encrypt --vault-password-file ~/.ssh/ansible-vault/ogc-api-sandbox.txt gh-key.rsa
ansible-vault encrypt --vault-password-file ~/.ssh/ansible-vault/ogc-api-sandbox.txt gh-key.rsa.pub
ansible-vault encrypt --vault-password-file ~/.ssh/ansible-vault/ogc-api-sandbox.txt authorized_keys
Globally Replace apitestbed.geonovum.nl
Under git/services
replace all occurrences of apitestbed.geonovum.nl
with apisandbox.geonovum.nl
Disable GitHub Workflows
We do not want that workflows take effect immediately. So disable them temporary by renaming the dir.
git mv workflows workflows.not
git add .
git commit -m "disable workflows"
git push
6 Prune Repo Tree for Unneeded Services
At this step you may want to delete services you don't need:
rm -rf git/docs
. Documentation is already maintained and available via https://apitestdocs.geonovum.nl/- for each service you want to delete, delete these 3 resources, e.g. for service
xyz
rm -rf git/services/xyz
rm git/.github/workflows/deploy.xyz.yml
- in
git/ansible/deploy.yml
delete the three Ansibletask
lines withxyz
name and tag.
7 Bootstrap/provision Server
Moment of truth! Bootstrap (provision the server) in single playbook.
ansible-playbook -v --vault-password-file ~/.ssh/ansible-vault/ogc-api-sandbox.txt bootstrap.yml -i hosts/prod.yml
If all goes well, this output should be shown at end:
PLAY RECAP ***********************************************************************************************************
apisandbox : ok=58 changed=22 unreachable=0 failed=0 skipped=8 rescued=0 ignored=0
Observe output for errors (better is to save output in file via .. > bootstrap.log 2>&1
).
In cases of errors and after fixes, simply rerun the above Playbook.
Site should be running at: https://apisandbox.geonovum.nl Check with portainer https://apisandbox.geonovum.nl/portainer/.
8 Resolve Issues
These are typical issues found and resolved:
/home/oadmin/git
is owned by root, change tooadmin
- delete (or change) CNAME
git/docs/docs
- permissions in services/qgis/data , make datadir writeable for all:
chmod 777 services/qgis/data
9. Enable GitHub Workflows
Enable by renaming:
git mv workflows.not workflows
git add .
git commit -m "enable workflows"
git push