• Stars
    star
    422
  • Rank 98,913 (Top 3 %)
  • Language
    Dockerfile
  • License
    MIT License
  • Created over 1 year ago
  • Updated about 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Provides a Rails generator to produce Dockerfiles and related files.

Overview

Provides a Rails generator to produce Dockerfiles and related files. This is being proposed as the generator to be included in Rails 7.1, and a substantial number of pull requests along those lines have already been merged. This repository contains fixes and features beyond those pull requests. Highlights:

  • Supports all Rails supported releases, not just Rails 7.1, and likely works with a number of previous releases.
  • Can be customized using flags on the generate dockerfile command, and rerun to produce a custom tailored dockerfile based on detecting the actual features used by your application.
  • Will set .node_version, packageManager and install gems if needed to deploy your application.
  • Can produce a docker-compose.yml file for locally testing your configuration before deploying.

For more background:

  • Motivation - why this generator was created and what problems it is meant to solve
  • Demos - scripts to copy and paste into an empty directory to launch demo apps
  • Test Results - expected outputs for each test

Usage

Install from the root of your Rails project by running the following.

bundle add dockerfile-rails --optimistic --group development
bin/rails generate dockerfile

The --optimistic flag will make sure you always get the latest dockerfile-rails gem when you run bundle update && rails g dockerfile.

General option:

  • --force - overwrite existing files
  • --skip - keep existing files

If neither are specified, you will be prompted if a file exists with different contents. If both are specified, --force takes precedence.

Runtime Optimizations:

Build optimizations:

  • --cache - use build caching to speed up builds
  • --parallel - use multi-stage builds to install gems and node modules in parallel

Add/remove a Feature:

  • --ci - include test gems in deployed image
  • --compose - generate a docker-compose.yml file
  • --max-idle=n - exit afer n seconds of inactivity. Supports iso 8601 and sleep syntaxes. Uses passenger for now, awaiting puma support.
  • --nginx - serve static files via nginx. May require --root on some targets to access /dev/stdout
  • --thruster - serve static files via thruster.
  • --no-link - don't add --link to COPY statements. Some tools (like at the moment, buildah) don't yet support this feature.
  • --no-lock - don't add linux platforms, set BUNDLE_DEPLOY, or --frozen-lockfile. May be needed at times to work around a rubygems bug.
  • --sudo - install and configure sudo to enable sudo -iu rails access to full environment

Error Tracking & Alerting:

  • --rollbar - install gem and a default initializer for Rollbar
  • --sentry - install gems and a default initializer for Sentry

Add a Database:

Generally the dockerfile generator will be able to determine what dependencies you are actually using. But should you be using DATABASE_URL, for example, at runtime additional support may be needed:

  • --litefs - use LiteFS
  • --mysql - add mysql libraries
  • --postgresql - add postgresql libraries
  • --redis - add redis libraries
  • --sqlite3 - add sqlite3 libraries
  • --sqlserver - add SQL Server libraries

Add a package/environment variable/build argument:

Not all of your needs can be determined by scanning your application. For example, I like to add vim and procps.

  • --add package... - add one or more debian packages
  • --arg=name:value - add a build argument
  • --env=name:value - add an environment variable
  • --remove package... - remove package from "to be added" list

Args and environment variables can be tailored to a specific build phase by adding -base, -build, or -deploy after the flag name (e.g --add-build freetds-dev --add-deploy freetds-bin). If no such suffix is found, the default for arg is -base, and the default for env is -deploy. Removal of an arg or environment variable is done by leaving the value blank (e.g --env-build=PORT:).

Configuration:

  • --bin-cd - adjust binstubs to set current working directory autocrlf enabled or may not be able to set bin stubs as executable.
  • --label=name:value - specify docker label. Can be used multiple times. See LABEL for detail
  • --no-prepare - omit db:prepare. Useful for cloud platforms with release phases
  • --passenger - use Phusion Passenger under nginx
  • --platform=s - specify target platform. See FROM for details
  • --variant=s - dockerhub ruby variant, defaults to slim. See docker official images for list.
  • --precompile=defer - may be needed when your configuration requires access to secrets that are not available at build time. Results in larger images and slower deployments.
  • --root - run application as root
  • --windows - make Dockerfile work for Windows users that may have set git config --global core.autocrlf true
  • --private-gemserver-domain=gems.example.com - set the domain name of your private gemserver. This is used to tell bundler for what domain to use the credentials of a private gemserver provided via a docker secret

Advanced Customization:

There may be times where feature detection plus flags just aren't enough. As an example, you may wish to configure and run multiple processes.

  • --instructions=path - a dockerfile fragment to be inserted into the final document.
  • --migration=cmd - a replacement (generally a script) for db:prepare/db:migrate.
  • --procfile=path - a Procfile to use in place of launching Rails directly.

Like with environment variables, packages, and build args, --instructions can be tailored to a specific build phase by adding -base, -build, or -deploy after the flag name, with the default being -deploy.

Additionally, if the instructions start with a shebang instead the file being treated as a Dockerfile fragment, the file is treated as a script and a RUN statement is added to your Dockerfile instead.


Options are saved between runs into config/dockerfile.yml. To invert a boolean options, add or remove a no- prefix from the option name.

Testing

A single invocation of rake test:all will run all of the tests defined. dockerfile-rails has are three types of tests:

  • rake test:rubocop runs rubocop using the same options as the Rails codebase.
  • rake test:system creates a new esbuild application, generates a dockerfile, builds and runs it. As this is time consuming, only one application is tested this way at this time, and a --javascript example was selected as it exercises a large portion of the features.
  • rake test runs integration tests, as described below

The current integration testing strategy is to run rails new and generate dockerfile with various configurations and compare the generated artifacts with expected results. ARG values in Dockerfiles are masked before comparison.

Running all integration tests, or even a single individual test can be done as follows:

rake test

bundle exec rake test TEST=test/test_minimal.rb
bundle exec ruby test/test_minimal.rb

To assist with this process, outputs of tests can be captured automatically. This is useful when adding new tests and when making a change that affects many tests. Be sure to inspect the output (e.g., by using git diff) before committing.

rake test:capture

If you are running a single test, the following environment variables settings may be helpful:

  • RAILS_ENV=TEST will match the environment used to produce the captured outputs.
  • TEST_CAPTURE=1 will capture test results.
  • TEST_KEEP=1 will leave the test app behind for inspection after the test completes.

Historical Links

The following links relate to the coordination between this package and Rails 7.1.

Parallel efforts for Hanami:

More Repositories

1

postgres-ha

Postgres + Stolon for HA clusters as Fly apps.
Go
287
star
2

litefs-js

JavaScript utilities for working with LiteFS on Fly.io
TypeScript
154
star
3

nginx-cluster

A horizontally scalable NGINX caching cluster
Shell
125
star
4

terraform-provider-fly

Terraform provider for the Fly.io API
Go
114
star
5

dockerfile-node

Dockerfile generator for Node.js
JavaScript
111
star
6

edge-apollo-cache

Run and cache results from your Apollo GraphQL server on the edge with Fly
JavaScript
91
star
7

redis-geo-cache

A global Redis cache
Shell
81
star
8

bun

Bun JS app doing basically nothing
TypeScript
76
star
9

redis

Launch a Redis server on Fly
Shell
70
star
10

fly-run-this-function-on-another-machine

This is a simple example on how to spawn a Fly.io machine and run a function from there.
JavaScript
63
star
11

hello-rust

Rust example app on Fly.io
Dockerfile
62
star
12

nats-cluster

Global messaging for apps that need to talk to each other.
Go
44
star
13

postgres-flex

Postgres HA setup using repmgr
Go
44
star
14

tailscale-router

Go
40
star
15

rds-connector

Trivial Terraform example for a WireGuard peer to RDS
HCL
38
star
16

docker-daemon

A Docker daemon to run in Fly and access via a WireGuard peer.
Shell
38
star
17

fly-laravel

Run your Laravel apps on Fly
PHP
38
star
18

hello_elixir

An example for building and deploying an Elixir application to Fly using a Dockerfile
Elixir
38
star
19

litestream-base

A base Docker image for adding Litestream to apps
Dockerfile
33
star
20

smokescreen

An example of deploying Smokescreen on Fly.io
Go
31
star
21

go-example

A minimal Go application for tutorials
Go
29
star
22

python-hellofly-flask

A Pythonic version of the Hellofly example
Python
29
star
23

laravel-docker

Base Docker images for use with Laravel on Fly.io
Shell
28
star
24

cockroachdb

Shell
27
star
25

nginx

A fly app nginx config
Dockerfile
23
star
26

supercronic

Run periodic jobs on Fly with supercronic
Dockerfile
21
star
27

hello-fly-langchain

A minimal example of how to deploy LangChain to Fly.io using Flask
Python
21
star
28

hellonode-builtin

A minimal Fly example Node application for use in tutorials
JavaScript
20
star
29

vscode-remote

Shell
19
star
30

privatenet

Examples around querying 6PN private networking on Fly
JavaScript
18
star
31

node-demo

Fly.io Node.js demo
JavaScript
18
star
32

puppeteer-js-renderer

A service to render js for web scraping hosted on fly.io
JavaScript
17
star
33

hello-static

Create a static website with Fly - HTML from the example
HTML
16
star
34

ghost-litestream

Ghost + Litestream for global sqlite blogging
Dockerfile
16
star
35

wordpress-sqlite

Wordpress on SQLite
PHP
16
star
36

coredns

Authoritative CoreDNS on Fly.io
DIGITAL Command Language
15
star
37

ichabod

serf + headless chromium && CDP
Dockerfile
14
star
38

nix-base

Nix overlays for supporting Nix deployments on Fly.io
Nix
14
star
39

fly-log-local

Store Fly app logs locally.
Dockerfile
13
star
40

terraformed-machines

Example of Fly.io machines orchestration with Terraform and DNSimple
HCL
13
star
41

elixir_opentel_and_grafana

Project that goes with a Fly.io Phoenix Files article
Elixir
13
star
42

dockerfile-laravel

PHP
13
star
43

fastify-functions

Example Fastify server
JavaScript
12
star
44

postgres-migrator

Fly app that works to streamline Postgres migrations.
Dockerfile
12
star
45

pdf-appliance

Auto start machines that will generate PDFs for your application
TypeScript
12
star
46

hellodeno

A version of the Hellodeno example that uses flyctl's builtin deno builder
TypeScript
11
star
47

whisper-example

Fly GPU Machines transcribing an mp3 file with Whisper
Dockerfile
11
star
48

hello_elixir_sqlite

An example for building and deploying an Elixir application to Fly using a Dockerfile and SQLite!
Elixir
10
star
49

keydb

KeyDB server on Fly
Shell
9
star
50

fly-app-with-multiple-internal-ports

Example of how to deploy an app that has multiple ports listened to
JavaScript
9
star
51

fly-varnish

Dockerfile
9
star
52

grafana

Run Grafana on Fly
8
star
53

ollama-demo

@jmorganca's ollama.ai demo app on Fly.io
8
star
54

postgres-importer

Shell
8
star
55

nodejs-planetscale-read-replicas

A sample Node.js app that uses a Planetscale database with additional read-only regions
JavaScript
7
star
56

kong-api-gateway

Dockerfile
7
star
57

hostnamesapi

JavaScript examples for working with the new hostnames API on Fly
JavaScript
7
star
58

appkata-minio

MinIO S3-compatible storage on Fly
Dockerfile
7
star
59

autoscale-to-zero-demo

TypeScript
7
star
60

live-elements-demo

Live Elements Demo
Ruby
6
star
61

6pn-demo-chat

A Node-based websockets and NATS chat app which uses Fly 6PN networking
JavaScript
6
star
62

rqlite

Shell
6
star
63

deno-apollo

TypeScript
6
star
64

hello-fly

JavaScript
6
star
65

ssh-app

Run an SSH server to connect your privately networked Database apps to things like BI tools
Dockerfile
6
star
66

global-apollo-server

Fly global deployment with Apollo Server and Prisma
TypeScript
6
star
67

rails-nix

Deploy Rails apps on Fly.io with Nix
Ruby
5
star
68

code-server-dev-environment

Dockerfile
5
star
69

hello-flask

Example project demonstrating how to deploy a Flask app to Fly.io.
HTML
5
star
70

postgres

Deploy a Postgres database on Fly, ready for your Fly apps.
4
star
71

appkata-mqtt

An MQTT server app (with Mosquitto) with TLS+passwords
Dockerfile
4
star
72

global-rails

Ruby
4
star
73

globe-request-mapper

Elixir
4
star
74

buildkite-agent

Run a Buildkite agent on Fly with disk caching
Dockerfile
4
star
75

openresty-basic

Dockerfile
4
star
76

flydictionary

A light crud example for database examples
JavaScript
4
star
77

grpc-service

Running gRPC services on Fly.io
JavaScript
4
star
78

elixir_prom_ex_example

Elixir
4
star
79

hello-create-react-app

JavaScript
4
star
80

hello-remix

Sample Remix app setup for deployment on Fly.io
JavaScript
3
star
81

tcp-echo

TCP echo service for testing things that TCP
Go
3
star
82

rails-on-fly

Ruby
3
star
83

laravel-worker

Auto-scaled Laravel queue workers on Fly.io
PHP
3
star
84

pi-hole

Dockerfile
3
star
85

fly-nestjs

Example NestJS application configured for deployment on Fly.io
TypeScript
3
star
86

view-component-playground

Various view components tried in Rails
Ruby
3
star
87

python_gpu_example

A setup with Jupyter for GPU-enabled ML tinkering
Shell
3
star
88

hello-django

Example project demonstrating how to deploy a Django app to Fly.io.
Python
3
star
89

localai-demo

LocalAI demo app on Fly.io
Shell
3
star
90

rails-statics

Rails application to test the performance of Rails static assets
Ruby
3
star
91

hello-django-postgres

Python
2
star
92

fly-laravel-litefs

Guide on deploying multiple instances of a Laravel Fly app and integrating LiteFS and fly-replay to allow syncing SQLite database across the instances.
PHP
2
star
93

ollama-webui-demo

Shell
2
star
94

udp-echo-

Sample TCP/UDP Echo Service
Go
2
star
95

replicache-websocket

TypeScript
2
star
96

rails-machine-workers

A demonstration of how to use Fly Machines for "scale-to-0" ActiveJob background workers
Ruby
2
star
97

flygreeting

An example app for other examples to use.
Go
2
star
98

postgres-standalone

Standalone Postgres on Fly
Go
2
star
99

flychat-ws

A chat example using raw websockets, tested on Fly.io
JavaScript
2
star
100

fly-lucky

Crystal Lucky Framework app for Fly.io deployment
Crystal
2
star