Pgadmin in MyBinder

I’ve started having a look at recipes for adding postgres to a Binderised repo, h/t others, and have got stuck (again) trying to see pgadmin4 via JupyterServerProxy. I can get the server running (at least, it starts on the port), but I get a time out trying to connect to the UI.

Repo is here: https://github.com/psychemedia/jupyter-postgres-demo/tree/server-proxy

Has anyone got pgadmin working via a proxy in MyBinder?

With a bit of editing of pgAdmin4.py to get it to log at DEBUG level to the console and starting it from a console I see that it sends 302 redirect to /browser when you first visit it at ../proxy/5050/. This request then ends up with a 404 because of the leading / in the redirect location.

If instead you navigate to .../proxy/5050/browser/ (with trailing slash) there is no 302 redirect and you get to see a bit of HTML produced by pgAdmin. However the JS doesn’t load because the paths all start with a / that make them absolute.

The missing puzzle piece is how to configure pgAdmin4 (a flask app) to understand that it is being served from a URL prefix. I can’t make that work. It is a general problem that I have with flask apps :-/

I’ve managed to get this running:

This was harder than I expected as it required a combination of options:

  • A WSGI server (Tried uwsgi but it didn’t work so switched to Gunicorn)
  • Set SCRIPT_NAME to indicate a subpath
  • Switch pgadmin to server mode. In desktop mode some javascript and static files didn’t get the prefix, in server mode it seems to work but requires a login (I’ve created a default).

If anyone can explain the logic for all this I’d love to hear it!

1 Like

Woah! This is pretty amazing. Both in terms of it working and how much work it was :wink: !

@betatim Thanks for the debug tutorial… I need to improve my skills in this area…

@manics Thanks for that huge effort.

Getting arbitrary services running in MyBinder is still quite a challenge I think, compared to linking containers using docker-compose, for example.

I wonder if it would be useful to have a complement to the Binder examples repo that hosts examples of recipes for how to include particular applications in a repo2docker built container?

Thinking more grandiosely, could repo2docker support a plugin / custom buildpack mechanism where someone could install additional applications from predefined recipes?

Or maybe a recipe for including a “custom buildpack” in a repo from another repo as a git submodule?

1 Like

Only apps that use relative links are (almost) guaranteed to work with proxying with minimal configuration. This includes Javascript, CSS, images and links to other pages in the app.

All other apps require built-in support for being proxied under a subpath, so that they know to include the prefix in any links they generate. Some apps can auto-detect this based on metadata supplied by the proxy.

This configuration is specific to each application so there’s no single set of instructions that will “just work”. It might be possible to write instructions for common frameworks, e.g. Django, Flask, and maybe other Python apps that support WSGI, but even then each app may have its own idiosyncrasies.

Docker-compose is a nice way to spin up multiple services, but if you want to proxy them all via a single container such as a front-end Nginx container you’d run into the same problems with configuring prefixes for each service.

jupyter-server-proxy allows configuration to be provided in a python package so this could be part of the solution for supporting repo2docker apps?

Okay, thanks… I think I need to learn more!

From the PR, I saw that you’d tried and then replaced uwsgi with gunicorn.

I’ve just been prompted to look at the official pgadmin Dockerfile, and that uses gunicorn too. (There’s an issue with the pgadmin query tool throwing an HTTP error), which someone else raised as an issue in their attempt at trying to Dockerise pgadmin, so I’m looking to the official working container for possible solution (the pgadmin Dockerfile listen domain is [::] rather than 127.0.0.1, and there’s also additional config for TLS/).)

I’m starting to think that looking to Dockerfiles of standalone applications may be a sensible strategy for trying to Binderise those applications?

I’d be happy for there to be more examples in the Binder Examples · GitHub organisation that demonstrate how to do things like this. If someone could make a minimal pgadmin example as a standalone repo we could add it. At this stage I’d err on the side of including too many examples in that organisation instead of trying to be selective. (One day it will become chaotic and require some kind of sorting/organising but that will be a good problem to have.)

2 Likes

We tried adding pgAdmin4 but proved tricky, so opted for pgweb instead. It’s a simpler solution but we love it.

1 Like

Ah, very nice… thanks for the tip off…

1 Like