efi-mk / serverless-django-demo

A demo serverless app showing integration between django and the serverless framework
53 stars 28 forks source link

Internal server error #1

Open ptrhck opened 5 years ago

ptrhck commented 5 years ago

I just tried your instructions in order to deploy a Django GraphQL API to AWS Lambda, which I used to deploy with Zappa. However, with serverless and your steps it returns {"message": "Internal server error"} when hitting the API Gateway. If I do sls invokde -f app --log, it returns: Task timed out after 6.01 seconds.

It is not hosted in a VPC, neither did I change anything major in the serverless.yml file (basically only zip:true as the project uses numpy, pandas,...). Increasing timeout does not help, which I did not expect as it should simply display the graphiql UI.

Any ideas?

efimk-lu commented 5 years ago

What do you see under cloudwatch ?

ptrhck commented 5 years ago

 19:27:42 START RequestId: 50172730-f1b1-11e8-a383-9772977811b9 Version: $LATEST  19:27:48 END RequestId: 50172730-f1b1-11e8-a383-9772977811b9  19:27:48 REPORT RequestId: 50172730-f1b1-11e8-a383-9772977811b9 Duration: 6006.14 ms Billed Duration: 6000 ms Memory Size: 1024 MB Max Memory Used: 600 MB  19:27:48 2018-11-26T19:27:48.280Z 50172730-f1b1-11e8-a383-9772977811b9 Task timed out after 6.01 seconds

efimk-lu commented 5 years ago

Do you have any db configuration ? Share your settings.py

ptrhck commented 5 years ago
"""
Django settings for api project.

Generated by 'django-admin startproject' using Django 2.0.7.

For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""
import logging
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
from logging import getLogger
from sys import stdout

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '...'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['127.0.0.1', '....execute-api.eu-central-1.amazonaws.com']

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'graphene_django',
    'api.functions',
    'zappa_django_utils',
    'corsheaders'
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'whitenoise.middleware.WhiteNoiseMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'graphql_jwt.middleware.JSONWebTokenMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'api.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'api.wsgi.application'

# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        '': {
            'handlers': ['console'],
            'level': 'INFO',
        },
    },
}

# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

AUTHENTICATION_BACKENDS = [
    'graphql_jwt.backends.JSONWebTokenBackend',
    'django.contrib.auth.backends.ModelBackend',
]

GRAPHENE = {
    'SCHEMA': 'api.schema.schema',
    'MIDDLEWARE': [
        'graphql_jwt.middleware.JSONWebTokenMiddleware',
    ],
}

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/

STATIC_URL = '/dev/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
WHITENOISE_STATIC_PREFIX = '/static/'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'

SQLITE_BUCKET = os.environ.get('bucket name', "service name serverless.yml")
try:
    from .local_settings import *
except ImportError:
    logging.error("Unable to find local_settings.py")

# Are we running in Lambda environment ?
# See https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html#lambda-environment-variables
IS_OFFLINE = os.environ.get('LAMBDA_TASK_ROOT') is None

# I hate different configuration for local and cloud, but this is what we have now.
if IS_OFFLINE:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
else:
    DATABASES = {
        'default': {
            'ENGINE': 'zappa_django_utils.db.backends.s3sqlite',
            'NAME': 'db.sqlite3',
            'BUCKET': SQLITE_BUCKET
        }
    }
efimk-lu commented 5 years ago

Add debug logs. Follow https://docs.djangoproject.com/en/2.1/topics/logging/

Specifically django and attach the cloudwatch logs

ptrhck commented 5 years ago

I have adjusted the logging settings to this:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': 'DEBUG',
        },
    },
}

That is what I get now:


09:16:43
START RequestId: 1f3d68b7-f225-11e8-a767-15d62415a88d Version: $LATEST

09:16:49
END RequestId: 1f3d68b7-f225-11e8-a767-15d62415a88d

09:16:49
REPORT RequestId: 1f3d68b7-f225-11e8-a767-15d62415a88d  Duration: 6003.91 ms    Billed Duration: 6000 ms Memory Size: 1024 MB   Max Memory Used: 319 MB

09:16:49
2018-11-27T09:16:49.945Z 1f3d68b7-f225-11e8-a767-15d62415a88d Task timed out after 6.00 seconds

09:17:00
[ERROR] 2018-11-27T09:17:00.165Z    Unable to find local_settings.py

So nothing special I guess? Could this be related to something graphql specific or django cors?

In this regard, I have only found this https://github.com/serverless/serverless-graphql/issues/94

However, changing the serverless.yml to this does not help:

functions:
  app:
    handler: wsgi.handler
    events:
      - http:
          path: graphql
          method: get
          cors: true
          integration: LAMBDA
      - http:
          path: graphql
          method: post
          cors: true
          integration: LAMBDA
efimk-lu commented 5 years ago

Start by eliminating stuff, remove the graphql bindings and see if it works. Create the simplest project.

On Tue, Nov 27, 2018 at 11:59 AM ptrhck notifications@github.com wrote:

I have adjusted the logging settings to this:

LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console': { 'class': 'logging.StreamHandler', }, }, 'loggers': {

'django': { 'handlers': ['console'], 'level': 'DEBUG', }, }, }

That is what I get now:  09:16:43 START RequestId: 1f3d68b7-f225-11e8-a767-15d62415a88d Version: $LATEST  09:16:49 END RequestId: 1f3d68b7-f225-11e8-a767-15d62415a88d  09:16:49 REPORT RequestId: 1f3d68b7-f225-11e8-a767-15d62415a88d Duration: 6003.91 ms Billed Duration: 6000 ms Memory Size: 1024 MB Max Memory Used: 319 MB  09:16:49 2018-11-27T09:16:49.945Z 1f3d68b7-f225-11e8-a767-15d62415a88d Task timed out after 6.00 seconds  09:17:00 [ERROR] 2018-11-27T09:17:00.165Z Unable to find local_settings.py

So nothing special I guess? Could this be related to something graphql specific or django cors?

In this regard, I have only found this serverless/serverless-graphql#94 https://github.com/serverless/serverless-graphql/issues/94

However, changing the serverless.yml to this does not help:

functions: app: handler: wsgi.handler events:

  • http: path: graphql method: get cors: true integration: LAMBDA
  • http: path: graphql method: post cors: true integration: LAMBDA

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/efi-mk/serverless-django-demo/issues/1#issuecomment-441998342, or mute the thread https://github.com/notifications/unsubscribe-auth/ApjVzRfyRPgwdaWvV4-Sr8a6IK7HRtALks5uzQzngaJpZM4YzUKH .

ptrhck commented 5 years ago

That is what I did now, especially setting up a new pipfile. It works so far that I get to the graphiql and admin interface. But still, if I do a graphql query I get an internal server error with the timeout. It works locally.

efimk-lu commented 5 years ago

Does graphql admin have any logs? It looks like a configuration problem here, I'm not proficient enough with graphql toolset to help you, sorry.