Skip to content

Run selfoss at a Heroku like PaaS

Christian Mäder edited this page May 10, 2015 · 10 revisions

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.

Requirements

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.

Preparation

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 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.

Our configuration in .env

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-php
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.

Our processes in the Procfile

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).

Our henchman, the update.sh script

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.

One more thing

As long as https://github.com/SSilence/selfoss/pull/652 is not merged, you need to add the following to the .htaccess file:

# set magic_quotes_gpc as f3 wouldn't start otherwise
<IfModule mod_php5.c>
    php_value magic_quotes_gpc "1"
</IfModule>

Deployment

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).

Troubleshooting

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:

It does not start at all

  1. Check if your symptoms are the same as in #22 described. Then check if #652 is merged or apply the fix yourself. (Also see above about the same.)
  2. Make sure your web process is scheduled. (E.g. deis ps:list and eventually deis ps:scale web=1)
  3. 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)

It does not render pretty and images & scripts don't load. It redirects me to weird URLs.

Check and adjust SELFOSS_BASE_URL.

It does not update my feeds automatically!

  1. Did you schedule the clock process? (E.g. deis ps:list and deis ps:scale clock=1)
  2. Does the manual import run?
  3. Login to https://yourselfoss.com/
  4. Open https://yourselfoss.com/update

I cannot login!

  1. Did you generate your password hash with https://yourselfoss.com/password ?
  2. Did you put it into your .env file?
  3. Did you push the changed config to the PaaS? (E.g. deis config:list and deis config:push, maybe also check the ENV on the PaaS with deis run -- sh -c printenv.

It's something else!

There's only one thing left to do for you: Read the logs! (E.g. deis logs)