<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <title>Tag: cloud :: phly, boy, phly</title>
    <description>Tag: cloud :: phly, boy, phly</description>
    <pubDate>Sun, 30 Dec 2012 15:52:00 +0000</pubDate>
    <generator>Zend_Feed_Writer 2.1.4dev (http://framework.zend.com)</generator>
    <link>http://mwop.net/blog/tag/cloud.html</link>
    <atom:link rel="self" type="application/rss+xml" href="http://mwop.net/blog/tag/cloud-rss.xml"/>
    <item>
      <title>OpenShift, Cron, and Naked Domains</title>
      <pubDate>Sun, 30 Dec 2012 15:52:00 +0000</pubDate>
      <link>http://mwop.net/blog/2012-12-30-openshift-cron-and-naked-domains.html</link>
      <guid>http://mwop.net/blog/2012-12-30-openshift-cron-and-naked-domains.html</guid>
      <author>me@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>
    As an experiment, I migrated my website over to <a 
    href="http://openshift.redhat.com">OpenShift</a> yesterday. I've been hosting
    a pastebin there already, and have found the service to be both straightforward
    and flexible; it was time to put it to a more thorough test.
</p>

<p>
    In the process, I ran into a number of interesting issues, some of which took quite
    some time to resolve; this post is both to help inform other potential users of the
    service, as well as act as a reminder to myself.
</p><h2>Cron</h2>

<p>
    OpenShift offers a <a href="http://en.wikipedia.org/wiki/Cron">Cron</a> cartridge,
    which I was excited to try out.<sup><a href="#f1">1</a></sup>
</p>

<p>
    The basics are quite easy. In your repository's <code>.openshift</code> 
    directory is a <code>cron</code> subdirectory, further divided into 
    <code>minutely</code>, <code>hourly</code>, <code>daily</code>, <code>weekly</code>,
    and <code>monthly</code> subdirectories. You drop a script you want to run
    into one of these directories, and push your changes upstream.
</p>

<p>
    The problem is: what if I want a job to run at a specific time daily? or on 
    the quarter hour? or on a specific day of the week?
</p>

<p>
    As it turns out, you can manage all of the above, just not quite as succinctly as
    you would in a normal crontab. Here, for example, is a script that I run at 
    5AM daily; I placed it in the <code>hourly</code> directory so that it can test
    more frequently:
</p>

<div class="example"><pre><code language="bash">
#!/bin/bash
if [ `date +%H` == "05" ]
then
    (
        export PHP=/usr/local/zend/bin/php ;
        cd $OPENSHIFT_REPO_DIR ; 
        $PHP public/index.php phlycomic fetch all ; 
        $PHP public/index.php phlysimplepage cache clear --page=pages/comics 
    )
fi
</code></pre></div>

<p>
    And here's one that runs on the quarter-hour, placed in the <code>minutely</code>
    directory:
</p>

<div class="example"><pre><code language="bash">
#!/bin/bash
MINUTES=`date +%M`

for i in "00" "15" "30" "45";do
    if [ "$MINUTES" == "$i" ];then
        (
            export PHP=/usr/local/zend/bin/php ;
            cd $OPENSHIFT_REPO_DIR ;
            $PHP public/index.php githubfeed fetch 
        )
    fi
done
</code></pre></div>

<p>
    The point is that if you need more specificity, push the script into the 
    next more specific directory, and test against the time of execution.
</p>

<h2>Naked Domains</h2>

<p>
    Naked domains are domains without a preceding subdomain. In my case, this
    means "mwop.net", vs. "www.mwop.net".
</p>

<p>
    The problem that cloud hosting presents is that the IP address on which you
    are hosted can change at any time, for a variety of reasons. As such, you
    typically cannot use DNS A records to point to your domain; the recommendation
    is to use a CNAME record that points the domain to a "virtual" domain 
    registered with your cloud hosting provider.
</p>

<p>
    However, most domain registrars and DNS providers do not let you do this for
    a naked domain, particularly if you also have MX or other records associated
    with that naked domain.
</p>

<p>
    Some registrars will allow you to forward the A record to a subdomain. I tried
    this, but had limited success; I personally found that I ended up in an infinite
    loop situation when doing the DNS lookup.
</p>

<p>
    Another solution is to have a redirect in place for your naked domain to the
    subdomain, which can then be a CNAME record. Typically, this would require you
    have a web server under your control with a fixed IP that then simply redirects
    to the subdomain. Fortunately, there's an easier solution: <a 
    href="http://wwwizer.com/naked-domain-redirect">wwwizer</a>. You simply point
    your naked domain A record to the wwwizer IP address, and they will do a 
    redirect to your <code>www</code> subdomain.
</p>

<p>
    I implemented wwwizer on my domain (which is why you'll see "www.mwop.net" in
    your location bar), and it's been working flawlessly since doing so.
</p>

<h4>Private repositories</h4>

<p>
    I keep my critical site settings in a private repository, which allows me 
    to version them while keeping the credentials they hold out of the public eye.
    This means, however, that I need to use <a href="https://help.github.com/articles/managing-deploy-keys">GitHub deploy keys</a> on my server
    in order to retrieve changes.
</p>

<p>
    This was simple enough: I created an <code>ssh</code> subdirectory in my
    <code>$OPENSHIFT_DATA_DIR</code> directory, and generated a new SSH keypair.
</p>

<p>
    The problem was telling SSH to <em>use</em> this key when fetching changes.
</p>

<p>
    The solution is to use a combination of <code>ssh-agent</code> and <code>ssh-add</code>,
    and it looks something like this:
</p>

<div class="example"><pre><code language="bash">
#!/bin/bash
ssh-agent `ssh-add $OPENSHIFT_DATA_DIR/ssh/github-key && (
    cd $OPENSHIFT_DATA_DIR/config ; 
    git fetch origin ; 
    git rebase origin/mwop.net.config
)`
</code></pre></div>

<p>
    After testing the above, I put this in a <code>pre_build</code> script in 
    my OpenShift configuration so that I can autoupdate my private 
    configuration on each build. However, I discovered a new problem: when
    a build is being done, the <code>ssh-agent</code> is not available, which
    means the above cannot be executed. I'm still trying to find a solution.
</p>

<h2>Fin</h2>

<p>
    I'm pretty happy with the move. I don't have to do anything special
    to automate deployment, and all my cronjobs and deployment scripts are now
    self-contained in the repository, which makes my site more portable.
    While a few things could use more documentation, all the pieces are there
    and discoverable with a small amount of work.
</p>

<p>
    I'll likely give some other PaaS providers a try in the future, but for 
    the moment, I'm quite happy with the functionality and flexibility of 
    OpenShift.
</p>

<h4>Footnotes</h4>

<ul>
    <li id="f1">Zend Server's JobQueue can also be used as a cron replacement, 
    but I was not keen on exposing the job functionality via HTTP.</li>
</ul>]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>OpenShift, ZF2, and Composer</title>
      <pubDate>Thu, 01 Nov 2012 20:25:00 +0000</pubDate>
      <link>http://mwop.net/blog/2012-11-01-openshift-zf2-composer.html</link>
      <guid>http://mwop.net/blog/2012-11-01-openshift-zf2-composer.html</guid>
      <author>me@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>
I was recently shopping around for inexpensive cloud hosting; I want to try out
a couple of ideas that may or may not have much traffic, but which aren't suited
for my VPS setup (the excellent <a href="http://servergrove.com/">ServerGrove</a>); additionally, I'm unsure how long
I will maintain these projects. My budget for this is quite small as a result;
I'm already paying for hosting, and am quite happy with it, so this is really
for experimental stuff.
</p>

<p>
I considered Amazon, Orchestra.io, and a few others, but was concerned about the
idea of a ~$50/month cost for something I'm uncertain about. 
</p>

<p>
When I asked in <a href="irc://irc.freenode.net/zftalk.dev">#zftalk.dev</a>, someone
suggested <a href="http://openshift.redhat.com/">OpenShift</a> as an idea, and
coincidentally, the very next day
<a href="http://www.zend.com/en/company/news/press/379_red-hat-expands-openshift-ecosystem-with-zend-partnership-to-offer-professional-grade-environment-for-php-developers">Zend announced a partnership with RedHat surrounding OpenShift</a>.  The stars were in alignment.
</p>

<p>
In the past month, in the few spare moments I've had (which included an
excellent OpenShift hackathon at ZendCon), I've created a quick application that
I've deployed and tested in OpenShift. These are my findings.
</p><h2>ZF2</h2>

<p>
    I didn't really have to do anything different to have <a 
    href="http://framework.zend.com/">zf2</a> work; the standard 
    <code>.htaccess</code> provided in the skeleton application worked 
    flawlessly the first time (I've worked with some cloud environments where 
    this is not the case).
</p>

<p>
The only frustration I had was the default directory structure OpenShift foists
upon us: 
</p>

<div class="example"><pre>
data/
libs/
misc/
php/
</pre></div>

<p>
This is not terrible, by any stretch. However, it's attempting to dictate the
application structure, which I'm not terribly happy with -- particularly as my
structure may vary based on the framework I'm using (or not!), and because I may
already have a project written that I simply want to deploy.
</p>

<p>
In particular, the <code>php</code> directory is galling -- it's simply the document root.
Most frameworks I've used or seen call the equivalent directory <code>public</code>, or
<code>web</code>, or <code>html</code> -- but never <code>php</code> (in large part because the only PHP file
under the document root in most frameworks is the <code>index.php</code> that acts as the
front controller). It would be nice if this were configurable.
</p>

<p>
This conflicts a bit with how a ZF2 app is structured. I ended up doing the
following:
</p>

<ul>
<li>
Removed <code>php</code> and symlinked my <code>public</code> directory to it.
</li>
<li>
Removed <code>libs</code> and symlinked my <code>vendor</code> directory to it.
</li>
<li>
Removed <code>misc</code> as I had no need to it.
</li>
</ul>

<p>
Nothing too big, thankfully -- but problematic from the perspective of, "I've
already developed this app, but now I have to make changes for it to work on a
specific cloud vendor."
</p>

<h2>Composer</h2>

<p>
    My next question was how to use <a 
    href="http://getcomposer.org/">Composer</a> during my deployment process, 
    and some some googling <a href="https://openshift.redhat.com/community/content/support-for-git-clone-on-the-server-aka-support-php-composerphar">found 
    some answers for me</a>.
</p>

<p>
Basically, I needed to create a <code>deploy</code> task that does two things:
</p>

<ul>
<li>
    Unset the <code>GIT_DIR</code> environment variable. Evidently, the build 
    process operates as part of a git hook, and since Composer often uses git 
    repositories, this can lead to problems.
</li>
<li>
    Change directory to <code>OPENSHIFT_REPO_DIR</code>, which is where the 
    application root (not document root!) lives.
</li>
</ul>

<p>
    Once I did those, I could run my normal composer installation. The 
    <code>deploy</code> task looks like this:
</p>

<div class="example"><pre><code language="bash">
#!/bin/bash
# .openshift/action_hooks/deploy
( unset GIT_DIR ; cd $OPENSHIFT_REPO_DIR ; /usr/local/zend/bin/php composer.phar install )
</code></pre></div>

<p>
This leads into my next topic.
</p>

<h2>Deployment</h2>

<p>
    First off, as you probably guessed from that last secton, there 
    <strong>are</strong> hooks for
    deployment -- it doesn't have to be simply git. I like this, as I may have
    additional things I want to do during deployment, such as retrieving and
    installing site-specific configuration files, installing Composer-defined
    dependencies (as already noted), etc.
</p>

<p>
    Over all, this is pretty seamless, but it's not without issues. I've been 
    told that some of my issues are being worked on, so those I won't bring up 
    here. The ones that were a bit strange, and which caught me by surprise, 
    though, were:
</p>

<ul>
<li>
    Though the build process creates the site build from git, your 
    <strong>submodules are not updated recursively</strong>. This tripped me 
    up, as I was using <a href="https://github.com/EvanDotPro/EdpMarkdown">EdpMarkdown</a>,
    and had installed it as a submodule. I ended up having to import it, and its
    own submodule, directly into my project so that it would work.
</li>
<li>
    I installed the <a href="http://www.mongodb.org/">MongoDB</a> cartridge. Ironically, it was not then enabled in
    Zend Server, and I had to go do this. This should be turnkey.
</li>
<li>
    <code>/usr/bin/php</code> is not the same as <code>/usr/local/zend/bin/php</code>. This makes no
    sense to me if I've installed Zend Server as my base gear. Considering
    they're different versions, this can be hugely misleading and lead to errors.
    I understand there are reasons to have both -- so simply be aware that if you
    use the Zend Server gear, your tasks likely should use
    <code>/usr/local/zend/bin/php</code>.
</li>
</ul>

<h2>The good parts?</h2>

<ul>
<li>
    <a href="https://openshift.redhat.com/community/faq/i-have-deployed-my-app-but-i-don%E2%80%99t-like-telling-people-to-visit-myapp-myusernamerhcloudcom-how-c">You 
    can alias an application to a DNS CNAME</a> -- meaning you can point your
    domain name to your OpenShift applications. Awesome!
</li>
<li>
    Simplicity of adding capabilities, such as Mongo, MySQL, Cron, and others. 
    In most cases, this is simply a "click on the button" and it's installed 
    and available.
</li>
<li>
    <a href="http://www.zend.com/en/products/server">Zend Server</a>. For 
    most PHP extensions, I can turn them on or off with a few
    mouse clicks. If I want page-level caching, I don't have to do anything to my
    application; I can simply setup some rules in the Zend Server interface and
    get on with it, and enjoy tremendous boosts to performance. I used to enjoy
    taming and tuning servers; most days anymore, I just want them to work.
</li>
<li>
    <a href="https://openshift.redhat.com/community/developers/remote-access">SSH</a> 
    access to the server, with a number of commands to which I've been given
    <code>sudoer</code> access. If you're going to sandbox somebody,
    this is a fantastic way to do it. Oh, also: SSH tunnels to services like Mongo
    and MySQL just work (via the <code>rhc-port-forward</code> command).
</li>
</ul>

<h2>Summary</h2>

<p>
Over all, I'm quite pleased. While it took me a bit to find the various
incantations I needed, the service is quite flexible. For my needs, considering
I'm doing experimental stuff, the price can't be beat (the current developer
preview is free). Considering most stuff I do will fall into this or the basic
tier, and that most cartridges do not end up counting against your alotment of
gears, the pricing ($0.05/hour) is extremely competitive. 
</p>]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
  </channel>
</rss>
