You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: context/deployment.md
+108-3Lines changed: 108 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,7 @@ Falcon can be deployed into production either as a standalone application server
16
16
17
17
`falcon host` loads configuration from the `falcon.rb` file in your application directory. This file contains configuration blocks which define how to host the application and any related services. This file should be executable and it invokes `falcon-host` which starts all defined services.
18
18
19
-
Here is a basic example which hosts a rack application using :
19
+
Here is a basic example which hosts a rack application:
20
20
21
21
~~~ruby
22
22
#!/usr/bin/env falcon-host
@@ -33,29 +33,134 @@ service hostname do
33
33
34
34
# Insert an in-memory cache in front of the application (using async-http-cache).
35
35
cache true
36
+
37
+
# Connect to the supervisor for monitoring.
38
+
includeAsync::Container::Supervisor::Supervised
36
39
end
37
40
38
41
service "supervisor"do
39
42
includeFalcon::Environment::Supervisor
43
+
44
+
monitors do
45
+
[
46
+
MemoryMonitor.new(
47
+
# Check every 10 seconds:
48
+
interval:10,
49
+
# Per-supervisor (cluster) limit:
50
+
total_size_limit:1000*1024*1024,
51
+
# Per-process limit:
52
+
maximum_size_limit:200*1024*1024
53
+
)
54
+
]
55
+
end
40
56
end
41
57
~~~
42
58
43
59
These configuration blocks are evaluated using the [async-service](https://github.com/socketry/async-service) gem. The supervisor is an independent service which monitors the health of the application and can restart it if necessary. Other services like background job processors can be added to the configuration.
44
60
45
61
### Environments
46
62
47
-
The service blocks define configuration that is loaded by the serivce layer to control how the service is run. The `service ... do` block defines the service name and the environment in which it runs. Different modules can be included to provide different functionality, such as `Falcon::Environment::Rack` for Rack applications, or `Falcon::Environment::LetsEncryptTLS` for automatic TLS certificate management.
63
+
The service blocks define configuration that is loaded by the service layer to control how the service is run. The `service ... do` block defines the service name and the environment in which it runs. Different modules can be included to provide different functionality, such as `Falcon::Environment::Rack` for Rack applications, or `Falcon::Environment::LetsEncryptTLS` for automatic TLS certificate management.
64
+
65
+
### Application Configuration
66
+
67
+
The environment configuration is defined in the `Falcon::Environment` module. The {ruby Falcon::Environment::Application} environment supports the generic virtual host functionality, but you can customise any parts of the configuration, e.g. to bind a production host to `localhost:3000` using plaintext HTTP/2:
68
+
69
+
~~~ruby
70
+
#!/usr/bin/env falcon host
71
+
# frozen_string_literal: true
72
+
73
+
require"falcon/environment/rack"
74
+
require"falcon/environment/supervisor"
75
+
76
+
hostname =File.basename(__dir__)
77
+
service hostname do
78
+
includeFalcon::Environment::Rack
79
+
includeFalcon::Environment::LetsEncryptTLS
80
+
81
+
endpoint do
82
+
Async::HTTP::Endpoint
83
+
.parse('http://localhost:3000')
84
+
.with(protocol:Async::HTTP::Protocol::HTTP2)
85
+
end
86
+
end
87
+
88
+
service "supervisor"do
89
+
includeFalcon::Environment::Supervisor
90
+
end
91
+
~~~
92
+
93
+
You can verify this is working using `nghttp -v http://localhost:3000`.
94
+
95
+
#### Application Configuration Example for Heroku
96
+
97
+
Building on the examples above, the following is a full configuration example for Heroku:
98
+
99
+
~~~bash
100
+
# Procfile
101
+
102
+
web: bundle exec falcon host
103
+
~~~
104
+
105
+
~~~ruby
106
+
# falcon.rb
107
+
108
+
#!/usr/bin/env -S falcon host
109
+
# frozen_string_literal: true
110
+
111
+
require"falcon/environment/rack"
112
+
113
+
hostname =File.basename(__dir__)
114
+
115
+
service hostname do
116
+
includeFalcon::Environment::Rack
117
+
118
+
# By default, Falcon uses Etc.nprocessors to set the count, which is likely incorrect on shared hosts like Heroku.
119
+
# Review the following for guidance about how to find the right value for your app:
Falcon virtual provides a virtual host proxy and HTTP-to-HTTPS redirection for multiple applications. It is designed to be a zero-configuration deployment option, allowing you to run multiple applications on the same server.
proxy -->|HTTP/2 UNIX PIPE| server["Application Server (Rack Compatible)"];
156
+
~~~
157
+
53
158
You need to create a `falcon.rb` configuration in the root of your applications, and start the virtual host:
54
159
55
160
~~~bash
56
161
falcon virtual /srv/http/*/falcon.rb
57
162
~~~
58
163
59
-
By default, it binds to both HTTP and HTTPS ports, and automatically redirects HTTP requests to HTTPS. It also supports automatic TLS certificate management using Let's Encrypt.
164
+
By default, it binds to both HTTP and HTTPS ports, and automatically redirects HTTP requests to HTTPS. It also supports TLS SNI for resolving the certificates.
60
165
61
166
See the [docker example](https://github.com/socketry/falcon-virtual-docker-example) for a complete working example.
This guide explains some of the extended features and functionality of Falcon.
4
+
5
+
## WebSockets
6
+
7
+
Falcon supports (partial and full) `rack.hijack` for both for HTTP/1 and HTTP/2 connections. You can use [async-websocket] in any controller layer to serve WebSocket connections.
Falcon supports the `rack.early_hints` API when running over HTTP/2. You can [read more about the implementation and proposed interface](https://www.codeotaku.com/journal/2019-02/falcon-early-hints/index).
This guide gives an overview of how to use Falcon for running Ruby web applications.
4
+
5
+
## Installation
6
+
7
+
Add the gem to your project:
8
+
9
+
~~~bash
10
+
$ bundle add falcon
11
+
~~~
12
+
13
+
Or, if you prefer, install it globally:
14
+
15
+
~~~bash
16
+
$ gem install falcon
17
+
~~~
18
+
19
+
## Core Concepts
20
+
21
+
Falcon is a high-performance web server for Ruby. It is designed to be fast, lightweight, and easy to use.
22
+
23
+
-**Asynchronous**: Falcon is built on top of the fiber scheduler and the [async gem](https://github.com/socketry/async) which allow it to handle thousands of connections concurrently.
24
+
-**Rack Compatible**: Falcon is a Rack server. It can run any Rack application, including Rails, Sinatra, and Roda with no modifications.
25
+
-**Secure**: Falcon supports TLS out of the box. It can generate self-signed certificates for localhost.
26
+
-**HTTP/2**: Falcon is build on top of the [async-http gem](https://github.com/socketry/async-http) which supports HTTP/2. It can serve multiple requests over a single connection.
27
+
-**WebSockets**: Falcon supports WebSockets using the [async-websocket gem](https://github.com/socketry/async-websocket) which takes advantage of Rack 3 streaming responses. You can build complex real-time applications with ease.
28
+
29
+
### Rack
30
+
31
+
Falcon is a Rack server. This means it can run any Rack application, including Rails, Sinatra, and Roda. It is compatible with the Rack 2 and Rack 3 specifications. Typically these applications have a `config.ru` file that defines the application. Falcon can run these applications directly:
For local application development, you can use the `falcon serve` command. This will start a local server on `https://localhost:9292`. Falcon generates self-signed certificates for `localhost`. This allows you to test your application with HTTPS locally.
50
+
51
+
To run on a different port:
52
+
53
+
~~~bash
54
+
$ falcon serve --port 3000
55
+
~~~
56
+
57
+
### Unencrypted HTTP
58
+
59
+
If you want to run Falcon without TLS, you can use the `--bind` option to bind to an unencrypted HTTP endpoint:
60
+
61
+
~~~bash
62
+
$ falcon serve --bind http://localhost:3000
63
+
~~~
64
+
65
+
### Using with Rackup
66
+
67
+
You can invoke Falcon via `rackup`:
68
+
69
+
~~~bash
70
+
$ rackup --server falcon
71
+
~~~
72
+
73
+
This will run a single-threaded instance of Falcon using `http/1`. While it works fine, it's not recommended to use `rackup` with `falcon`, because performance will be limited.
This guide gives an overview of how Falcon handles an incoming web request.
4
+
5
+
## Overview
6
+
7
+
When you run `falcon serve`, Falcon creates a {ruby Falcon::Controller::Serve} which is used to create several worker threads or processes. Before starting the workers, the controller binds to an endpoint (e.g. a local unix socket, a TCP network socket, etc). The workers are spawned and receive this bound endpoint, and start accepting connections.
8
+
9
+
The workers individually load a copy of your rack application. These applications are wrapped using {ruby Falcon::Adapters::Rack} which modifies the incoming {ruby Protocol::HTTP::Request} object into an `env` object suitable for your application. It also handles converting the output of your rack application `[status, headers, body]` into an instance of {ruby Falcon::Adapters::Response} which is derived from {ruby Protocol::HTTP::Response}.
10
+
11
+
## Server
12
+
13
+
The server itself is mostly implemented by {ruby Async::HTTP::Server} which in turn depends on the `protocol-http` gems for the actual protocol implementations. Therefore, Falcon is primarily a bridge between the underlying protocol objects and the Rack interface.
This guide explains the performance characteristics of Falcon.
4
+
5
+
## Scalability
6
+
7
+
Falcon uses an asynchronous event-driven reactor to provide non-blocking IO. It uses one Fiber per request, which have minimal overhead. Falcon can handle a large number of in-flight requests including long-running connections like websockets, HTTP/2 streaming, etc.
8
+
9
+
-[Improving Ruby Concurrency](https://www.codeotaku.com/journal/2018-06/improving-ruby-concurrency/index#performance) – Comparison of Falcon and Puma.
10
+
11
+
### Falcon Benchmark
12
+
13
+
The [falcon-benchmark] suite looks at how various servers respond to different levels of concurrency across several sample applications.
Falcon uses [async-container] to start multiple copies of your application. Each instance of your application is isolated by default for maximum fault-tolerance. However, this can lead to increased memory usage. Preloading parts of your application reduce this overhead and in addition can improve instance start-up time. To understand your application memory usage, you should use [process-metrics] which take into account memory shared between processes.
By default, falcon will load all gems in the `preload` group:
31
+
32
+
~~~ruby
33
+
# In gems.rb:
34
+
35
+
source "https://rubygems.org"
36
+
37
+
group :preloaddo
38
+
# List any gems you want to be pre-loaded into the falcon process before forking.
39
+
end
40
+
~~~
41
+
42
+
#### Preloading Files
43
+
44
+
Create a file in your application called `preload.rb`. You can put this file anywhere in your application.
45
+
46
+
##### Falcon Serve
47
+
48
+
`falcon serve` has a `--preload` option which accepts the path to this file.
49
+
50
+
##### Falcon Host
51
+
52
+
`falcon.rb` applications may have a `preload` configuration option.
53
+
54
+
## System Limitations
55
+
56
+
If you are expecting to handle many simultaneous connections, please ensure you configure your file limits correctly.
57
+
58
+
~~~
59
+
Errno::EMFILE: Too many open files - accept(2)
60
+
~~~
61
+
62
+
This means that your system is limiting the number of files that can be opened by falcon. Please check the `ulimit` of your system and set it appropriately.
0 commit comments