Search code examples
pythondjangogoogle-app-enginedockermanaged-vm

Django on App Engine Managed VM


I have a minimal Django project that I am trying to deploy onto Google App Engine Managed VMs. I'm having a bit of trouble understanding exactly what is going on and what is serving what. I have an app.yaml file that looks like this:

runtime: custom
vm: true
entrypoint: custom
api_version: 1

manual_scaling:
  instances: 1

handlers:
- url: /static
  static_dir: static

- url: /.*
  script: DjangoVM.wsgi.application

And a dockerfile that looks like this:

FROM gcr.io/google_appengine/python
RUN apt-get update
RUN apt-get -y install python-numpy python-scipy
ADD requirements.txt /app/requirements.txt
RUN pip install -r /app/requirements.txt
ADD . /app
CMD gunicorn DjangoVM.wsgi

My requirements.txt looks like this:

Django==1.8.5
gunicorn==19.3.0
scikit-learn==0.16.1

The site deploys okay, but my static files aren't showing up. So on a sandboxed app engine project the handlers in the app.yaml take care of serving my static content. Do I have to configure an nginx server or similar server in my dockerfile to serve static content?

To help me understand this, if I didn't have gunicorn serving my application, does App Engine not serve it by default using the handlers? i.e. What would happen if I didn't have CMD gunicorn DjangoVM.wsgi? Does a custom runtime mean that app engine will not serve my application by default and I have to specify a particular WSGI server? The documentation is not very thorough for Managed VMs yet. Sorry if the questions seem a bit confusing, but it reflects my current confusion on the subject as well. Thanks for any help!


Solution

  • It looks like you've confused two things here.

    There are two ways of deploying a managed vm: using a standard runtime, in this case Python, and using a custom runtime.

    The standard runtime is basically an App Engine app; you define your routes in app.yaml as usual. The runtime value should be "python27". However, you don't need a Dockerfile, and so it wouldn't include nginx or gunicorn; the routes are served by the App Engine runtime.

    A custom runtime is defined by giving a runtime value of "custom". This is a completely custom app, defined by a Dockerfile. You don't declare routes in app.yaml, and they need to be served by properly-configured nginx/gunicorn within your container.