After being acquired by Google, EtherPad was opensourced. Being it the kickass thing it is, I got itching with the *need* to have my own etherpad instance running right away.
As I found out, scratching that itch was actually fast: it took me ~3 or so hours, and that includes troubleshooting and gathering bits of info from all around. With a step-by-step how-to it’ll probably take you a lot less than that!
The machine was naraka.pauleira.com, running CentOS 5.3. I used YUM to install most of the prerequisites from RPM repositories, but you’ll probably be fine if you follow similar steps with APT or while installing from source packages. Probably! ;)
The machine serves http://pauleira.com, and I got EtherPad to answer on http://pauleira.com:9000 and https://pauleira.com:9001. EtherPad Pro account’s subdomains are created as subdomains.pauleira.com and are likewise available at http://subdomain.pauleira.com:9000 and https://subdomain.pauleira.com:9001.
Let’s get started!
Create the etherpad user
adduser -r -m etherpad
Set the DNS for *.yourdomain.com
For my pauleira.com domain, I just added a * A record in the DNS pointing to the machine’s IP address. That’ll catch everything!.pauleira.com! If that gets you puzzled, check wikipedia’s entry on the Wildcard DNS record for a gentle explanation.
Java
On CentOS this is little bit more convoluted than it should. Still, just follow the instructions on http://wiki.centos.org/HowTos/JavaOnCentOS and you should reach the other side of the maze safe and sound:
# java -version java version "1.6.0_11" Java(TM) SE Runtime Environment (build 1.6.0_11-b03) Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode)
Scala
Got it from here.
# su - etherpad # wget http://www.scala-lang.org/downloads/distrib/files/scala-2.7.7.final.tgz # tar xfz scala-2.7.7.final.tgz
This will place your scala on
/home/etherpad/scala-2.7.7.final/
We’ll get back to that later on.
MySQL
# yum install mysql-server
and we need mysql to run, so:
# service mysqld start
If you never launched the mysqld before, it’ll warn you about the need to set a password for the root account. I suggest you heed the warnings and do so!
Now is also a good time to add mysql as a service, so you don’t have to enable it manually every your machine restarts.
# chkconfig mysqld on
Now, to install some prereqs we’ll need to make some additional repositories available to YUM. If you don’t have them configured yet, don’t worry, just follow the well-trodden path explained on each of these repositories’ links.
We need:
# yum install mysql-connector-java
which is provided by the jpackage repository.
IPTABLES
We’ll have EtherPad listen for
- HTTP on port 9000
- HTTPS on port 9001
So we need those ports open in the machine’s firewall.
Check if iptables is running. As user root:
# service iptables status
If it is, then save the current rules
# service iptables save
Add the following rules before the COMMIT line in /etc/sysconfig/iptables
-A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 9000 -j ACCEPT -A RH-Firewall-1-INPUT -p tcp -m state --state NEW -m tcp --dport 9001 -j ACCEPT
And then restart it:
# service iptables restart
Mercurial .. or Git
You can get EtherPad from from the offical repository, on Google Code, where it uses Mercurial, but if you already have git and don’t want to install mercurial just for that, I’ve got a mirror you can use.
Both Git and Mercurial are provided by DAG or RPMFORGE.
Once you get one of these going, just issue
# yum install mercurial
or
# yum install git
We’re now done with the prereqs, and it’s about time we dive in the dough!
EtherPad
I won’t digress about how cool EtherPad is. If you’re following this I suppose you’ve found that out already! :) After the acquisition by Google, EtherPad’s source code was (fittingly) hosted on Google Code.
This is where we’ll get it: EtherPad Open Source Release, the official repository, by the EtherPad.com guys.
To check it out, with mercurial:
# su - etherpad # hg clone https://etherpad.googlecode.com/hg/ etherpad
These check the repository’s code into etherpad’s homedir.
NOTE: for this tutorial we’ll leave the directory hierarchy as it is. However, should you ever move “/home/etherpad/etherpad/trunk/etherpad”, somewhere else, make sure you take “/home/etherpad/etherpad/trunk/infrastructure” there too, maintaining both in the same hierarchy level. You need both to compile EtherPad!
sslkeystore
Required for HTTPS. I used keytool as below. It should be obvious that STOREPASS_CHANGEME and KEYPASS_CHANGEME are to be replaced with some good and strong passwords, as usual…
# su - etherpad # cd etherpad/trunk/etherpad/data/appjet # keytool -genkey -alias appjet -storepass STOREPASS_CHANGEME -keypass KEYPASS_CHANGEME -keyalg RSA -keystore sslkeystore
To know about what’s stored in a keystore file, use
# keytool -list -v -keystore sslkeystore
Now everything is in place, and we can configure our Etherpad instance.
Quick introduction to diff files, as used here
diff -u /tmp/before /tmp/after --- /tmp/before 2009-12-23 20:37:05.000000000 -0200 +++ /tmp/after 2009-12-23 20:37:40.000000000 -0200 @@ -1,5 +1,5 @@ not changed not changed not changed not changed -this line will be removed -this line will be removed too +this line was added not changed not changed +this line was added in the end of the file
Make sure you understand the diff above before proceeding.
Really.
Ok, let’s get to work:
./etc/etherpad.localdev-default.properties
Copy the sample config file
# su - etherpad # cd etherpad/trunk/etherpad # cp etc/etherpad.localdev-default.properties data/etherpad.local.properties
And make the following changes
--- etc/etherpad.localdev-default.properties 2009-12-21 02:15:03.000000000 -0200 +++ data/etherpad.local.properties 2009-12-23 19:25:18.000000000 -0200 @@ -1,14 +1,16 @@ ajstdlibHome = ../infrastructure/framework-src/modules appjetHome = ./data/appjet -devMode = true -etherpad.adminPass = password +devMode = false +etherpad.adminPass = ADMINPASS_CHANGEME +smtpServer = localhost:25 etherpad.fakeProduction = false -etherpad.isProduction = false +etherpad.isProduction = true etherpad.SQL_JDBC_DRIVER = com.mysql.jdbc.Driver etherpad.SQL_JDBC_URL = jdbc:mysql://localhost:3306/etherpad -etherpad.SQL_PASSWORD = password +etherpad.SQL_PASSWORD = MYSQLPASS_CHANGEME etherpad.SQL_USERNAME = etherpad -listen = 9000 +listen = 0.0.0.0:9000 +listenSecure = 0.0.0.0:9001 logDir = ./data/logs modulePath = ./src transportPrefix = /comet +sslKeyPassword = KEYPASS_CHANGEME +sslKeyStore = ./data/appjet/sslkeystore +sslStorePassword = STOREPASS_CHANGEME
Pay attention to the *_CHANGEME! :)
NOTE: These settings will get EtherPad to send emails by connecting to a mail transfer agent listening on localhost:25. If you need different settings, check this.
And now a a number of scattered changes:
./bin/setup-mysql-db.sh
--- ./bin/setup-mysql-db.sh.orig 2009-12-23 20:59:15.000000000 -0200
+++ ./bin/setup-mysql-db.sh 2009-12-23 20:59:31.000000000 -0200
@@ -25,6 +25,6 @@
echo "create database ${db};" | ${mysql} -u root
echo "Granting priviliges..."
-echo "grant all privileges on ${db}.* to 'etherpad'@'localhost' identified by 'password';" | ${mysql} -u root
+echo "grant all privileges on ${db}.* to 'etherpad'@'localhost' identified by 'MYSQLPASS_CHANGEME';" | ${mysql} -u root
echo "Success"
./src/main.js
--- ./src/main.js.orig 2009-12-23 14:31:05.000000000 -0200
+++ ./src/main.js 2009-12-23 14:31:54.000000000 -0200
@@ -269,7 +269,7 @@
}
// redirect to etherpad.com
- var newurl = "http://etherpad.com"+request.path;
+ var newurl = "http://YOURDOMAIN_CHANGEME.com"+request.path;
if (request.query) { newurl += "?"+request.query; }
response.redirect(newurl);
}
./src/templates/pro/admin/admin-template.ejs
--- ./src/templates/pro/admin/admin-template.ejs.orig 2009-12-23 15:40:15.000000000 -0200
+++ ./src/templates/pro/admin/admin-template.ejs 2009-12-23 15:40:27.000000000 -0200
@@ -16,11 +16,9 @@
<div class="fpcontent">
<table id="admin-layout-table">
<tr>
- <% if (validLicense) { %>
<td width="1%" id="admin-leftnav">
<%= renderAdminLeftNav() %>
</td>
- <% } %>
<td width="99%" id="admin-right">
<%= getAdminContent() %>
</td>
./src/templates/framed/framedheader-pro.ejs
--- ./src/templates/framed/framedheader-pro.ejs.orig 2009-12-23 14:39:11.000000000 -0200
+++ ./src/templates/framed/framedheader-pro.ejs 2009-12-23 14:39:37.000000000 -0200
@@ -64,10 +64,8 @@
<div id="pro-topnav">
<div id="pro-topnav-inner">
- <% if (validLicense && account) { %>
<%= renderProTopNav() %>
<%= helpers.clearFloats() %>
- <% } %>
</div>
</div>
./src/static/crossdomain.xml
--- ./src/static/crossdomain.xml.orig 2009-12-23 15:34:54.000000000 -0200 +++ ./src/static/crossdomain.xml 2009-12-23 15:44:46.000000000 -0200 @@ -3,8 +3,6 @@ xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFile.xsd"> <site-control permitted-cross-domain-policies="all"/> <allow-http-request-headers-from domain="*" headers="*"/> -<allow-access-from domain="*.tokbox.com" to-ports="*"/> -<allow-access-from domain="tokbox.com" to-ports="*"/> -<allow-access-from domain="*.etherpad.com" to-ports="*"/> -<allow-access-from domain="etherpad.com" to-ports="*"/> +<allow-access-from domain="*.YOURDOMAIN_CHANGEME.com" to-ports="*"/> +<allow-access-from domain="YOURDOMAIN_CHANGEME.com" to-ports="*"/> </cross-domain-policy>
./src/etherpad/pro/pro_utils.js
--- ./src/etherpad/pro/pro_utils.js.orig 2009-12-23 14:28:23.000000000 -0200
+++ ./src/etherpad/pro/pro_utils.js 2009-12-23 14:29:16.000000000 -0200
@@ -145,7 +145,7 @@
}
function getEmailFromAddr() {
- var fromDomain = 'etherpad.com';
+ var fromDomain = 'YOURDOMAIN_CHANGEME.com';
if (pne_utils.isPNE()) {
fromDomain = getFullProDomain();
}
./src/etherpad/globals.js
--- ./src/etherpad/globals.js.orig 2009-12-23 14:27:30.000000000 -0200
+++ ./src/etherpad/globals.js 2009-12-23 16:17:34.000000000 -0200
@@ -27,12 +27,11 @@
}
var SUPERDOMAINS = {
- 'localbox.info': true,
'localhost': true,
- 'etherpad.com': true
+ 'YOURDOMAIN_CHANGEME.com': true
};
./src/etherpad/control/pro/pro_main_control.js
--- ./src/etherpad/control/pro/pro_main_control.js.orig 2009-12-23 14:37:44.000000000 -0200
+++ ./src/etherpad/control/pro/pro_main_control.js 2009-12-23 14:38:09.000000000 -0200
@@ -70,7 +70,7 @@
renderFramed('pro/pro_home.ejs', {
isEvaluation: licensing.isEvaluation(),
- evalExpDate: licensing.getLicense().expiresDate,
+// evalExpDate: licensing.getLicense().expiresDate,
account: getSessionProAccount(),
isPNE: pne_utils.isPNE(),
pneVersion: pne_utils.getVersionString(),
./src/etherpad/control/pad/pad_control.js
--- ./src/etherpad/control/pad/pad_control.js.orig 2009-12-23 14:34:11.000000000 -0200
+++ ./src/etherpad/control/pad/pad_control.js 2009-12-23 14:34:37.000000000 -0200
@@ -661,7 +661,7 @@
{toEmails: toEmails, padId: padId, username: username,
subject: subject, message: message});
- var fromAddr = '"EtherPad" <noreply@etherpad.com>';
+ var fromAddr = '"EtherPad" <noreply@YOURDOMAIN_CHANGEME.com>';
// client enforces non-empty subject and message
var subj = '[EtherPad] '+subject;
var body = renderTemplateAsString('email/padinvite.ejs',
./src/etherpad/control/global_pro_account_control.js
--- ./src/etherpad/control/global_pro_account_control.js.orig 2009-12-23 14:35:13.000000000 -0200
+++ ./src/etherpad/control/global_pro_account_control.js 2009-12-23 14:35:28.000000000 -0200
@@ -125,7 +125,7 @@
response.redirect(_recoverLink(accountList[0], domainList[0]));
}
if (accountList.length > 1) {
- var fromAddr = '"EtherPad Support" <support@etherpad.com>';
+ var fromAddr = '"EtherPad Support" <support@YOURDOMAIN_CHANGEME.com>';
var subj = "EtherPad: account information";
var body = renderTemplateAsString(
'pro/account/global-multi-domain-recover-email.ejs', {
Your EtherPad instance should be ready to go live and kick ass now!
RUN!
First, set the following environment variables:
# export JAVA_HOME="/usr/java/jdk1.6.0_17/" # export JAVA="/usr/java/jdk1.6.0_17/bin/java" # export SCALA="/home/etherpad/scala-2.7.7.final/bin/scala" # export SCALA_HOME="/home/etherpad/scala-2.7.7.final/" # export PATH=/home/etherpad/scala-2.7.7.final/bin/:$PATH # export MYSQL_CONNECTOR_JAR="/usr/share/java/mysql-connector-java-5.0.8.jar" # export mysql=mysql
then create the database,
# bin/setup-mysql-db.sh
compile it,
# bin/rebuildjar.sh
which outputs:
using JAR fastjar... lib/mysql-connector-java-5.0.8.jar has changed, rebuilding JAR unzipping JARs... making cached JAR.... compiling... compiling with 'fsc'... using cached common... using cached sars... using cached cli... using cached bodylock... using cached appserver... using cached ajstdlib... using cached etherpad... using cached ooservice... copying files... obfuscating... building javascript classfiles... done. copying cached JAR... making JAR... cleaning up... done. including etherpad JARs... using cached JAR-etherpad... updating... done. wrote /home/etherpad/trunk/etherpad/appjet-eth-dev.jar which: no growlnotify in (/home/etherpad/trunk/etherpad/scala/bin/:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/bin:/bin)
… and launch it!
# bin/run-local.sh
Which outputs:
Using config file: ./data/etherpad.local.properties Using mysql database type. Establishing mysql connection (this may take a minute)... mysql connection established. Checking for database migrations... HTTP server listening on http://0.0.0.0:9000/ HTTPS server listening on https://0.0.0.0:9001/
Et Voilà! Your EtherPad instance is running!
Sightseeings
You can hit http://youdomain.com:9000/ now!
Start page
Create a new pad
Start page
Hit http://youdomain.com:9000/ep/admin, and use the ADMINPASS_CHANGEME to log in.
Getting a pro account
Hit http://yourdomain.com:9000/ep/pro-signup/
Pro account sign in
http://subdomain.yourdomain.com:9000/
Pro account admin interface
http://subdomain.yourdomain.com:9000/ep/admin
Afterthoughts
Besides the first-hand experience, much of what was summarized here came from the members of the EtherPad Open Source Discussion google group. It’s very cool to watch and participate of an active and gentle community coming into existence almost overnight!
I believe Etherpad will receive some love and polishing soon by its maintainers, and we’ll see it nicely packaged, with switches and knobs inside properly placed config files instead of these tweaks and scattered changes on hardcoded stuff all over the place!
A BIG THANKS to the AppJet/EtherPad team for this great product that is EtherPad, and to Google Inc. for “getting” opensource!
See also
If you came this far, you might also be interested in:
- http://etherpad.com/ep/pne-manual/configuration-guide
- http://etherpad.com/ep/pne-manual/installation-guide
- http://code.google.com/p/etherpad/wiki/Instructions
- http://code.google.com/p/etherpad/wiki/FAQ
- https://wiki.ubuntu.com/Etherpad
- http://www.mclear.co.uk/2009/12/configure-etherpad-pro-after.html
I hope you enjoyed this guide. Feedback and constructive criticism are highly appreciated! Thank you!
Nuba Princigalli






@nprincigalli
Bookmarks
Curriculum
Pictures
Resume
Videos
Great writeup of all the places to modify for pro accounts.Sounds like we need a setup script to modify everything with one action. I’ll look at making one soon. I’m also in the process of ripping out mysql/derby support and replacing it with postgres: http://bitbucket.org/mattsta/etherpad-postgres/.
This comment was originally posted on Hacker News
This is indeed pretty awesome. I was actually just looking through articles about getting it running today. I think for many collaborative apps it would be great to be able to use a barebones etherpad in a model much like we currently use text fields and charfields. This would make me infinitely happy :)
This comment was originally posted on Hacker News
Thanks, your tutorial is, by far, the best one.
Great tutorial!.
I have the same itching, to say it so, and this definitely will help me get my own etherpad running.
Thanks.
Thank you!
Great write up, haven’t seen something this detailed in a while. I was hoping to install this weekend and this definitely saved me a load of time.
This comment was originally posted on Hacker News
I can’t wait to start hacking around. My goal is to make a wiki editor based off Etherpad. If anyone else is interested, drop me a line.
This comment was originally posted on Hacker News
Thanks for the tutorial! When the source was released I downloaded it and was about to install it when I got around to it and just found that in the meantime you wrote this up. I have been a Pro user of Etherpad for quite some time.
I was looking through the Etherpad blog today and came across your exact idea: http://etherpad.com/ep/blog/posts/embedding-etherpadThe etherpad blog is actually an extension of etherpad itself, but they didn’t include the blog template in the open source release (the guts are there, just not the UI). Anybody want to poke them and see why it didn’t get added?
This comment was originally posted on Hacker News
(might as well reply to myself!)I finished the postgres support today along with a sane one step installer. Give it a try.
This comment was originally posted on Hacker News
“After being acquired by Google, EtherPad was opensourced. Being it the kickass thing it is, I got itching with the need to have my own etherpad instance running right away.”
This comment was originally posted on FriendFeed
Very nice and easy to follow. Consider yourself linked-to. –Tom
hi there,
thanks for doing this post.
Does anyone know what it would take to do this on Windows ? I have cygwin and am on vista 64-bit.
thank you,
BR,
~A
Has anybody got the OpenOffice.org integration to work?
I can’t get passed the sslkeystore step. The directory
cd etherpad/trunk/etherpad/data/appjet
doesn’t exist.
If you ever come across this error when compiling with the bin/rebuildjar.sh :
Unable to establish connection to compilation daemon
Compilation failed.
The problem maybe that the server’s hostname doenst have a entry for 127.0.0.1 in the /etc/hosts file.
Fix the /etc/hosts file and recompile.
This one hounded me for several hours until I saw it in the etherpad google group.
http://groups.google.com/group/etherpad-open-source-discuss/browse_thread/thread/1bcfce02e984c728/a325ebcd56b68dc2?lnk=gst&q=Unable+to+establish+connection+to+compilation+daemon#a325ebcd56b68dc2
Thanks for the link Nuba. For those asking re openoffice documentation see http://www.mclear.co.uk/2010/01/problem-with-etherpad-file-importexport.html and/or the section on file import/export here:
http://karteek.selfdabba.com/post/301488675/etherpad-opensourced
It’s really nice that you took the time to write all of this up, but I’ve had a devil of a time trying to get it to work. I tried first on Ubuntu, because it seemed more automated, i.e., scripts walk you through a lot of it, but I couldn’t get it to work, so then I tried on a Redhat-based installation. After much gnashing of teeth, I got the paths straightened out and was able to compile, but I have been trying for three days now to get it to run. It fails with an “access denied” for the etherpad mysql user: “Startup execution failed with non-200 response: 500
Error while executing: Access denied for user ‘etherpad’@‘localhost’ (using password: YES)”
I’ve tried every suggestion I’ve found through Google, all to no avail.
This is really very frustrating. I had suggested to my boss that we use this, and now I’ll have to go back and tell him that I can’t get it working. I really wish all these Etherpad enthusiasts would make it clear that this software really isn’t ready for primetime. It suffers from the same problem as so much open source software — no reliable support, despite the many well-intentioned contributors.
200 500 is documented here:
http://mclear.co.uk/2010/06/29/etherpad-startup-execution-failed-with-non-200-response-500/