moonbase_alpha 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 199aa19a27e389795884b46af93cdcb99c0ec72acf1c6b422b9a6e09fc750974
4
+ data.tar.gz: 9a33751590d6eb5868480545ef1526ae584b38852331eeadbd6a1a8885d43a3f
5
+ SHA512:
6
+ metadata.gz: 71ad7c41ecf34069aa854f71a42421854237cfc888ab0b37bdf3192e02afd5d8435c7c968295ead9ef5e589c1ef87e9580b829f5438b978d81b4e1d5f1be64f7
7
+ data.tar.gz: ec59d43e90afeb1eff77a8e9249bc8fea78046b0acc91a7c4f942ff9f5a668a894c4943943f5f19b4e2c33e9c9266013ada4f68dfa165339e37c34218c9e11c1
@@ -0,0 +1,72 @@
1
+ # MoonbaseAlpha
2
+
3
+ Moonbase Alpha rolls up everything you need to build a Rails app into a docker image ready to deploy on AWS Lambda. It is based heavily on (and uses) [Lamby](http://lamby.custominktech.com), which requires even fewer steps to launch a project, but unlike Lamby, Moonbase Alpha does not use any of AWS' SAM tooling. Moonbase Alpha is ideal for cases where you want more control over orchestration or to integrate with other tools.
4
+
5
+ Using Moonbase Alpha, a blank rails app builds into a ~120MB docker image, and the final image is constructed in stages to minimize the build tools that leak into the production environment.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'moonbase_alpha'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install moonbase_alpha
22
+
23
+ Then use the generator to create the configuration files and `app.rb` entrypoint:
24
+
25
+ $ bin/rails g moonbase
26
+
27
+ ## Usage
28
+
29
+ You must set at least one value in `moonbase_alpha.yml` prior to building your project, the docker repository, such as:
30
+
31
+ # Repository for the build. A build number will be set as the version
32
+ repository: 134567895209.dkr.ecr.us-west-2.amazonaws.com/dockertest
33
+
34
+ You can control which Alpine Linux packages are available at build time (both gems and assets) and at run time. The defaults should be sufficient to build a basic Rails app.
35
+
36
+ To build an image, run `bin/rails moonbase_alpha:build`. Moonbase Alpha includes rake tasks that output the last build tag and the full repository name. To push the current image, for example, invoke:
37
+
38
+ $ docker push `bin/rails moonbase_alpha:latest_image`
39
+ The push refers to repository [134567895209.dkr.ecr.us-west-2.amazonaws.com/dockertest]
40
+ 5d6180898fe9: Pushed
41
+ 9d6fac557487: Pushed
42
+ 4b60b0d829a4: Pushed
43
+ ae7119e06cea: Pushed
44
+ 84cbece2f061: Pushed
45
+ 745332470db1: Pushed
46
+ 93a2bfafa84f: Pushed
47
+ 54f362ba164c: Pushed
48
+ c4b1ff92c516: Pushed
49
+ 446d8e2016ac: Pushed
50
+ 50644c29ef5a: Pushed
51
+ build-2021-01-30-12-22-22: digest: sha256:41c633b81b41d107fdc15740d1e68e3f8cfcfbf4dfb8d54428fe07e748427f42 size: 2618
52
+
53
+
54
+ ## Development
55
+
56
+ This is a relatively simple project I put together mostly to accelerate my own workflows. It is missing some functionality and patches are welcome. The following items are outstanding:
57
+
58
+ * Setup automated testing
59
+ * Definitively handle asset compilation (more or less stubbed out right now because my use case is as an API project only)
60
+
61
+ ## Contributing
62
+
63
+ Bug reports and pull requests are welcome on GitHub at https://github.com/loganb/moonbase_alpha. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/loganb/moonbase_alpha/blob/master/CODE_OF_CONDUCT.md).
64
+
65
+
66
+ ## License
67
+
68
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
69
+
70
+ ## Code of Conduct
71
+
72
+ Everyone interacting in the MoonbaseAlpha project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/loganb/moonbase_alpha/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,31 @@
1
+
2
+ class MoonbaseGenerator < Rails::Generators::Base
3
+ desc "Install basic moonbase files"
4
+ def add_configuration
5
+ create_file "config/moonbase_alpha.yml", <<-EOF
6
+ # This configuration is technically specified on a per-environment basis, but
7
+ # moonbase doesn't currently use that
8
+ shared:
9
+ # Repository for the build. A build number will be set as the version
10
+ repository:
11
+ # These packages will be available only while installing gems and precompiling assets
12
+ build_packages:
13
+ - tzdata
14
+ - postgresql-dev
15
+ - sqlite-dev
16
+ # These pckages will be available only at runtime in the final build image
17
+ run_packages:
18
+ - postgresql-libs
19
+ - tzdata
20
+ - sqlite-libs
21
+ # If true, moonbase will run `rake assets:precompile` (not suitable for API projects)
22
+ compile_assets: false
23
+ EOF
24
+
25
+ environment do
26
+ "config.moonbase_alpha = config_for(:moonbase_alpha)"
27
+ end
28
+
29
+ create_file "app.rb", File.read(File.expand_path(__dir__ + "/../../../templates/app.rb"))
30
+ end
31
+ end
@@ -0,0 +1,8 @@
1
+ require "moonbase_alpha/version"
2
+
3
+ require 'moonbase_alpha/railtie' if defined? ::Rails::Railtie
4
+
5
+ module MoonbaseAlpha
6
+ class Error < StandardError; end
7
+ # Your code goes here...
8
+ end
@@ -0,0 +1,10 @@
1
+ require 'rails'
2
+
3
+ class MoonbaseAlpha::Railtie < Rails::Railtie
4
+ railtie_name :moonbase_alpha
5
+
6
+ rake_tasks do
7
+ path = File.expand_path(__dir__)
8
+ Dir.glob("#{path}/../tasks/**/*.rake").each { |f| load f }
9
+ end
10
+ end
@@ -0,0 +1,69 @@
1
+ module LambdaLayerCake
2
+ class RakeHelper
3
+ include Rake::DSL
4
+
5
+ attr_reader :root
6
+
7
+ def initialize(root)
8
+ @root = root
9
+ end
10
+
11
+ def docker_build_definitions!
12
+ desc "Build Docker Image"
13
+ task :build do
14
+ dockerfile_path = File.expand_path(__dir__ + "/../../templates/Dockerfile")
15
+
16
+ raise "Must specify a repository in moonbase_alpha.yml" if repository.blank?
17
+
18
+ tag = "#{repository}:#{build_version}"
19
+
20
+ cmd = %W{docker build -f #{dockerfile_path}
21
+ --build-arg RUNTIME_VERSION=#{RUBY_VERSION}
22
+ --build-arg BLDTIME_PKGS=#{config.build_packages.join(" ")}
23
+ --build-arg COMPILE_ASSETS=#{config.compile_assets.to_s}
24
+ -t #{tag}
25
+ #{root}}
26
+ system(*cmd) or raise
27
+ end
28
+
29
+ desc "Output the last version built"
30
+ task :latest_tag do
31
+ puts latest_tag
32
+ end
33
+
34
+ desc "Output the image name for the latest build"
35
+ task :latest_image do
36
+ puts "#{repository}:#{latest_tag}"
37
+ end
38
+ end
39
+
40
+ def config
41
+ Rails.configuration.moonbase_alpha
42
+ end
43
+
44
+ def repository
45
+ config.repository
46
+ end
47
+
48
+ def build_version
49
+ @build_version ||= begin
50
+ t = Time.now
51
+ "build-#{t.strftime("%Y-%m-%d-%H-%M-%S")}"
52
+ end
53
+ end
54
+
55
+ def latest_tag
56
+ @latest_tag ||= begin
57
+ cmd = %W{
58
+ docker image list
59
+ --format {{.Tag}}
60
+ #{repository}
61
+ }
62
+
63
+ IO.popen(cmd) do |versions|
64
+ versions.readlines.select {|v| v =~ /\Abuild-/ }.sort.last
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,3 @@
1
+ module MoonbaseAlpha
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,16 @@
1
+ require 'digest'
2
+ require 'fileutils'
3
+
4
+ require 'rake/packagetask'
5
+
6
+ require 'moonbase_alpha/rake_helper'
7
+
8
+
9
+
10
+ namespace :moonbase_alpha do
11
+
12
+ LambdaLayerCake::RakeHelper.new(Rails.root).tap do |rh|
13
+ rh.docker_build_definitions!
14
+ end
15
+
16
+ end
@@ -0,0 +1,103 @@
1
+ # Define global args
2
+ ARG FUNCTION_DIR="/function"
3
+ ARG RUNTIME_VERSION="2.7.2"
4
+ ARG DISTRO_VERSION="3.12"
5
+ ARG BLDTIME_PKGS=""
6
+ ARG RUNTIME_PKGS=""
7
+ ARG COMPILE_ASSETS
8
+
9
+ # Stage 1 - bundle base image + runtime
10
+ # Grab a fresh copy of the image and install GCC
11
+ FROM ruby:${RUNTIME_VERSION}-alpine${DISTRO_VERSION} AS base
12
+ # Include global args in this stage of the build
13
+ ARG FUNCTION_DIR
14
+ ARG RUNTIME_VERSION
15
+
16
+ # Install GCC (Alpine uses musl but we compile and link dependencies with GCC)
17
+ RUN apk add --no-cache \
18
+ libstdc++
19
+
20
+ # Create function directory
21
+ RUN mkdir -p ${FUNCTION_DIR}
22
+ WORKDIR ${FUNCTION_DIR}
23
+
24
+ # Needed for the lambda runtime
25
+ RUN ln -s /tmp tmp
26
+
27
+ # Configure bundler for deployment mode
28
+ RUN bundle config --local deployment 'true' && \
29
+ bundle config --local system_bindir ${FUNCTION_DIR}/bin && \
30
+ bundle config --local path vendor/bundle
31
+
32
+ RUN bundle config
33
+
34
+
35
+
36
+ # Stage 2 - build function and dependencies
37
+ FROM base AS build-image
38
+ # Install aws-lambda-cpp build dependencies
39
+ RUN apk add --no-cache \
40
+ build-base \
41
+ libtool \
42
+ autoconf \
43
+ automake \
44
+ libexecinfo-dev \
45
+ make \
46
+ cmake \
47
+ libcurl
48
+
49
+ # Include global args in this stage of the build
50
+ ARG FUNCTION_DIR
51
+ ARG RUNTIME_VERSION
52
+
53
+ ARG BLDTIME_PKGS
54
+ ARG COMPILE_ASSETS
55
+
56
+ # TODO make this work
57
+ # Blank packages by default just in case there aren't any
58
+ # RUN touch system-packages.txt
59
+
60
+ # Copy list of system packages to install
61
+ # COPY system-packages.txt ${FUNCTION_DIR}/
62
+
63
+ # Install system packages
64
+ # RUN xargs apk add < system-packages.txt
65
+ # TODO make this config driven
66
+ RUN apk add ${BLDTIME_PKGS}
67
+
68
+ # Copy Gemfile spec
69
+ COPY Gemfile Gemfile.lock ${FUNCTION_DIR}/
70
+ COPY vendor ${FUNCTION_DIR}/vendor
71
+
72
+ # RUN bundle config
73
+
74
+ # Install the gems for the project
75
+ RUN bundle install --jobs=4 && rm -Rf vendor/bundle/ruby/*/cache vendor/bundle/ruby/*/gems/*/test
76
+
77
+
78
+ # Copy over rest of project
79
+ COPY . ${FUNCTION_DIR}/
80
+
81
+
82
+
83
+ # Compile the assets
84
+ RUN if [[ "${COMPILE_ASSETS}" = "true" ]] ; then bin/rails assets:precompile ; fi
85
+
86
+ # Stage 3 - final runtime image
87
+ # Grab a fresh copy of the base image
88
+ FROM base
89
+
90
+ # Include global arg in this stage of the build
91
+ ARG FUNCTION_DIR
92
+ ARG RUNTIME_PKGS
93
+
94
+ # Set working directory to function root directory
95
+ WORKDIR ${FUNCTION_DIR}
96
+
97
+ RUN apk add ${RUNTIME_PKGS}
98
+
99
+ # Copy in the built dependencies
100
+ COPY --from=build-image ${FUNCTION_DIR} ${FUNCTION_DIR}
101
+
102
+ ENTRYPOINT ["/usr/local/bin/bundle", "exec", "bin/aws_lambda_ric"]
103
+ CMD ["app.handler"]
@@ -0,0 +1,27 @@
1
+ require_relative 'config/boot'
2
+
3
+ require 'lamby'
4
+ require 'lamby/ssm_parameter_store'
5
+
6
+ #Loads any configuration given in ParameterStore (typically passwords)
7
+ path = "/config/#{ENV['RAILS_ENV']}/#{ENV['SERVICE_NAME']}/env"
8
+ $envs = Lamby::SsmParameterStore.new path
9
+ $envs.get!
10
+ $envs.to_env
11
+
12
+ require_relative 'config/application'
13
+ require_relative 'config/environment'
14
+
15
+ $app = Rack::Builder.new { run Rails.application }.to_app
16
+
17
+ def handler(event:, context:)
18
+
19
+ if(event["source"] == 'aws.events')
20
+ Rails.logger.info("Processing a cron event")
21
+ ActiveRecord::Base.connection.query_cache.clear
22
+ # Event coming from Cloudwatch Events
23
+ else
24
+ # Lamby's standard path
25
+ Lamby.handler $app, event, context, rack: :api
26
+ end
27
+ end
@@ -0,0 +1,11 @@
1
+ require "test_helper"
2
+
3
+ class MoonbaseAlphaTest < Minitest::Test
4
+ def test_that_it_has_a_version_number
5
+ refute_nil ::MoonbaseAlpha::VERSION
6
+ end
7
+
8
+ def test_it_does_something_useful
9
+ assert true
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
2
+ require "moonbase_alpha"
3
+
4
+ require "minitest/autorun"
metadata ADDED
@@ -0,0 +1,57 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: moonbase_alpha
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Logan Bowers
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2021-01-30 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Builds an AWS Lambda-ready Docker image for a rails app
14
+ email:
15
+ - logan@datacurrent.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - README.md
21
+ - lib/generators/moonbase/moonbase_generator.rb
22
+ - lib/moonbase_alpha.rb
23
+ - lib/moonbase_alpha/railtie.rb
24
+ - lib/moonbase_alpha/rake_helper.rb
25
+ - lib/moonbase_alpha/version.rb
26
+ - lib/tasks/moonbase_alpha.rake
27
+ - templates/Dockerfile
28
+ - templates/app.rb
29
+ - test/moonbase_alpha_test.rb
30
+ - test/test_helper.rb
31
+ homepage: https://github.com/loganb/moonbase_alpha
32
+ licenses:
33
+ - MIT
34
+ metadata:
35
+ homepage_uri: https://github.com/loganb/moonbase_alpha
36
+ post_install_message:
37
+ rdoc_options: []
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 2.3.0
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubygems_version: 3.1.2
52
+ signing_key:
53
+ specification_version: 4
54
+ summary: Builds an AWS Lambda-ready Docker image for a rails app
55
+ test_files:
56
+ - test/moonbase_alpha_test.rb
57
+ - test/test_helper.rb