-
Notifications
You must be signed in to change notification settings - Fork 345
Run selfoss at a Heroku like PaaS
This guide shows you how to deploy selfoss on a Heroku-like PaaS. I explicitly say "Heroku-like" because I only tested it with deis. But the steps for Heroku or Cloudfoundry will be similar.
You need access to a PaaS and have the required client tools installed. In my case it is the deis client. For Heroku it would be the Heroku toolbelt. For Cloudfoundry it'll be the cloudfoundry cli.
You usually want to have git
installed as well. And some nice text editor like vim
or Sublime Text
or whatever you prefer.
You need access to a mysql or postgresql database from within your PaaS.
Before we start, we have to check out the current selfoss to a directory. I usually have my projects at ~/projects/
. So I opened up my terminal and typed
$ cd ~/projects
$ git clone https://github.com/SSilence/selfoss.git
$ cd selfoss
If you want a specific version, you should check that version out:
$ git checkout 2.14
Now we need to add a few files:
$ touch .env
$ touch .buildpacks
$ touch Procfile
$ touch clock.sh
In the .env
file we'll add all out environment variables. The Procfile
will tell your PaaS what kind of processes there are and how to start them. The clock.sh
is a custom script for updating our RSS-feeds every once in a while.
Usually we configure selfoss by creating a "config.ini" file. But in 'the cloud' we like to configure our applications through environment variables (short: "ENV"), so we can tell our PaaS to change the variable and restart the application whenever our needs change. This way we don't have to push the changed files back to the server.
The .env
file is a file that contains all the ENV variables that'll later be made available to our application by the PaaS. A basic sample is shown below
BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-multi
SELFOSS_DB_TYPE=mysql
SELFOSS_DB_HOST=10.0.0.100
SELFOSS_DB_PORT=3306
SELFOSS_DB_USERNAME=selfoss
SELFOSS_DB_PASSWORD=randompassword
SELFOSS_DB_DATABASE=selfoss
SELFOSS_SALT=8XddRN5nPHXLTMsM
SELFOSS_PASSWORD=https://yourselfoss.com/password
SELFOSS_USERNAME=your_desired_username
SELFOSS_BASE_URL=https://yourselfoss.com
Important: Do not blindly copy this into your .env
file. You must change the following variables (I omitted the SELFOSS_
prefix):
- DB_TYPE: use mysql or pgsql. Don't use sqlite, or you lose your feeds every time you upgrade your app. See 12factor.net, especially the chapters about backing services and disposability.
- DB_HOST, DB_USERNAME, DB_PASSWORD, DB_DATABASE: obvious, right?
- DB_PORT: 3306 for mysql, 5432 for PostgreSQL
- SALT: Create your own salt!
- PASSWORD: After the first deployment, open your selfoss instance in the browser and point it to the "/password" page. Use this page to generate the hashed & salted password, which you put here afterwards. (And don't forget to re-submit the config once you've changed it in here!)
- USERNAME: again, obvious.
- BASE_URL: Some PaaS don't somehow hide the real URL through which the user accesses because they do a lot of proxying and therefore the auto-detection of the client facing URL breaks. Put your full URL here. I think you can omit the protocol and write "://yourselfoss.com", but I don't use that and didn't test it.
Since version 2.18, selfoss no longer bundles the JavaScript libraries – it needs Node.js buildpack in addition to PHP one to obtain them. The .buildpacks
file contains a list of buildpacks to use.
https://github.com/heroku/heroku-buildpack-nodejs
https://github.com/heroku/heroku-buildpack-php
On Heroku, you can also run heroku buildpacks:add --index 1 heroku/nodejs
instead of creating the file, see https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app
We're going to have two processes. One is the web server (Apache2). The second one is the update process which will fetch the RSS feeds for us.
The Procfile
looks like this:
web: vendor/bin/heroku-php-apache2
clock: sh ~/clock.sh
Note: Never start more than one instance of the clock process on your PaaS. Also, some PaaS don't run the clock process by default, so you have to set it manually to one instance. (E.g. with deis: deis ps:scale clock=1
).
This script will call the update.php
file from the command-line (i.e. php update.php
) and then wait a certain amount of time, just to call the update.php
file once more. And again, and again, and again.
The file looks like this:
#!/bin/sh
#
# Runs the update task every now and then sleeps for a while.
# Use SELFOSS_UPDATE_INTERVAL to adjust the sleep time. Defaults to 5 mintes.
#
# Author: Christian Mäder <mail*cimnine.ch>
# License: WTFPL
#
# Inspired by
# http://stackoverflow.com/questions/10614454/php-heroku-background-workers
#
echo "Clock V1.0.0"
echo Started at `date`
echo Started in `pwd`
echo ENV:
LD_LIBRARY_PATH=$HOME/.heroku/php/usr/lib/x86_64-linux-gnu:$HOME/.heroku/php/usr/lib
PATH="$HOME/.heroku/php/bin:$HOME/.heroku/php/sbin:$PATH"
printenv
while :
do
echo "Update now."
php update.php
echo "Sleep now for ${SELFOSS_UPDATE_INTERVAL-600}"
sleep ${SELFOSS_UPDATE_INTERVAL-600}
done
You can adjust the update interval through the ENV variable SELFOSS_UPDATE_INTERVAL
. It defaults to 600 seconds.
This is now very specific to your PaaS. I'll show the commands for the deis PaaS, those for Heroku will look very similar, probably those of Cloudfoundry as well.
Modern PaaS leverage git
to publish to them. This has the advantage that you only send the delta of the version that is already deployed on the PaaS to the version you would like to deploy.
$ cd ~/projects/selfoss
$ deis create selfoss
$ deis config:push
$ git commit -a -m "ready for deployment"
$ git push deis
First I created a new application on my PaaS. Then I pushed the configuration we prepared in .env
. An finally I uploaded the code to the PaaS.
You should now be able to access your selfoss instance through the web. But you can not login because you have not yet created the password hash. Do this now: https://yourselfoss.com/password. Copy the value and adjust the SELFOSS_PASSWORD
variable in the .env
file and finally re-upload the configuration (e.g. deis config:push
).
As selfoss stores some files, especially favicons, on the filesystem, you must call '/update' at least once manually. Usually the clock
task runs in a separate container so it will put the favicons in a folder in his own container rather the container selfoss is delivered from. You still get the feeds updated because they are stored in the DB.
This will get tricky if you deliver selfoss from multiple instances behind a loadbalancer.
Somehow you must get access to the application logs to do proper troubleshooting. On deis you get access to the logs by running deis logs
. The following things happened to me during the deployment before everything worked out:
- Check if your symptoms are the same as in #22 described. See #652 for a way to fix it. (Please make a note in the pull request #652 if you ran into problem #22.)
- Make sure your web process is scheduled. (E.g.
deis ps:list
and eventuallydeis ps:scale web=1
) - Is the DB connection information correct? (You can also check if your PaaS applied the ENV correctly. In my case:
deis run -- sh -c printenv
)
Check and adjust SELFOSS_BASE_URL
.
- Did you schedule the
clock
process? (E.g.deis ps:list
anddeis ps:scale clock=1
) - Does the manual import run?
- Login to https://yourselfoss.com/
- Open https://yourselfoss.com/update
- Did you generate your password hash with https://yourselfoss.com/password ?
- Did you put it into your
.env
file? - Did you push the changed config to the PaaS? (E.g.
deis config:list
anddeis config:push
, maybe also check the ENV on the PaaS withdeis run -- sh -c printenv
.
There's only one thing left to do for you: Read the logs! (E.g. deis logs
)