# Installing Flipper Pro

> Install Flipper Pro in your Rails app. Gemfile, migrations, engine mount, authentication, multi-database support.

## How it deploys

Flipper Pro ships as a Ruby gem and mounts as a Rails Engine. It reads and writes your existing database, protected by your existing authentication. No new infrastructure, no outbound network calls, nothing phones home.

Works with single-database and multi-database Rails setups.

## Installing the gem

Add Flipper Pro to your Gemfile:

```ruby
source "https://rubygems.pkg.github.com/flippercloud" do
  gem "flipper-pro"
end
```

After purchase, you'll receive an access credential. Configure Bundler to authenticate:

```
bundle config https://rubygems.pkg.github.com/flippercloud USERNAME:TOKEN
```

Install:

```
bundle
```

## Migrations

Generate and run the migrations:

```
bin/rails flipper_pro:install:migrations
bin/rails db:migrate
```

Flipper Pro stores flag data, groups, expressions, audit history, and group memberships in your database.

## Mount the engine

Mount Flipper Pro in `config/routes.rb`:

```ruby
Rails.application.routes.draw do
  mount Flipper::Pro::Engine => "/flipper"
end
```

## Authenticate

The Pro admin dashboard ships without authentication. Protect it with your existing auth. Three common patterns:

### Rack basic auth

```ruby
# config/initializers/flipper.rb
expected_username = ::Digest::SHA256.hexdigest(ENV.fetch("FLIPPER_PRO_USERNAME"))
expected_password = ::Digest::SHA256.hexdigest(ENV.fetch("FLIPPER_PRO_PASSWORD"))

Flipper::Pro::Engine.middleware.use(Rack::Auth::Basic) do |username, password|
  given_username = ::Digest::SHA256.hexdigest(username.to_s)
  given_password = ::Digest::SHA256.hexdigest(password.to_s)

  ActiveSupport::SecurityUtils.secure_compare(expected_username, given_username) &
    ActiveSupport::SecurityUtils.secure_compare(expected_password, given_password)
end
```

Hashing both sides keeps the comparison constant-time regardless of input length. Reading the credentials above `middleware.use` makes `ENV.fetch` raise at boot if either is missing, instead of failing on the first request to the dashboard.

### Devise

```ruby
# config/routes.rb
authenticate :user, ->(user) { user.admin? } do
  mount Flipper::Pro::Engine => "/flipper"
end
```

### Custom middleware

```ruby
# config/initializers/flipper.rb
Flipper::Pro::Engine.middleware.use MyCustomMiddleware
```

## Multi-database support

If your app uses ActiveRecord's multiple database support (for example, read replicas with `DatabaseSelector`), configure Flipper Pro's connections:

```ruby
# config/initializers/flipper.rb
Flipper::Pro.configure do |config|
  config.database = { writing: :primary, reading: :primary }
end
```

Without this, you may see `No connection pool for 'ActiveRecord::Base' found for the 'reading' role` errors.

## Upgrading from Flipper OSS

Flipper Pro is a drop-in upgrade. Your existing Flipper adapter, flag data, groups, and Rails integration keep working. The change is the gem you install and the engine you mount.
