Docker-composing bokeh + nginx: useful approach?

Hello All,
First time poster here, thanks in advance! (This is probably the type of question which would be flagged on SO as “opinion based,” so I hope I’ve found the right place to ask; and if not, please let me know!)

I’m new to devops, and currently exploring ways to dockerize Bokeh apps with Nginx for deployment to DigitalOcean droplets. By combining the basic Nginx example from the Bokeh docs, and an adaptation of this testdriven.io tutorial, I now have a container which runs as expected. I am considering publishing this as a Template repo on Github, because it seems like a straightforward, functional, and easily accessible approach to my untrained eye. But before I do, I was hoping those with more experience might weigh in: could something like this be useful to others? am I overlooking major flaws? is this topic already covered somewhere that I haven’t found? etc.

The basic structure of this project is as follows:

.
├── .env.dev
├── .env.prod
├── docker-compose.dev.yml
├── docker-compose.prod.yml
└── services
    ├── nginx
    │   ├── Dockerfile.prod
    │   └── nginx.conf
    └── web
        ├── Dockerfile.dev
        ├── Dockerfile.prod
        └── bokeh_app.py

Starting from the top, we have two .env files. Currently, their main purpose is to declare IP addresses for the development (local) and production (remote) machines, respectively.

Next, we have two docker-compose files. The development file builds the services/web directory only, so it can be used to check that all dependencies for the bokeh app are building as expected before introducing Nginx.

The production docker-compose builds a multi-service container which puts the Bokeh server behind the Nginx reverse proxy. This requires only a minor tweak to the .conf example provided in the Bokeh docs. Specifically, adding an upstream block as such:

upstream docker_machine {
    server web:5100;
}

server {
    listen 80 default_server;
    server_name _;

    access_log  /tmp/bokeh.access.log;
    error_log   /tmp/bokeh.error.log debug;

    location / {
        proxy_pass http://docker_machine;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host:$server_port;
        proxy_buffering off;
    }

}

Here I declare the name docker_machine in upstream because I am using Docker Machine to setup the virtual hosts (both local development and remote production).

There’s obviously a bit more too it, as I haven’t gone into what precisely is in the docker-compose and Dockerfile files, among other things. My intention here is not obfuscation (happy to share!) but rather to simplify this first presentation to ask a more general question. Namely:

What do you think about this general approach? My thought is a template of this general type might be useful to others who want to deploy bokeh apps in a reproducible manner, but don’t know much about devops. (e.g.: me, especially about 3 weeks ago).

But I am also new to this and may be overlooking flaws in this approach. Any and all reflections much appreciated!

Best,
Charles