Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Digital Ocean Discourse production install with LAMP (using Apache)
#create & deploy lamp droplet
#login via ssh as root
#initial setup (ref: http://library.linode.com/getting-started#sph_logging-in-for-the-first-time)
# update /etc/hosts (to "thalassophobia.surrealroad.com")
nano /etc/hosts
#
127.0.0.1 localhost.localdomain localhost
12.34.56.78 thalassophobia.surrealroad.com thalassophobia
# set timezone to GMT
dpkg-reconfigure tzdata
#initial security (ref: http://library.linode.com/securing-your-server)
# create local admin user "jack"
adduser jack
usermod -a -G sudo jack
# use ssh key/pair authentication
exit
#from local Mac terminal:
ssh-keygen
scp ~/.ssh/id_rsa.pub jack@12.34.56.78:
# ssh back into digital ocean:
mkdir .ssh
mv id_rsa.pub .ssh/authorized_keys
chown -R jack:jack .ssh
chmod 700 .ssh
chmod 600 .ssh/authorized_keys
# exit ssh and connect again to verify password is not needed
# disable root login and require ssh key/pair
sudo nano /etc/ssh/sshd_config
PasswordAuthentication no
PermitRootLogin no
#
sudo restart ssh
# create firewall
sudo nano /etc/iptables.firewall.rules
*filter
# Allow all loopback (lo0) traffic and drop all traffic to 127/8 that doesn't use lo0
-A INPUT -i lo -j ACCEPT
-A INPUT -d 127.0.0.0/8 -j REJECT
# Accept all established inbound connections
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow all outbound traffic - you can modify this to only allow certain traffic
-A OUTPUT -j ACCEPT
# Allow HTTP and HTTPS connections from anywhere (the normal ports for websites and SSL).
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
# allow ruby thin server connections on port 3000 through 3100
-A INPUT -p tcp --dport 3000:3002 -j ACCEPT
# Allow SSH connections
#
# The -dport number should be the same port number you set in sshd_config
#
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT
# Allow ping
-A INPUT -p icmp -j ACCEPT
# Log iptables denied calls
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
# Drop all other inbound - default deny unless explicitly allowed policy
-A INPUT -j DROP
-A FORWARD -j DROP
COMMIT
#
# activate firewall settings
sudo iptables-restore < /etc/iptables.firewall.rules
# verify
sudo iptables -L
# activate on startup
sudo nano /etc/network/if-pre-up.d/firewall
#!/bin/sh
/sbin/iptables-restore < /etc/iptables.firewall.rules
#
sudo chmod +x /etc/network/if-pre-up.d/firewall
# install fail2ban
sudo apt-get install fail2ban
# TODO: IPV6 support (not currently supported by digital ocean)
#install system software
# get everything up-to-date
sudo apt-get update
sudo apt-get upgrade
# don't make any changes to grub menu if prompted
# install git
sudo apt-get install build-essential git libpq-dev
# install postgresql & redis
sudo apt-get install postgresql-9.1 postgresql-contrib-9.1 redis-server
# configure postgresql database
sudo nano /etc/postgresql/9.1/main/pg_hba.conf
host all all 127.0.0.1/32 trust
host all all ::1/128 trust
#
sudo /etc/init.d/postgresql restart
# set postgresql root password
passwd postgres
su - postgres
psql -d template1 -c "ALTER USER postgres WITH PASSWORD 'changeme';"
# create discourse database role
createuser discourse --pwprompt
# (make it a superuser when prompted)
su - jack
# install ruby on rails/RVM
sudo apt-get --no-install-recommends install build-essential openssl libreadline6 libreadline6-dev curl git-core zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev libgdbm-dev ncurses-dev automake libtool bison subversion pkg-config libffi-dev
\curl -L https://get.rvm.io | bash -s stable --ruby
# activate rvm
source /home/jack/.rvm/scripts/rvm
# or logout and back in
# install ruby gems
rvm rubygems current
# if there's a verification error: rvm rubygems current --verify-downloads 1
gem install thin
# install sendmail
sudo apt-get install sendmail
# install discourse
cd /srv/www/mysite/
# or wherever you want to install it
git clone git://github.com/discourse/discourse.git
bundle install
# configure discourse
cp config/database.yml.sample config/database.yml
cp config/redis.yml.sample config/redis.yml
nano config/database.yml
username: discourse
password: discourserolepassword
host: localhost
host_names:
- "mysite.com"
# make changes for each instance you want to configure, e.g. production and development
#
nano config/environments/development.rb
config.action_mailer.delivery_method = :sendmail
config.action_mailer.sendmail_settings = {arguments: '-i'}
#
rake db:create db:migrate db:seed_fu
redis-cli flushall
# start discourse on port 3000
# best to open a new shell here
cd /srv/www/mysite/discourse
thin start
# and open another shell
cd /srv/www/mysite/discourse
sidekiq
# browse to http://12.34.56.78:3000
# register an account
# activate the account from the email
# stop thin with ctrl-c
# make your user admin
bundle exec rails c
u = User.first
u.admin = true
u.save
quit
thin start
# verify you have admin privileges when you log in
# set up production environment
# generate secret token
rake secret
# set secret token
nano config/initializers/secret_token.rb
Discourse::Application.config.secret_token = "1234567etc"
# compile assets
bundle exec rake assets:clean
bundle exec rake assets:precompile
# configure foreman for production environment
# ref: http://michaelvanrooijen.com/articles/2011/06/08-managing-and-monitoring-your-ruby-application-with-foreman-and-upstart/
gem install foreman
nano .env
PORT=3000
RAILS_ENV=production
RUBY_GC_MALLOC_LIMIT=90000000
# start foreman with 3 thin servers
foreman start -c web=3,sidekiq=1,clockwork=1
# make discouse a service, which will run as user jack
# TODO: get it to run as www-data
rvmsudo foreman export upstart /etc/init -a discourse -c web=3,sidekiq=1,clockwork=1 -u jack
# start discourse
sudo start discourse
# enable apache proxy
mkdir /srv/www/mysite/logs
sudo a2enmod rewrite proxy expires headers proxy_balancer proxy_http
sudo nano /etc/apache2/sites-available/mysite
<VirtualHost *:80>
ServerName forums.mysite.com
DocumentRoot /srv/www/mysite/discourse/public
CustomLog /srv/www/mysite/logs/access.log common
ErrorLog /srv/www/mysite/logs/error.log
RewriteEngine On
# http://stackoverflow.com/questions/7870408/in-rails-should-i-enable-serve-static-assets
<Proxy balancer://thinservers>
BalancerMember http://127.0.0.1:3000
BalancerMember http://127.0.0.1:3001
BalancerMember http://127.0.0.1:3002
</Proxy>
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
# Redirect all non-static requests to thin
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://thinservers%{REQUEST_URI} [P,QSA,L]
ProxyPreserveHost on
</VirtualHost>
#
sudo a2ensite mysite
sudo /usr/sbin/apache2ctl configtest
sudo service apache2 restart
# access discourse via http://mysite
# CODA: UPDATING DISCOURSE
sudo stop discourse
git stash
git pull
git stash pop
# resolve conflicts by editing conflicted files if need be
bundle install
rake db:migrate db:seed_fu db:test:prepare
bundle exec rake assets:clean
bundle exec rake assets:precompile
sudo start discourse
@surrealroad

This comment has been minimized.

Copy link
Owner Author

@surrealroad surrealroad commented Mar 22, 2013

Updated to use garbage collection as per http://meta.discourse.org/t/tuning-ruby-and-rails-for-discourse/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment