Add Heroku deployment support
This commit is contained in:
parent
3f30e91462
commit
a898072d76
8 changed files with 126 additions and 4 deletions
1
Procfile
Normal file
1
Procfile
Normal file
|
@ -0,0 +1 @@
|
||||||
|
web: bundle exec puma -C config/puma.rb
|
13
README.md
13
README.md
|
@ -118,6 +118,19 @@ Which will re-create the updated containers, leaving databases and data as is. D
|
||||||
|
|
||||||
Docker is great for quickly trying out software, but it has its drawbacks too. If you prefer to run Mastodon without using Docker, refer to the [production guide](https://github.com/tootsuite/mastodon/wiki/Production-guide) for examples, configuration and instructions.
|
Docker is great for quickly trying out software, but it has its drawbacks too. If you prefer to run Mastodon without using Docker, refer to the [production guide](https://github.com/tootsuite/mastodon/wiki/Production-guide) for examples, configuration and instructions.
|
||||||
|
|
||||||
|
## Deployment on Heroku (experimental)
|
||||||
|
|
||||||
|
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
|
||||||
|
|
||||||
|
Mastodon can theoretically run indefinitely on a free [Heroku](https://heroku.com) app. It should be noted this has limited testing and could have unpredictable results.
|
||||||
|
|
||||||
|
1. Click the above button.
|
||||||
|
2. Fill in the options requested.
|
||||||
|
* You can use a .herokuapp.com domain, which will be simple to set up, or you can use a custom domain. If you want a custom domain and HTTPS, you will need to upgrade to a paid plan (to use Heroku's SSL features), or set up [CloudFlare](https://cloudflare.com) who offer free "Flexible SSL" (note: CloudFlare have some undefined limits on WebSockets. So far, no one has reported hitting concurrent connection limits).
|
||||||
|
* You will want Amazon S3 for file storage. The only exception is for development purposes, where you may not care if files are not saaved. Follow a guide online for creating a free Amazon S3 bucket and Access Key, then enter the details.
|
||||||
|
* If you want your Mastodon to be able to send emails, configure SMTP settings here (or later). Consider using [Mailgun](https://mailgun.com) or similar, who offer free plans that should suit your interests.
|
||||||
|
3. Deploy! The app should be set up, with a working web interface and database. You can change settings and manage versions from the Heroku dashboard.
|
||||||
|
|
||||||
## Development with Vagrant
|
## Development with Vagrant
|
||||||
|
|
||||||
A quick way to get a development environment up and running is with Vagrant. You will need recent versions of [Vagrant](https://www.vagrantup.com/) and [VirtualBox](https://www.virtualbox.org/) installed.
|
A quick way to get a development environment up and running is with Vagrant. You will need recent versions of [Vagrant](https://www.vagrantup.com/) and [VirtualBox](https://www.virtualbox.org/) installed.
|
||||||
|
|
91
app.json
Normal file
91
app.json
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
{
|
||||||
|
"name": "Mastodon",
|
||||||
|
"description": "A GNU Social-compatible microblogging server",
|
||||||
|
"repository": "https://github.com/tootsuite/mastodon",
|
||||||
|
"logo": "https://github.com/tootsuite/mastodon/raw/master/app/assets/images/logo.png",
|
||||||
|
"env": {
|
||||||
|
"HEROKU": {
|
||||||
|
"description": "Leave this as true",
|
||||||
|
"value": "true",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"LOCAL_DOMAIN": {
|
||||||
|
"description": "The domain that your Mastodon instance will run on (this can be appname.herokuapp.com or a custom domain)",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"LOCAL_HTTPS": {
|
||||||
|
"description": "Will your domain support HTTPS? (Automatic for herokuapp, requires manual configuration for custom domains)",
|
||||||
|
"value": "false",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"PAPERCLIP_SECRET": {
|
||||||
|
"description": "The secret key for storing media files",
|
||||||
|
"generator": "secret"
|
||||||
|
},
|
||||||
|
"SECRET_KEY_BASE": {
|
||||||
|
"description": "The secret key base",
|
||||||
|
"generator": "secret"
|
||||||
|
},
|
||||||
|
"SINGLE_USER_MODE": {
|
||||||
|
"description": "Should the instance run in single user mode? (Disable registrations, redirect to front page)",
|
||||||
|
"value": "false",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"S3_ENABLED": {
|
||||||
|
"description": "Should Mastodon use Amazon S3 for storage? This is highly recommended, as Heroku does not have persistent file storage (files will be lost).",
|
||||||
|
"value": "true",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
"S3_BUCKET": {
|
||||||
|
"description": "Amazon S3 Bucket",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
"S3_REGION": {
|
||||||
|
"description": "Amazon S3 region that the bucket is located in",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
"AWS_ACCESS_KEY_ID": {
|
||||||
|
"description": "Amazon S3 Access Key",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
"AWS_SECRET_ACCESS_KEY": {
|
||||||
|
"description": "Amazon S3 Secret Key",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
"SMTP_SERVER": {
|
||||||
|
"description": "Hostname for SMTP server, if you want to enable email",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
"SMTP_PORT": {
|
||||||
|
"description": "Port for SMTP server",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
"SMTP_LOGIN": {
|
||||||
|
"description": "Username for SMTP server",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
"SMTP_PASSWORD": {
|
||||||
|
"description": "Password for SMTP server",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
"SMTP_DOMAIN": {
|
||||||
|
"description": "Domain for SMTP server. Will default to instance domain if blank.",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buildpacks": [
|
||||||
|
{
|
||||||
|
"url": "heroku/nodejs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "heroku/ruby"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"postdeploy": "bundle exec rails db:migrate && bundle exec rails db:seed"
|
||||||
|
},
|
||||||
|
"addons": [
|
||||||
|
"heroku-postgresql",
|
||||||
|
"heroku-redis"
|
||||||
|
]
|
||||||
|
}
|
|
@ -7,4 +7,4 @@ test:
|
||||||
|
|
||||||
production:
|
production:
|
||||||
adapter: redis
|
adapter: redis
|
||||||
url: redis://<%= ENV['REDIS_HOST'] || 'localhost' %>:<%= ENV['REDIS_PORT'] || 6379 %>/1
|
url: redis://<%= ENV['REDIS_PASSWORD'] ? ':' + ENV['REDIS_PASSWORD'] + '@' : '' %><%= ENV['REDIS_HOST'] || 'localhost' %>:<%= ENV['REDIS_PORT'] || 6379 %>/1
|
||||||
|
|
|
@ -45,10 +45,20 @@ Rails.application.configure do
|
||||||
# Use a different logger for distributed setups.
|
# Use a different logger for distributed setups.
|
||||||
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
|
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
|
||||||
|
|
||||||
|
# Parse and split the REDIS_URL if passed (used with hosting platforms such as Heroku).
|
||||||
|
# Set ENV variables because they are used elsewhere.
|
||||||
|
if ENV['REDIS_URL']
|
||||||
|
redis_url = URI.parse(ENV['REDIS_URL'])
|
||||||
|
ENV['REDIS_HOST'] = redis_url.host
|
||||||
|
ENV['REDIS_PORT'] = redis_url.port.to_s
|
||||||
|
ENV['REDIS_PASSWORD'] = redis_url.password
|
||||||
|
end
|
||||||
|
|
||||||
# Use a different cache store in production.
|
# Use a different cache store in production.
|
||||||
config.cache_store = :redis_store, {
|
config.cache_store = :redis_store, {
|
||||||
host: ENV.fetch('REDIS_HOST') { 'localhost' },
|
host: ENV.fetch('REDIS_HOST') { 'localhost' },
|
||||||
port: ENV.fetch('REDIS_PORT') { 6379 },
|
port: ENV.fetch('REDIS_PORT') { 6379 },
|
||||||
|
password: ENV.fetch('REDIS_PASSWORD') { false },
|
||||||
db: 0,
|
db: 0,
|
||||||
namespace: 'cache',
|
namespace: 'cache',
|
||||||
expires_in: 20.minutes
|
expires_in: 20.minutes
|
||||||
|
@ -85,7 +95,7 @@ Rails.application.configure do
|
||||||
:address => ENV['SMTP_SERVER'],
|
:address => ENV['SMTP_SERVER'],
|
||||||
:user_name => ENV['SMTP_LOGIN'],
|
:user_name => ENV['SMTP_LOGIN'],
|
||||||
:password => ENV['SMTP_PASSWORD'],
|
:password => ENV['SMTP_PASSWORD'],
|
||||||
:domain => config.x.local_domain,
|
:domain => ENV['SMTP_DOMAIN'] || config.x.local_domain,
|
||||||
:authentication => :plain,
|
:authentication => :plain,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,5 +3,6 @@
|
||||||
Redis.current = Redis.new(
|
Redis.current = Redis.new(
|
||||||
host: ENV.fetch('REDIS_HOST') { 'localhost' },
|
host: ENV.fetch('REDIS_HOST') { 'localhost' },
|
||||||
port: ENV.fetch('REDIS_PORT') { 6379 },
|
port: ENV.fetch('REDIS_PORT') { 6379 },
|
||||||
|
password: ENV.fetch('REDIS_PASSWORD') { false },
|
||||||
driver: :hiredis
|
driver: :hiredis
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
host = ENV.fetch('REDIS_HOST') { 'localhost' }
|
host = ENV.fetch('REDIS_HOST') { 'localhost' }
|
||||||
port = ENV.fetch('REDIS_PORT') { 6379 }
|
port = ENV.fetch('REDIS_PORT') { 6379 }
|
||||||
|
password = ENV.fetch('REDIS_PASSWORD') { false }
|
||||||
|
|
||||||
Sidekiq.configure_server do |config|
|
Sidekiq.configure_server do |config|
|
||||||
config.redis = { host: host, port: port }
|
config.redis = { host: host, port: port, password: password}
|
||||||
end
|
end
|
||||||
|
|
||||||
Sidekiq.configure_client do |config|
|
Sidekiq.configure_client do |config|
|
||||||
config.redis = { host: host, port: port }
|
config.redis = { host: host, port: port, password: password }
|
||||||
end
|
end
|
||||||
|
|
|
@ -40,6 +40,11 @@ preload_app!
|
||||||
# cannot share connections between processes.
|
# cannot share connections between processes.
|
||||||
#
|
#
|
||||||
on_worker_boot do
|
on_worker_boot do
|
||||||
|
|
||||||
|
if ENV["HEROKU"] #Spwan the workers from Puma, to only use one dyno
|
||||||
|
@sidekiq_pid ||= spawn('bundle exec sidekiq -q default -q mailers -q push')
|
||||||
|
end
|
||||||
|
|
||||||
ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
|
ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue