joshuaflanagan / serverless-ruby-package

serverless plugin to package ruby gems
39 stars 11 forks source link

Postgres with ActiveRecord not working #28

Open akawalsky opened 3 years ago

akawalsky commented 3 years ago

I am trying to create a lambda that works with a rails project. This involve using the pg gem and the active_record gem.

Gemfile

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.2'

gem 'activerecord', '~> 6.0.3.4'
gem 'pg', '~> 1.2.3'
gem 'aws-sdk-ssm', '~> 1'

In order to use the pg gem, I had to extend the base lambci/lambda:build-ruby2.7 image in order for extensions to be installed correctly. Some of the packages installed are probably unnecessary, but shouldn't make a difference.

Dockerfile

FROM lambci/lambda:build-ruby2.7

RUN yum update -y && yum install -y \
    git-core \
    curl \
    zlib1g-dev \
    build-essential \
    libssl-dev \
    libreadline-dev \
    libyaml-dev \
    libsqlite3-dev \
    sqlite3 \
    libxml2-dev \
    libxslt1-dev \
    libcurl4-openssl-dev \
    python-software-properties \
    libffi-dev \
    postgresql-client-common \
    postgresql-client \
    libpq-dev \
    postgresql-devel

The extension files were not being picked up by my lambda, so I manually included them in lib borrowing from this script https://github.com/proton/lambda-ruby-pg/blob/main/deploy.bash .

I then include those files in my serverless.yml

package:
  include:
    - handlers.rb
    - lib/**

Finally, I create the ActiveRecord connection with

handlers.rb

load "vendor/bundle/bundler/setup.rb"
require 'json'
require 'pg'
require 'active_record'

def do_something(event:, context:)
  ActiveRecord::Base.establish_connection('HARDCODED_CONFIGURATION')

  { success: true }
end

Everything works expect the establish_connection call. I am getting

"Error loading the 'postgresql' Active Record adapter. Missing a gem it depends on? Could not find 'pg' (>= 0.18, < 2.0) among 301 total gem(s)\nChecked in 'GEM_PATH=/var/task/vendor/bundle/ruby/2.7.0:/opt/ruby/gems/2.7.0:/var/runtime', execute `gem env` for more information"

This error is being caused by this line https://github.com/rails/rails/blob/3de9669188b543192571932e5cb6f0d5a6ec1043/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L4

I confirmed this by manually commenting out that line in my /vendor/bundle before deploying and everything worked. I also have tried commenting out the establish_connection call and just calling PG.library_version, which works. I also tried just putting gem "pg", ">= 0.18", "< 2.0" directly in my code and got the same error result.

It seems like the GEM_PATH being used by this command does not use the same LOAD_PATHS variable that is populated by bundler in standalone mode.

I don't think this is necessarily a bug with this plugin, but any guidance would be greatly appreciated.

apsoto commented 3 years ago

I don't use PG with Lambda so I have no experience to help, but maybe try looking through the Lamby docs (https://lamby.custominktech.com/docs/database_options) or forums for some tips?

joshuaflanagan commented 3 years ago

I don't use PG, or Rails, with Lambda either. I don't think Rails is a great fit for Lambda, but if you want to go down that route, I would suggest using a container image https://docs.aws.amazon.com/lambda/latest/dg/images-create.html.

I think that will be a much better experience than trying to use the Serverless framework and this plugin.

NARKOZ commented 3 years ago

I had success with serverless-ruby-layer plugin. Check it out https://navarasu.github.io/serverless-ruby-layer/#/use_docker_with_yums

nvengal commented 3 years ago

You might also take a look at https://github.com/boltops-tools/jets for a rails-like serverless framework.