diff --git a/config/nginx.sample.conf b/config/nginx.sample.conf index ee5efabec..eafbf4a51 100644 --- a/config/nginx.sample.conf +++ b/config/nginx.sample.conf @@ -17,6 +17,7 @@ server { sendfile on; keepalive_timeout 65; + client_max_body_size 2m; location / { root /home/discourse/discourse/public; diff --git a/docs/INSTALL-alternatives.md b/docs/INSTALL-alternatives.md new file mode 100644 index 000000000..9c2622eee --- /dev/null +++ b/docs/INSTALL-alternatives.md @@ -0,0 +1,82 @@ +# Alternative Install Options + +Here lie some alternative installation options for Discourse. They're not the +recommended way of doing things, hence they're a bit out of the way. + +Oh, and dragons. Lots of dragons. + +## Web Server Alternative: apache2 + +If you instead want to use apache2 to serve the static pages: + + # Run these commands as your normal login (e.g. "michael") + # If you don't have apache2 yet + sudo apt-get install apache2 + + # Edit your site details in a new apache2 config file + sudo vim /etc/apache2/sites-available/your-domain.com + + # Put these info inside and change accordingly + + + ServerName your-domain.com + ServerAlias www.your-domain.com + + DocumentRoot /srv/www/apps/discourse/public + + + AllowOverride all + Options -MultiViews + + + # Custom log file locations + ErrorLog /srv/www/apps/discourse/log/error.log + CustomLog /srv/www/apps/discourse/access.log combined + + + # Install the Passenger Phusion gem and run the install + gem install passenger + passenger-install-apache2-module + + # Next, we "create" a new apache2 module, passenger + sudo vim /etc/apache2/mods-available/passenger.load + + # Inside paste (change the user accodingly) + LoadModule passenger_module /home/YOUR-USER/.rvm/gems/ruby-2.0.0-p0/gems/passenger-4.0.2/libout/apache2/mod_passenger.so + + # Now the passenger module configuration + sudo vim /etc/apache2/mods-available/passenger.conf + + # Inside, paste (change the user accodingly) + PassengerRoot /home/YOUR-USER/.rvm/gems/ruby-2.0.0-p0/gems/passenger-4.0.2 + PassengerDefaultRuby /home/YOUR-USER/.rvm/wrappers/ruby-2.0.0-p0/ruby + + # Now activate them all + + sudo a2ensite your-domain.com + sudo a2enmod passenger + sudo service apache2 reload + sudo service apache2 restart + +If you get any errors starting or reloading apache, please check the paths above - Ruby 2.0 should be there if you are using RVM, but it could get tricky. + +## RVM Alternative: Systemwide installation + +Taken from http://rvm.io/, the commands below installs RVM and users in the 'rvm' group have access to modify state: + + # Run these commands as your normal login (e.g. "michael") \curl -s -S -L https://get.rvm.io | sudo bash -s stable + sudo adduser $USER rvm + newgrp rvm + . /etc/profile.d/rvm.sh + rvm requirements + + # Build and install ruby + rvm install 2.0.0 + gem install bundler + +When creating the `discourse` user, add him/her/it to the RVM group: + + # Run these commands as your normal login (e.g. "michael") + sudo adduser discourse rvm + +RVM will be located in `/usr/local/rvm` directory instead of `/home/discourse/.rvm`, so update the crontab line respectively. diff --git a/docs/INSTALL-ubuntu.md b/docs/INSTALL-ubuntu.md index 40e9544b2..4af47b899 100644 --- a/docs/INSTALL-ubuntu.md +++ b/docs/INSTALL-ubuntu.md @@ -2,10 +2,16 @@ ## What kind of hardware do you have? -- We *strongly* recommend 2GB of memory minimum if you don't want to deal with swap partitions during the install. -- We recommend at least a dual core CPU. +- Recommended minimum configuration is: + - 2GiB of RAM + - 2GiB of swap + - 2 processor cores +- With 2GB of memory and dual cores, you can run two instances of the thin + server (`NUM_WEBS=2`) -1 GB of memory and a single core CPU are the minimums for a steady state, running Discourse forum -- but it's simpler to just throw a bit more hardware at the problem if you can, particularly during the install. +1 GiB of memory, 3GiB of swap and a single core CPU are the minimums for a +steady state, running Discourse forum -- but it's simpler to just throw a bit +more hardware at the problem if you can, particularly during the install. ## Install Ubuntu Server 12.04 LTS with the package groups: @@ -51,7 +57,13 @@ Install necessary packages: sudo apt-get update sudo apt-get install redis-server -## Web Server Option: nginx +## Web Server: nginx + +nginx is used for: + +* reverse proxy (i.e. load balancer) +* static asset serving (since you don't want to do that from ruby) +* anonymous user cache At Discourse, we recommend the latest version of nginx (we like the new and shiny). To install on Ubuntu: @@ -73,83 +85,11 @@ shiny). To install on Ubuntu: # install nginx sudo apt-get update && sudo apt-get -y install nginx -## Web Server Option: apache2 - -If you instead want to use apache2 to serve the static pages: - - # Run these commands as your normal login (e.g. "michael") - # If you don't have apache2 yet - sudo apt-get install apache2 - - # Edit your site details in a new apache2 config file - sudo vim /etc/apache2/sites-available/your-domain.com - - # Put these info inside and change accordingly - - - ServerName your-domain.com - ServerAlias www.your-domain.com - - DocumentRoot /srv/www/apps/discourse/public - - - AllowOverride all - Options -MultiViews - - - # Custom log file locations - ErrorLog /srv/www/apps/discourse/log/error.log - CustomLog /srv/www/apps/discourse/access.log combined - - - # Install the Passenger Phusion gem and run the install - gem install passenger - passenger-install-apache2-module - - # Next, we "create" a new apache2 module, passenger - sudo vim /etc/apache2/mods-available/passenger.load - - # Inside paste (change the user accodingly) - LoadModule passenger_module /home/YOUR-USER/.rvm/gems/ruby-2.0.0-p0/gems/passenger-4.0.2/libout/apache2/mod_passenger.so - - # Now the passenger module configuration - sudo vim /etc/apache2/mods-available/passenger.conf - - # Inside, paste (change the user accodingly) - PassengerRoot /home/YOUR-USER/.rvm/gems/ruby-2.0.0-p0/gems/passenger-4.0.2 - PassengerDefaultRuby /home/YOUR-USER/.rvm/wrappers/ruby-2.0.0-p0/ruby - - # Now activate them all - - sudo a2ensite your-domain.com - sudo a2enmod passenger - sudo service apache2 reload - sudo service apache2 restart - -If you get any errors starting or reloading apache, please check the paths above - Ruby 2.0 should be there if you are using RVM, but it could get tricky. - ## Install Ruby with RVM -### RVM Option: Systemwide installation +### RVM : Single-user installation -Taken from http://rvm.io/, the commands below installs RVM and users in the 'rvm' group have access to modify state: - - # Run these commands as your normal login (e.g. "michael") - \curl -s -S -L https://get.rvm.io | sudo bash -s stable - sudo adduser $USER rvm - newgrp rvm - . /etc/profile.d/rvm.sh - rvm requirements - - # Build and install ruby - rvm install 2.0.0 - gem install bundler - -### RVM Option: Single-user installation - -Another sensible option (especially if only one Ruby app is on the machine) is -to install RVM isolated to a user's environment. Further instructions are -below. +We recommend installing RVM isolated to a single user's environment. ## Discourse setup @@ -157,9 +97,6 @@ Create Discourse user: # Run these commands as your normal login (e.g. "michael") sudo adduser --shell /bin/bash discourse - # If this fails, it's because you're doing the RVM single-user install. - # In that case, you could just not run it if errors make you squirrely - sudo adduser discourse rvm Give Postgres database rights to the `discourse` user: @@ -172,7 +109,7 @@ Change to the 'discourse' user: # Run this command as your normal login (e.g. "michael"), further commands should be run as 'discourse' sudo su - discourse -Install RVM if doing a single-user RVM installation: +Install RVM # As 'discourse' # Install RVM @@ -304,7 +241,7 @@ Configure Bluepill: Start Discourse: # Run these commands as the discourse user - RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ROOT=~/discourse RAILS_ENV=production NUM_WEBS=4 bluepill --no-privileged -c ~/.bluepill load ~/discourse/config/discourse.pill + RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ROOT=~/discourse RAILS_ENV=production NUM_WEBS=2 bluepill --no-privileged -c ~/.bluepill load ~/discourse/config/discourse.pill Add the Bluepill startup to crontab. @@ -313,10 +250,7 @@ Add the Bluepill startup to crontab. Add the following lines: - @reboot RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ROOT=~/discourse RAILS_ENV=production NUM_WEBS=4 /home/discourse/.rvm/bin/bootup_bluepill --no-privileged -c ~/.bluepill load ~/discourse/config/discourse.pill - - -Note: in case of RVM system-wide installation RVM will be located in `/usr/local/rvm` directory instead of `/home/discourse/.rvm`, so update the line above respectively. + @reboot RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ROOT=~/discourse RAILS_ENV=production NUM_WEBS=2 /home/discourse/.rvm/bin/bootup_bluepill --no-privileged -c ~/.bluepill load ~/discourse/config/discourse.pill ## Log rotation setup @@ -360,6 +294,11 @@ The corresponding site setting is: # Run these commands as the discourse user bluepill stop + bluepill quit + # Back up your install + DATESTAMP=$(TZ=UTC date +%F-%T) + pg_dump --no-owner --clean discourse_prod | gzip -c > ~/discourse-db-$DATESTAMP.sql.gz + tar cfz ~/discourse-dir-$DATESTAMP.tar.gz -C ~ discourse # Pull down the latest release cd ~/discourse git checkout master @@ -367,9 +306,65 @@ The corresponding site setting is: git fetch --tags # To run on the latest version instead of bleeding-edge: #git checkout latest-release + # + # Follow the section below titled: + # "Check sample configuration files for new settings" + # bundle install --without test --deployment RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ENV=production rake db:migrate RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ENV=production rake assets:precompile - bluepill start + # restart bluepill + crontab -l + # Here, run the command to start bluepill. + # Get it from the crontab output above. Note that if bluepill *itself* needs to be restarted, it must be killed with `bluepill quit` and restarted with the same command that's in crontab + +### Check sample configuration files for new settings + +Check the sample configuration files provided in the repo with the ones being used for additional recommended settings and merge those in: + + # Run these commands as the discourse user + cd ~/discourse + diff -u config/discourse.pill.sample config/discourse.pill + diff -u config/nginx.sample.conf /etc/nginx/conf.d/discourse.conf + diff -u config/environments/production.rb.sample config/environments/production.rb + +#### Example 1 + + $ diff -u config/discourse.pill.sample config/discourse.pill + --- config/discourse.pill.sample 2013-07-15 17:38:06.501507001 +0000 + +++ config/discourse.pill 2013-07-05 06:38:27.133506896 +0000 + @@ -46,7 +46,7 @@ + + app.working_dir = rails_root + sockdir = "#{rails_root}/tmp/sockets" + - File.directory? sockdir or FileUtils.mkdir_p sockdir + + File.directory? sockdir or Dir.mkdir sockdir + num_webs.times do |i| + app.process("thin-#{i}") do |process| + +This change reflects us switching to using `FileUtils.mkdir_p` instead of `Dir.mkdir`. + +#### Example 2 + + $ diff -u config/nginx.sample.conf /etc/nginx/conf.d/discourse.conf + --- config/nginx.sample.conf 2013-07-15 17:38:06.521507000 +0000 + +++ /etc/nginx/conf.d/discourse.conf 2013-07-15 17:52:46.649507024 +0000 + @@ -12,17 +12,18 @@ + gzip_min_length 1000; + gzip_types application/json text/css application/x-javascript; + + - server_name enter.your.web.hostname.here; + + server_name webtier.discourse.org; + + sendfile on; + + keepalive_timeout 65; + - client_max_body_size 2m; + location / { + root /home/discourse/discourse/public; + +This change reflects a change in placeholder information plus (importantly) +adding the `client_max_body_size 2m;` directive to the nginx.conf. This change +should also be made to your production file. diff --git a/docs/MIGRATION.md b/docs/MIGRATION.md new file mode 100644 index 000000000..b2ad9f210 --- /dev/null +++ b/docs/MIGRATION.md @@ -0,0 +1,72 @@ +# Discourse Migration Guide + +## Install new server + +Complete a fresh install of Discourse on the new server, following the official guide, except for the initial database population (rake db:migrate). + +## Review old server + +On old server, run `git status` and review changes to the tree. For example: + + # On branch master + # Changes not staged for commit: + # (use "git add ..." to update what will be committed) + # (use "git checkout -- ..." to discard changes in working directory) + # + # modified: app/assets/javascripts/external/Markdown.Editor.js + # modified: app/views/layouts/application.html.erb + # modified: config/application.rb + # + # Untracked files: + # (use "git add ..." to include in what will be committed) + # + # app/views/layouts/application.html.erb.bitnami + # config/environments/production.rb + # log/clockworkd.clock.output + # log/clockworkd.clock.pid + # log/sidekiq.pid + # vendor/gems/active_model_serializers/ + # vendor/gems/fast_blank/ + # vendor/gems/message_bus/ + # vendor/gems/redis-rack-cache/ + # vendor/gems/sprockets/ + # vendor/gems/vestal_versions/ + +### Review for changes + +Review each of the changed files for changes that need to be manually moved over + +* Ignore all files under vendor/gems +* Ignore files under log/ + +Check your config/environments/production.rb, config/discourse.pill, +config/database.yml (as per the upgrade instructions) + +## Move DB + +Take DB dump with: + + pg_dump --no-owner -U user_name -W database_name + +Copy it over to the new server + +Run as discourse user: + +* createdb discourse_prod +* psql discourse_prod + * \i discourse_dump_from_old_server.sql + +On oldserver: + +* rsync -avz -e ssh public newserver:public + + bundle install --without test --deployment + RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ENV=production rake db:migrate + RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ENV=production rake assets:precompile + RUBY_GC_MALLOC_LIMIT=90000000 RAILS_ENV=production rake posts:rebake + +Are you just testing your migration? Disable outgoing email by changing +`config/environments/production.rb` and adding the following below the mail +configuration: + + config.action_mailer.perform_deliveries = false diff --git a/docs/TROUBLESHOOTING-prod.md b/docs/TROUBLESHOOTING-prod.md index 463ce3c6f..65a48f768 100644 --- a/docs/TROUBLESHOOTING-prod.md +++ b/docs/TROUBLESHOOTING-prod.md @@ -3,56 +3,55 @@ Are you having trouble setting up Discourse? Here are some basic things to check before reaching out to the community for help: - 1. Are you running Ruby 1.9.3 or later? Discourse is designed for Ruby 1.9.3 or later. You can check your version by -typing `ruby -v` and checking the response. +typing `ruby -v` (as the discourse user) and checking the response for +something like: + + `ruby 2.0.0p195 (2013-05-14 revision 40734) [x86_64-linux]` -2. Are you on Postgres 9.1 or later with HSTORE enabled? +1. Are you on Postgres 9.1 or later with HSTORE enabled? - You can check your postgres version by typing `psql --version`. To see if hstore is - installed, open a session to postgres and type `\dx` and see if hstore is listed. + You can check your postgres version by typing `psql --version`. To see if +hstore is installed, open a session to postgres and type `\dx` and see if +hstore is listed. -3. Have you run `bundle install`? +1. Have you run `bundle install`? - We frequently update our dependencies to newer versions. It is a good idea to run - `bundle install` every time you check out Discourse, especially if it's been a while. + We frequently update our dependencies to newer versions. It is a good idea +to run `bundle install` every time you check out Discourse, especially if it's +been a while. -4. Did you run `bundle update`? +1. Did you run `bundle update`? - Don't. Running `bundle update` will download gem versions that we haven't tested with. - The Gemfile.lock has the gem versions that Discourse currently uses, so `bundle install` - will work. If you ran update, then you should uninstall the gems, run - `git checkout -- Gemfile.lock` and then run `bundle install`. + Don't. Running `bundle update` will download gem versions that we haven't +tested with. The Gemfile.lock has the gem versions that Discourse currently +uses, so `bundle install` will work. If you ran update, then you should +uninstall the gems, run `git checkout -- Gemfile.lock` and then run `bundle +install`. -5. Have you migrated your database? +1. Have you migrated your database? - Our schema changes fairly frequently. After checking out the source code, you should - run `rake db:migrate` + Our schema changes fairly frequently. After checking out the source code, +you should run `rake db:migrate`. +1. Do the tests pass? -6. Have you added the seed data? + If you are having other problems, it's useful to know if the test suite +passes. You can run it by first using `rake db:test:prepare` and then `rake +spec`. If you experience any failures, that's a bad sign! Our master branch +should *always* pass every test. - We depend on some basic seed data being present in the database. You should run - `rake db:seed_fu` to keep your database in sync. +1. Have you updated host_names in your database.yml? - -7. Do the tests pass? - - If you are having other problems, it's useful to know if the test suite passes. You - can run it by first using `rake db:test:prepare` and then `rake spec`. If you - experience any failures, that's a bad sign! Our master branch should *always* pass - every test. - -8. Have you updated host_names in your database.yml? - - If links in emails have localhost in them, then you are still using the default host_names - value in database.yml. Update it to use your site's host name(s). + If links in emails have localhost in them, then you are still using the +default `host_names` value in database.yml. Update it to use your site's host +name(s). -9. Are you having problems bundling: +1. Are you having problems bundling: ``` ArgumentError: invalid byte sequence in US-ASCII @@ -75,3 +74,13 @@ Encoding.default_external = Encoding::UTF_8 Encoding.default_internal = Encoding::UTF_8 end ``` + +--- + +Check your ~/discourse/log/production.log file if you are getting HTTP 500 +errors. + +Some common situations: + +**Problem:** `ActiveRecord::StatementInvalid (PG::Error: ERROR: column X does not exist` +**Solution**: run `db:migrate` task to apply migrations to the database