Multisite configuration with Docker

docker

(Sam Saffron) #89

no there are no known open issues with it, it works fine for for us and is how we host our business and enterprise customers.

BUT

I strongly recommend you are a sysadmin or developer and have a strong understanding of Docker before attempting this kind of install.

You can not simply cut-and-paste-and-pray.


(Tenzan) #90

I’m experimenting in DigitalOcean with my own account and have saved a snapshot, so I’m OK if I fail.
But I don’t know how…


#91

That’s funny, it does seem to mostly be a cut and paste configuration after you understand what’s going on. There’s been at least a few people who have brought up issues recently with multisite, but maybe they initially misconfigured, got it to work for a period of time, and now the cracks show as things inevitably change. I prefer to keep it simple.


(Kane York) #92

No, you want a /var/discourse/containers/app2.yml file.

There should be a howto on how to fix up the “volumes” section of the container configuration for this.


(Sean Whalen) #93

As someone who is very new to Docker and Discourse, why not just give each site its own containers and route the requests from the host with a reverse proxy? Is there too much overhead?


(eriko) #94

Extra overhead of containers plus extra rails frame works running. If all the instances use about the same amount of resources it does not make sense to split them up and it is way easier to update them all at once. On the other hand if a couple are very resource intensive it might make sense to slip them off so you can move them to place with more resources. If I remember correctly discourse hosting does both for these reasons.


(oblio) #95

I have a couple of questions regarding the “multisite” setup.

I want to integrate Discourse on 3 separate blogs:
dota.oblio360.com
hearthstone.oblio360.com
blog.oblio360.com

Ideally there would be no need for 3 separate Discourse instances but unless I’ve missed something from here:
http://eviltrout.com/2014/01/22/embedding-discourse.html
this doesn’t seem possible because the embed URL is a single URL. Or am I missing something and it is possible to embed it on multiple blogs and I can just use the domain name?

Anyway, moving on to multisite:
There’s a data.yml which configures a PostgreSQL container.
There’s a web_only.yml which configures a Rail + Redis container.

Now, for a multisite configuration, I see the snippet above adds a new PostgreSQL database for the standalone setup. How would this change in case of a multiple container setup: web_only + data?
Should I create multiple web containers? I.e. web_only_dota.yml, web_only_blog.yml? (I’m not sure I understand how the forum can be embedded with just 1 running Rails app since there seems to be 1 configuration value for the embedding).
Should I reuse the same container and just add hooks?

What would be the best way to setup multiple forums for some relatively small communities?

Thanks for any answers, meanwhile I will keep digging through discourse_docker and if I get something working I might even contribute a multisite.yml as a sample.


(Kane York) #96

Every site gets its own set of SiteSettings, that’s why.

The configuration that would be most amenable to growth and change in the future - especially if your community wants to talk about other games, or stops talking about one of them - is to put it all on one forum. Have top-level categories: Dota 2, Hearthstone, Blog, Forum Feedback, General. If someone really hates Hearthstone, they can put the category on mute.


(oblio) #97

I’d really want to do this. But I don’t think it’s compatible with embedding.

Because, besides the actual forum itself I’d like to have comment sections below the blogs.

Is it possible to embed a forum under multiple subdomains?
I.e. link the forum to oblio360.com and then have comments for dota.oblio360.com & co?
Based on your previous reply I guess not and I guess I have to go multisite.

So the follow up question: are multisite upgrade supported by the upgrade button?


(Kane York) #98

… Maybe.

IIRC it’s either disabled, or only functions on the first site in the list.


(Quenten) #100

After all these steps , what should we do ? Rebuild ?


(jon r) #101

Additional to

or

setting this up worked for me with

  before_bundle_exec:
    - file:
        path: $home/config/multisite.yml
        contents: |
         subsite_identifier:
           host: database_host_alias
           username: discourse
           password: redacted
           adapter: postgresql
           database: database_name
           pool: 25
           timeout: 5000
           db_id: 2
           host_names:
             - sub.domain.tld

  after_bundle_exec:
    - exec: cd /var/www/discourse && RAILS_DB=subsite_identifier sudo -E -u discourse bundle exec rake db:migrate

as I also ran into the Postgres socket error.
Please note above I have added the database credentials directly to the subsite and not via environmental variables. In the same time I am only migrating a single RAILS_DB and not multisite:.
All has been taken from my pre-Docker bluepill multisite setup whose backups I intend to replay these days.

If you are interested to run Discourse behind jwilder/nginx-proxy, also check out

To be continued.


(Hammad Abbasi) #102

I am planning to implement multi-site feature but i have few questions-- and i would appreciate if someone can answer them.

  1. Does it mean that i can use different domain e.g http://forums.abc.com , http://forums.xyz.com
  2. What About Data Segregation ? Does this mean that both forums will have their own categories and Threads ?

Please confirm. Thanks


(Jeff Atwood) #103

Yes the domains and databases will be completely independent.


(Hammad Abbasi) #104

Many Thanks for reply, I also want to confirm about Plugins or any changes in code-base (in case i need some customization)


(Jeff Atwood) #105

Nope plugins will be shared across all sites in multi-site.


(cpradio) #106

But many of them you can enable/disable via the admin settings independently. Some may not be able to do that though.


(Shri) #107

Quick question - Any ideas what needs to get done for a multisite web_only container WITH LetsEncrypt SSL support for all sites?

Have about 10 sites old and new and setting up a web_only with nginx proxying for each of them seems like the wrong way to go.


(Oleg Bovykin) #108

Hi! I tried to add multisite configuration today, but got strang errors.

I running separate app, postgres and redis containers and without multisite it works fine.
When I rebuild my app container, I got the problem:

I, [2016-07-24T20:13:54.641530 #15]  INFO -- : > cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate'
Failed to report error: Name or service not known 2 Name or service not known subscribe failed, reconnecting in 1 second. Call stack ["/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/connection/hiredis.rb:19:in `connect'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/connection/hiredis.rb:19:in `connect'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:336:in `establish_connection'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:101:in `block in connect'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:293:in `with_reconnect'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:100:in `connect'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:276:in `with_socket_timeout'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:133:in `call_loop'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/subscribe.rb:43:in `subscription'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/subscribe.rb:12:in `subscribe'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:2760:in `_subscription'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:2138:in `block in subscribe'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:58:in `block in synchronize'", "/usr/local/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:58:in `synchronize'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:2137:in `subscribe'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/message_bus-2.0.1/lib/message_bus/backends/redis.rb:304:in `global_subscribe'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/message_bus-2.0.1/lib/message_bus.rb:508:in `global_subscribe_thread'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/message_bus-2.0.1/lib/message_bus.rb:456:in `block in new_subscriber_thread'"]
URGENT: could not translate host name "postgres" to address: Name or service not known
 Failed to initialize site default
URGENT: could not translate host name "postgres" to address: Name or service not known
 Failed to initialize site zav
Failed to report error: Name or service not known 2 Name or service not known subscribe failed, reconnecting in 1 second. Call stack ["/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/connection/hiredis.rb:19:in `connect'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/connection/hiredis.rb:19:in `connect'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:336:in `establish_connection'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:101:in `block in connect'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:293:in `with_reconnect'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:100:in `connect'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:276:in `with_socket_timeout'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:133:in `call_loop'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/subscribe.rb:43:in `subscription'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/subscribe.rb:12:in `subscribe'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:2760:in `_subscription'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:2138:in `block in subscribe'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:58:in `block in synchronize'", "/usr/local/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:58:in `synchronize'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:2137:in `subscribe'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/message_bus-2.0.1/lib/message_bus/backends/redis.rb:304:in `global_subscribe'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/message_bus-2.0.1/lib/message_bus.rb:508:in `global_subscribe_thread'", "/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/message_bus-2.0.1/lib/message_bus.rb:456:in `block in new_subscriber_thread'"]
rake aborted!
Name or service not known
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/connection/hiredis.rb:19:in `connect'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/connection/hiredis.rb:19:in `connect'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:336:in `establish_connection'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:101:in `block in connect'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:293:in `with_reconnect'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:100:in `connect'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:364:in `ensure_connected'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:221:in `block in process'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:306:in `logging'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:220:in `process'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis/client.rb:120:in `call'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:862:in `block in get'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:58:in `block in synchronize'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:58:in `synchronize'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/redis-3.3.0/lib/redis.rb:861:in `get'
/var/www/discourse/lib/discourse_redis.rb:184:in `block (3 levels) in <class:DiscourseRedis>'
/var/www/discourse/lib/discourse_redis.rb:150:in `ignore_readonly'
/var/www/discourse/lib/discourse_redis.rb:184:in `block (2 levels) in <class:DiscourseRedis>'
/var/www/discourse/config/initializers/100-secret_token.rb:6:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.7/lib/active_support/dependencies.rb:268:in `load'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.7/lib/active_support/dependencies.rb:268:in `block in load'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.7/lib/active_support/dependencies.rb:240:in `load_dependency'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.7/lib/active_support/dependencies.rb:268:in `load'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/engine.rb:652:in `block in load_config_initializer'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.7/lib/active_support/notifications.rb:166:in `instrument'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/engine.rb:651:in `load_config_initializer'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/engine.rb:616:in `block (2 levels) in <class:Engine>'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/engine.rb:615:in `each'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/engine.rb:615:in `block in <class:Engine>'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/initializable.rb:30:in `instance_exec'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/initializable.rb:30:in `run'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/initializable.rb:55:in `block in run_initializers'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/initializable.rb:44:in `each'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/initializable.rb:44:in `tsort_each_child'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/initializable.rb:54:in `run_initializers'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/application.rb:352:in `initialize!'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/railtie.rb:194:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/railtie.rb:194:in `method_missing'
/var/www/discourse/config/environment.rb:5:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.7/lib/active_support/dependencies.rb:274:in `require'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.7/lib/active_support/dependencies.rb:274:in `block in require'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.7/lib/active_support/dependencies.rb:240:in `load_dependency'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/activesupport-4.2.7/lib/active_support/dependencies.rb:274:in `require'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/application.rb:328:in `require_environment!'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/railties-4.2.7/lib/rails/application.rb:457:in `block in run_tasks_blocks'
/var/www/discourse/vendor/bundle/ruby/2.3.0/gems/rake-11.2.2/exe/rake:27:in `<top (required)>'
/usr/local/bin/bundle:23:in `load'
/usr/local/bin/bundle:23:in `<main>'
Tasks: TOP => db:migrate => environment
(See full trace by running task with --trace)
I, [2016-07-24T20:14:03.694233 #15]  INFO -- :


FAILED
--------------------
Pups::ExecError: cd /var/www/discourse && su discourse -c 'bundle exec rake db:migrate' failed with return #<Process::Status: pid 705 exit 1>
Location of failure: /pups/lib/pups/exec_command.rb:108:in `spawn'
exec failed with the params {"cd"=>"$home", "hook"=>"bundle_exec", "cmd"=>["su discourse -c 'bundle install --deployment --verbose --without test --without development'", "su discourse -c 'bundle exec rake db:migrate'", "su discourse -c 'bundle exec rake assets:precompile'"]}
c92e5b4f41b55e4e0a4ea8bd4039a33618c54c0efe9a037b470d8a2469a45978
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one

My app.yml

# IMPORTANT: SET A SECRET PASSWORD in Postgres for the Discourse User
# TODO: change SOME_SECRET in this template


templates:
  - "templates/sshd.template.yml"
  - "templates/web.template.yml"
  - "templates/web.ratelimited.template.yml"
expose:
  - "88:80"
  - "2222:22"

# any extra arguments for Docker?
# docker_args:

volumes:
  - volume:
    host: /var/discourse/shared/app
    guest: /shared
  - volume:
    host: /var/discourse/shared/app/log/var-log
    guest: /var/log
  - volume:
    host: /var/discourse/shared/app/bundler-cache
    guest: /var/www/vendor/cache
#Use 'links' key to link containers together, aka use Docker --link flag.
links:
  - link:
    name: postgres
    alias: postgres
  - link:
    name: redis
    alias: redis

params:
  ## Which Git revision should this container use? (default: tests-passed)
  #version: tests-passed

env:
  LANG: ru_RU.UTF-8
  ## TODO: How many concurrent web requests are supported?
  ## With 2GB we recommend 3-4 workers, with 1GB only 2
  ## If you have lots of memory, use one or two workers per logical CPU core
  UNICORN_WORKERS: 3

  ## TODO: configure connectivity to the databases
  DISCOURSE_DB_SOCKET: ''
  #DISCOURSE_DB_USERNAME: discourse
  DISCOURSE_DB_PASSWORD: SOME_SECRET
  DISCOURSE_DB_HOST: postgres
  DISCOURSE_REDIS_HOST: redis
  ##
  ## TODO: List of comma delimited emails that will be made admin and developer
  ## on initial signup example 'user1@example.com,user2@example.com'
  DISCOURSE_DEVELOPER_EMAILS: 'oleg.bovykin@gmail.com'
  ##
  ## TODO: The domain name this Discourse instance will respond to
  DISCOURSE_HOSTNAME: 'hive.redde.ru'
  ##
  ## TODO: The mailserver this Discourse instance will use
  DISCOURSE_SMTP_ADDRESS: smtp.sparkpostmail.com         # (mandatory)
  DISCOURSE_SMTP_PORT: 587                        # (optional)
  DISCOURSE_SMTP_USER_NAME: SMTP_Injection      # (optional)
  DISCOURSE_SMTP_PASSWORD: ololo               # (optional)
  ##
  ## The CDN address for this Discourse instance (configured to pull)
  #DISCOURSE_CDN_URL: //discourse-cdn.example.com
  RAILS_ENV: production

## The docker manager plugin allows you to one-click upgrade Discouse
## http://discourse.example.com/admin/docker
hooks:
  after_code:
    - exec:
        cd: $home/plugins
        cmd:
          - git clone https://github.com/discourse/docker_manager.git
  before_bundle_exec:
    - file:
        path: $home/config/multisite.yml
        contents: |
         zav:
           adapter: postgresql
           database: zav_discourse
           password: SOME_SECRET
           pool: 25
           timeout: 5000
           db_id: 2
           host: postgres
           host_names:
             - zav3d.ru
  after_bundle_exec:
    - exec: cd /var/www/discourse && sudo -E -u discourse bundle exec rake multisite:migrate

## Remember, this is YAML syntax - you can only have one block with a name
run:
  - exec: echo "Beginning of custom commands"

  ## If you want to configure password login for root, uncomment and change:
  ## Use only one of the following lines:
  #- exec: /usr/sbin/usermod -p 'PASSWORD_HASH' root
  #- exec: /usr/sbin/usermod -p "$(mkpasswd -m sha-256 'RAW_PASSWORD')" root

  ## If you want to authorized additional users, uncomment and change:
  #- exec: ssh-import-id username
  #- exec: ssh-import-id anotherusername

  - exec: echo "End of custom commands"
  - exec: awk -F\# '{print $1;}' ~/.ssh/authorized_keys | awk 'BEGIN { print "Authorized SSH keys for this container:"; } NF>=2 {print $NF;}'

It looks like it dont see postgres and redis containers via links. Without multisite all works fine.

How to deal with this problem?

UPDATE: Tried to revert to single discourse installation, but cant rebuild app. Same error.
UPDATE2 Figured out what happend, I think I messed up with yaml syntax. After fixing and rebuilding got totally empty site without working emails. Created user, activated via admin and run restore from backup.


(Hammad Abbasi) #109

Is multi-site setup still broken ? I tried following the steps as described in the post but got following error. Any help would be appreciated. Thanks

Pups::ExecError: cd /var/www/discourse && su discourse -c ‘bundle exec rake assets:precompile’ failed with return #<Process::Status: pid 2433 exit 1>
Location of failure: /pups/lib/pups/exec_command.rb:108:in `spawn’
exec failed with the params {“cd”=>"$home", “hook”=>“bundle_exec”, “cmd”=>[“su discourse -c ‘bundle install --deployment --verbose --without test --without development’”, “su discourse -c ‘bundle exec rake db:migrate’”, “su discourse -c ‘bundle exec rake assets:precompile’”]}
f29f5f8be149651b3fc12de42fe8d9653e1cc97de2b97526a69ae929a3024076
** FAILED TO BOOTSTRAP ** please scroll up and look for earlier error messages, there may be more than one

P.S there are no other errors.

EDIT: I managed to make it working but now both domains are having same site-settings? What do i need to configure now ?