OpenStreetMap logo OpenStreetMap

So here are my experiences in installing Panoramax instance OSM-HR. I’ve made this from notes taken at a time, so hopefully I did not miss too much. Let me know if I did.

There are several ways to install, and I’ve decided to go with docker compose, and with regular OSM Oauth2 login.

We bumped into few issues during the deployment, but we reported them at appropriate repos, and they were fixed so nobody should be bothered by them anymore. Please do the same if you bump into some of your own!

So mostly I followed official instructions here: https://docs.panoramax.fr/backend/install/tutorials/running_docker_osm_auth/

with some preparation first as outlined in: https://forum.geocommuns.fr/t/deploying-a-panoramax-instance-the-pre-flight-check-list/1892

and info about storage needs: https://forum.geocommuns.fr/t/storage-needs-for-a-panoramax-instance/3205

Hardware

First actual hard step was getting the appropriate hardware and place to host it; see that pre-flight check list for other things like checking the law etc.

http://openit.hr/ kindly donated the hardware, and https://carnet.hr/ the place and Internet to host it. Much thanks to them!

We got quite a beast: 4U Super-Micro cse-847 server with 2 * Xeon E5-2680v2 (40 CPU threads @ 2.80GHz), 256 GB DDR3 RAM, 2x1TB SATA SSD, and 34x3TB SAS HDD (54 TB of usable HDD space after RAID6 partitioning), Nvidia Tesla P4

You can get with (much) lower specs, depending on your needs. But we have a good-hearted sponsor so yay!

Creating Oauth2 app

So firstly, I went to osm.org/, logged in, clicked on menu / “My account” / “Oauth 2 Applications” / “Register new application” and created Oauth2 application as described on: https://docs.panoramax.fr/backend/install/tutorials/running_docker_osm_auth/#creating-our-osm-oauth2-client

“Name” was set to Panoramax HR and “Redirect URIs” to https://panoramax.osm-hr.org/api/auth/redirect

Make sure to write down “Client ID” and “Client Secret”, as you’ll need them later and this is only time you’ll be able to see them.

Preparing the host OS

We use Debian. Originally at a time we tried going with Debian Bookworm GNU/Linux, but that had complained about Docker Compose configs, so we upgraded to Trixie. As it is Debian Stable at this moment, that is what I’d recommend anyway nowadays.

We also decided to use multiple HW RAID6 pools, LVM and EXT4, due to familiarity and stability and experience in recovering them (hopefully this won’t jinx it). Some people go with XFS instead of EXT4, and others swear by ZFS and replace both LVM and EXT4 with it – but I’ve never got too familiar with it (due to the way back in bad old days there were licensing issues with it. Never checked if that was resolved. Ha). And we decided on Docker Compose in order to hopefully have easy upgrades and keep host OS to pure Debian “main” packages.

So, we installed prerequisite packages, created a logical volume and formatted it.

apt install docker.io docker-compose docker-cli curl nginx certbot python3-certbot-nginx

lvcreate --name panoramax-pics --size 40T shrikehdd
mkfs.ext4 -T largefile /dev/shrikehdd/panoramax-pics
mkdir /osm/panoramax/storage
echo "/dev/shrikehdd/panoramax-pics   /osm/panoramax/storage    ext4    defaults        0       3" >> /etc/fstab
mount /osm/panoramax/storage
mkdir /osm/panoramax/storage/pics
chmod 1777 /osm/panoramax/storage/pics

Note that our Debian root directory (and thus, where docker SQL database will live) is on SSD.

Getting and configuring Panoramax

We fetch it from git and copied template config file:

git clone https://gitlab.com/panoramax/server/api.git panoramax-api
# git checkout develop # only if you like to live on the edge -- we had to at a time, as we were finding some bugs on the way
cd panoramax-api/docker/full-osm-auth/
cp -ai env.example .env

and then we edited that .env to configure for our instance:

INSTANCE_NAME=OSM-HR
FLASK_SESSION_COOKIE_DOMAIN=panoramax.osm-hr.org
PICTURES_DIR=/osm/panoramax/storage/pics/
INFRA_NB_PROXIES=2
  • we also set the long (different) passwords for FLASK_SECRET_KEY and PG_PASSWORD. You can use output of python3 -c 'import secrets; print(secrets.token_hex()) to generate appropriately long passwords.
  • and we set OAUTH_CLIENT_ID and OAUTH_CLIENT_SECRET to those values we’ve written down when when we created Oauth2 app in previous steps.

Also, we needed to edit docker-compose.yml from that panoramax-api/docker/full-osm-auth/ directory and update API_SUMMARY according to docs at https://panoramax.ign.fr/api/configuration We did this:

   API_SUMMARY: >-
     {
      "color": "#ff0000",
      "description": {"en": "OpenStreetMap Croatia", "hr": "OpenStreetMap Hrvatska"},
      "logo": "https://wiki.openstreetmap.org/w/images/6/6d/Logo_Croatia.svg",
      "email": "panoramax@osm-hr.org",
      "name": {"en": "${INSTANCE_NAME:-A Panoramax instance}", "hr": "${INSTANCE_NAME:-Panoramax instanca}"},
      "geo_coverage": {"en": "Croatia and ex-YU region", "hr": "Hrvatska i regija"}
     }

Starting up Panoramax

We went to panoramax-api/docker/full-osm-auth/ directory and started Docker Compose with docker compose --project-name panoramax-hr up --pull=always -d

That should pull up everything newest and start Panoramax in background.

You should verify here if it works by calling curl --fail http://localhost:8080/api - it should return some JSON.

Publishing it to the world

We’ve picked nginx. Since panoramax.osm-hr.org was setup in DNS to point to our server, we created /etc/nginx/sites-available/panoramax with following content:

  server {
        listen 80;
        listen [::]:80;

        server_name panoramax.osm-hr.org;

        # Limit the files that can be sent to 100M
        client_max_body_size  100M;

        # buffer size when receiving big files. 6M should be enough for most pictures, but feel free to tune this value depending of your needs.
        client_body_buffer_size 6M;

        client_body_timeout     120s;
        send_timeout            60s;
        proxy_read_timeout      120s;
        proxy_send_timeout      120s;

        location / {
            proxy_pass http://localhost:8080;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Host $host;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
  }

And then enabled it and started it:

ln -s /etc/nginx/sites-available/panoramax /etc/nginx/sites-enabled/
service nginx reload

(note we don’t use systemd as I deem it a horrible idea; but service(8) on Debian should run regardless if you’re using SysVinit or Systemd)

Then we fetch free Let’s Encrypt TLS certificates by running certbot --nginx and choosing out panoramax.osm-hr.org server from the list.

That makes people able to open https://panoramax.osm-hr.org/ and login and look and upload there!

Geo-limiting the uploads

While the hardware we got was very powerful, we knew it wasn’t nowhere near infinite, so we couldn’t host the whole world. And cameras get better (and more Mpx) with time, and disk usage only rises.

Still, it felt a shame to limit it only to Croatia (where the server and sponsors are from), so we decided to allow all countries from ex-Yugoslavia to use it. (not only we have great mapper friends there, but laws and language are similar, so there is also that).

To restrict what areas are allowed, we first had to get .geojson of the area (see https://docs.panoramax.fr/backend/install/deep_dive/excluded_areas for the info) and save it as exyu.geojson

Then we used docker compose -p panoramax-hr exec api /home/geovisio/.local/bin/panoramax_backend default-account-tokens get to get a Bearer token (looong string of letters and numbers and few dots)

And then we uploaded that config:

  curl -X PUT "https://panoramax.osm-hr.org/api/configuration/excluded_areas?invert=true"\
       -H "Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.the.rest.ofthe.bearer.token.xxxxxxxx" \
       -H "Content-Type: application/geo+json"     --data-binary "@exyu.geojson"

(of course you replace bearer token with that string you got earlier)

Testing

Then there was testing. Obviously, easiest was to use our new web at https://panoramax.osm-hr.org/ to try to upload pictures from both allowed and disallowed regions, to see if geo-limiting was working.

Then we tried some sequences uploading from CLI (sudo apt install pipx; pipx install panormax_cli), using the mobile apps (Vespucci custom server) etc.

We first had test instance on different hardware that we nuked later and setup production, but that is not needed. (If you do something similar, make sure to nuke your panoramax-cli config cache, or it will behave strangely).

Announcing to the world

Well, when you’re happy that everything is working great, you want to make your instance usable by others too!

Appendix A: managing the Docker Compose

I’m not much of a docker guy, but here are some commands which seem to work for me and might come handy to you:

# startup in the future with fetching new versions if needed:
docker compose -p panoramax-hr up --pull=always -d
# shutdown with:
docker compose -p panoramax-hr down
# check logs:
docker compose -p panoramax-hr logs -f --tail 1000
# process list:
docker compose -p panoramax-hr ps
# DESTROY everything docker-related -- in case you mucked it up completely and want to start from scratch:
docker compose -p panoramax-hr down --volumes --rmi all --remove-orphans
docker system prune -a --volumes
# database access
docker compose -p panoramax-hr exec -it db psql postgres://gvs:thatlongPostgresqlPassword@db/geovisio

TODO

  • try to setup our own blurring server (it was in initial plan, but there were issues with that blurring docker container, and we had deadlines to mean - SotM-HR 2026; where I presented Panoramax)
  • backups (Database. And pictures. And hardware to store ‘em, uhhhh)
  • move Croatian (and other ex-YU) pictures off the OSM-FR server to our OSM-HR, to help reduce their overload (see https://c.osm.org/t/osm-fr-panoramax-server-only-for-testing-if-outside-of-france/143428/2) once stable UUIDs are implemented
  • encourage more users to setup their Panoramax instances – this can only work for whole world if there are a lot of us!
  • admin user over the web (not just CLI Bearer - see https://docs.panoramax.fr/backend/install/cli/#set-the-role-of-an-account )
  • figuring out how to check out blur / unblur requests and other moderation / flow checking
  • look into few warnings / errors in the logs (and file some more issues)

Discussion

Leave a comment

Log in to leave a comment