<!DOCTYPE html>
<html class="theme-dark" lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>From The Keyboard</title>
    <link rel="stylesheet" href="https://www.fromthekeyboard.com/assets/built/screen.css?v=04544d1367">

    <link rel="shortcut icon" href="https://from-the-keyboard.ghost.io/content/images/2024/02/FTK-copy-2.gif" type="image/jpeg">
    <link rel="apple-touch-icon" href="https://from-the-keyboard.ghost.io/content/images/2024/02/FTK-copy-2.gif" type="image/jpeg">

    <meta name="description" content="Hi, I&#x27;m Nick. I’ve been working professionally on the internet building things for over 18 years. I’ve spent most of that time building Rails apps with a strong focus on Developer UX and DevOps.">
    <link rel="icon" href="https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w256h256/2024/02/ZTd-c6KN_400x400-1.jpeg" type="image/jpeg">
    <link rel="canonical" href="https://www.fromthekeyboard.com/">
    <meta name="referrer" content="no-referrer-when-downgrade">
    <link rel="next" href="https://www.fromthekeyboard.com/page/2/">
    
    <meta property="og:site_name" content="From The Keyboard">
    <meta property="og:type" content="website">
    <meta property="og:title" content="From The Keyboard">
    <meta property="og:description" content="Hi, I&#x27;m Nick. I’ve been working professionally on the internet building things for over 18 years. I’ve spent most of that time building Rails apps with a strong focus on Developer UX and DevOps.">
    <meta property="og:url" content="https://www.fromthekeyboard.com/">
    <meta property="article:publisher" content="https://www.facebook.com/ghost">
    <meta name="twitter:card" content="summary">
    <meta name="twitter:title" content="From The Keyboard">
    <meta name="twitter:description" content="Hi, I&#x27;m Nick. I’ve been working professionally on the internet building things for over 18 years. I’ve spent most of that time building Rails apps with a strong focus on Developer UX and DevOps.">
    <meta name="twitter:url" content="https://www.fromthekeyboard.com/">
    <meta name="twitter:site" content="@ghost">
    
    <script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "WebSite",
    "publisher": {
        "@type": "Organization",
        "name": "From The Keyboard",
        "url": "https://www.fromthekeyboard.com/",
        "logo": {
            "@type": "ImageObject",
            "url": "https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/2024/02/FTK-3.png"
        }
    },
    "url": "https://www.fromthekeyboard.com/",
    "name": "From The Keyboard",
    "mainEntityOfPage": "https://www.fromthekeyboard.com/",
    "description": "Hi, I&#x27;m Nick. I’ve been working professionally on the internet building things for over 18 years. I’ve spent most of that time building Rails apps with a strong focus on Developer UX and DevOps."
}
    </script>

    <meta name="generator" content="Ghost 6.44">
    <link rel="alternate" type="application/rss+xml" title="From The Keyboard" href="https://www.fromthekeyboard.com/rss/">
    <script defer src="https://cdn.jsdelivr.net/ghost/portal@~2.68/umd/portal.min.js" data-i18n="true" data-ghost="https://www.fromthekeyboard.com/" data-key="528a41061448b8aade92aaea49" data-api="https://from-the-keyboard.ghost.io/ghost/api/content/" data-locale="en" crossorigin="anonymous"></script><style id="gh-members-styles">.gh-post-upgrade-cta-content,
.gh-post-upgrade-cta {
    display: flex;
    flex-direction: column;
    align-items: center;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
    text-align: center;
    width: 100%;
    color: #ffffff;
    font-size: 16px;
}

.gh-post-upgrade-cta-content {
    border-radius: 8px;
    padding: 40px 4vw;
}

.gh-post-upgrade-cta h2 {
    color: #ffffff;
    font-size: 28px;
    letter-spacing: -0.2px;
    margin: 0;
    padding: 0;
}

.gh-post-upgrade-cta p {
    margin: 20px 0 0;
    padding: 0;
}

.gh-post-upgrade-cta small {
    font-size: 16px;
    letter-spacing: -0.2px;
}

.gh-post-upgrade-cta a {
    color: #ffffff;
    cursor: pointer;
    font-weight: 500;
    box-shadow: none;
    text-decoration: underline;
}

.gh-post-upgrade-cta a:hover {
    color: #ffffff;
    opacity: 0.8;
    box-shadow: none;
    text-decoration: underline;
}

.gh-post-upgrade-cta a.gh-btn {
    display: block;
    background: #ffffff;
    text-decoration: none;
    margin: 28px 0 0;
    padding: 8px 18px;
    border-radius: 4px;
    font-size: 16px;
    font-weight: 600;
}

.gh-post-upgrade-cta a.gh-btn:hover {
    opacity: 0.92;
}</style>
    <script defer src="https://cdn.jsdelivr.net/ghost/sodo-search@~1.8/umd/sodo-search.min.js" data-key="528a41061448b8aade92aaea49" data-styles="https://cdn.jsdelivr.net/ghost/sodo-search@~1.8/umd/main.css" data-sodo-search="https://from-the-keyboard.ghost.io/" data-locale="en" crossorigin="anonymous"></script>
    
    <link href="https://www.fromthekeyboard.com/webmentions/receive/" rel="webmention">
    <script defer src="/public/cards.min.js?v=04544d1367"></script>
    <link rel="stylesheet" type="text/css" href="/public/cards.min.css?v=04544d1367">
    <script defer src="/public/member-attribution.min.js?v=04544d1367"></script>
    <script defer src="/public/ghost-stats.min.js?v=04544d1367" data-stringify-payload="false" data-datasource="analytics_events" data-storage="localStorage" data-host="https://www.fromthekeyboard.com/.ghost/analytics/api/v1/page_hit"  tb_site_uuid="c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b" tb_post_uuid="undefined" tb_post_type="null" tb_member_uuid="undefined" tb_member_status="undefined"></script><style>:root {--ghost-accent-color: #73D9A7;}</style>
    <!-- Privacy-friendly analytics by Plausible -->
<script async src="https://plausible.io/js/pa-f0eZQ_fyiP45SvlXhceF-.js"></script>
<script>
  window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}};
  plausible.init()
</script>

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/prism/9000.0.1/themes/prism-tomorrow.min.css">

<style>
  :not(pre)>code {
    background-color: #404040;
  }

  pre, pre > code {
    background-color: transparent;
    overflow-x: auto;
  }

  .gh-head-logo img {
    left: -30px;
  }
  
  .gh-head-logo img {
    max-height: 80px;
  }
  .cover-icon-image {
    border-radius: 5px;
  }
</style>
</head>

<body class='home-template is-head-left-logo'>
<div class="site">

    <header id="gh-head" class="gh-head gh-outer">
        <div class="gh-head-inner gh-inner">
            <div class="gh-head-brand">
                <div class="gh-head-brand-wrapper">
                    <a class="gh-head-logo" href="https://www.fromthekeyboard.com">
                            <img src="https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/2024/02/FTK-3.png" alt="From The Keyboard">
                                <img src="https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/2024/02/FTK.png" alt="From The Keyboard">
                    </a>
                </div>
                <button class="gh-search gh-icon-btn" aria-label="Search this site" data-ghost-search><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" width="20" height="20"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg></button>
                <button class="gh-burger"></button>
            </div>

            <nav class="gh-head-menu">
                <ul class="nav">
    <li class="nav-home nav-current"><a href="https://www.fromthekeyboard.com/">Home</a></li>
    <li class="nav-about"><a href="https://www.fromthekeyboard.com/about/">About</a></li>
    <li class="nav-writing"><a href="https://www.fromthekeyboard.com/author/nick/">Writing</a></li>
    <li class="nav-contact"><a href="mailto:nick@fromthekeyboard.com">Contact</a></li>
</ul>

            </nav>

            <div class="gh-head-actions">
                    <button class="gh-search gh-icon-btn" aria-label="Search this site" data-ghost-search><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2" width="20" height="20"><path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg></button>
                    <div class="gh-head-members">
                                <a class="gh-head-link" href="#/portal/signin" data-portal="signin">Sign in</a>
                                <a class="gh-head-btn gh-btn gh-primary-btn" href="#/portal/signup" data-portal="signup">Subscribe</a>
                    </div>
            </div>
        </div>
    </header>

        <div class="cover gh-outer">
    <div class="cover-content gh-inner">
        <div class="cover-icon">
            <img class="cover-icon-image" src="https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/2024/02/ZTd-c6KN_400x400-1.jpeg" alt="From The Keyboard">
        </div>

        <div class="cover-description">Hi, I&#x27;m Nick. I’ve been working professionally on the internet building things for over 18 years. I’ve spent most of that time building Rails apps with a strong focus on Developer UX and DevOps.</div>

        <div class="cover-cta">
            <a href="mailto:nick@fromthekeyboard.com" class="button get-in-touch">Get In Touch</a>
        </div>
    </div>
</div>
                <div class="gh-outer">
    <section class="featured-wrapper gh-inner">

            <h2 class="featured-title">Recent Projects</h2>

        <div class="featured-feed owl">
            <article class="post featured">
                <div class="u-placeholder horizontal">
                        <img
                            class="u-object-fit"
                            srcset="https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w400/2025/01/Screenshot-2025-01-22-at-6.48.43-AM-2.png 400w,
https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w750/2025/01/Screenshot-2025-01-22-at-6.48.43-AM-2.png 750w,
https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w960/2025/01/Screenshot-2025-01-22-at-6.48.43-AM-2.png 960w,
https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w1140/2025/01/Screenshot-2025-01-22-at-6.48.43-AM-2.png 1140w"
                            sizes="(min-width: 992px) calc((92vw - 60px) / 3), (min-width: 768px) calc((92vw - 30px) / 2), 92vw"
                            src="https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w750/2025/01/Screenshot-2025-01-22-at-6.48.43-AM-2.png"
                            alt="Health care plan cost estimator for employees"
                        >
                </div>
                <h3 class="post-title">Health care plan cost estimator for employees</h3>
                <a class="u-permalink" href=/health-care-plan-cost-estimator/ aria-label="Health care plan cost estimator for employees"></a>
            </article>
            <article class="post featured">
                <div class="u-placeholder horizontal">
                        <img
                            class="u-object-fit"
                            srcset="https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w400/2025/01/WIWS---24x36-1.jpg 400w,
https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w750/2025/01/WIWS---24x36-1.jpg 750w,
https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w960/2025/01/WIWS---24x36-1.jpg 960w,
https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w1140/2025/01/WIWS---24x36-1.jpg 1140w"
                            sizes="(min-width: 992px) calc((92vw - 60px) / 3), (min-width: 768px) calc((92vw - 30px) / 2), 92vw"
                            src="https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w750/2025/01/WIWS---24x36-1.jpg"
                            alt="Construction job site safety enhancement program"
                        >
                </div>
                <h3 class="post-title">Construction job site safety enhancement program</h3>
                <a class="u-permalink" href=/construction-job-site-safety-enhancement-program-2/ aria-label="Construction job site safety enhancement program"></a>
            </article>
            <article class="post featured">
                <div class="u-placeholder horizontal">
                        <img
                            class="u-object-fit"
                            srcset="https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w400/2025/01/demo-1.png 400w,
https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w750/2025/01/demo-1.png 750w,
https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w960/2025/01/demo-1.png 960w,
https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w1140/2025/01/demo-1.png 1140w"
                            sizes="(min-width: 992px) calc((92vw - 60px) / 3), (min-width: 768px) calc((92vw - 30px) / 2), 92vw"
                            src="https://storage.ghost.io/c/c0/53/c0537bc9-4d1e-4e9b-b49c-b51bd461bf4b/content/images/size/w750/2025/01/demo-1.png"
                            alt="Deployment dashboard for container-based deployments using Kamal"
                        >
                </div>
                <h3 class="post-title">Deployment dashboard for container-based deployments using Kamal</h3>
                <a class="u-permalink" href=/deployment-dashboard-for-container-based-deployments-using-kamal-2/ aria-label="Deployment dashboard for container-based deployments using Kamal"></a>
            </article>
        </div>

    </section>
    </div>

    <div class="site-content">
        
<main class="site-main">

    <div class="post-feed gh-feed gh-canvas">
            <article class="feed public post tag-shipyrd tag-kamal no-image">

    <div class="feed-calendar">
        <div class="feed-calendar-month">
            May
        </div>
        <div class="feed-calendar-day">
            06
        </div>
    </div>

    <h2 class="feed-title">Shipyrd now works with Honeybadger, Rollbar, and AppSignal</h2>

    <div class="feed-right">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon icon-star">
    <path d="M16 23.027L24.24 28l-2.187-9.373 7.28-6.307-9.587-.827-3.747-8.827-3.747 8.827-9.587.827 7.267 6.307L7.759 28l8.24-4.973z"></path>
</svg>        <div class="feed-length">
            2 min read
        </div>
    </div>

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon feed-icon">
    <path d="M11.453 22.107L17.56 16l-6.107-6.12L13.333 8l8 8-8 8-1.88-1.893z"></path>
</svg>
    <a class="u-permalink" href="/shipyrd-now-works-with-honeybadger-rollbar-and-appsignal/" aria-label="Shipyrd now works with Honeybadger, Rollbar, and AppSignal"></a>

</article>            <article class="feed public post tag-shipyrd tag-devops no-image">

    <div class="feed-calendar">
        <div class="feed-calendar-month">
            Apr
        </div>
        <div class="feed-calendar-day">
            29
        </div>
    </div>

    <h2 class="feed-title">Deploy status and lock badges for your app</h2>

    <div class="feed-right">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon icon-star">
    <path d="M16 23.027L24.24 28l-2.187-9.373 7.28-6.307-9.587-.827-3.747-8.827-3.747 8.827-9.587.827 7.267 6.307L7.759 28l8.24-4.973z"></path>
</svg>        <div class="feed-length">
            1 min read
        </div>
    </div>

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon feed-icon">
    <path d="M11.453 22.107L17.56 16l-6.107-6.12L13.333 8l8 8-8 8-1.88-1.893z"></path>
</svg>
    <a class="u-permalink" href="/deploy-status-and-lock-badges-for-your-app/" aria-label="Deploy status and lock badges for your app"></a>

</article>            <article class="feed public post tag-ai tag-mcp no-image">

    <div class="feed-calendar">
        <div class="feed-calendar-month">
            Apr
        </div>
        <div class="feed-calendar-day">
            22
        </div>
    </div>

    <h2 class="feed-title">Preconfiguring your MCP servers for your team</h2>

    <div class="feed-right">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon icon-star">
    <path d="M16 23.027L24.24 28l-2.187-9.373 7.28-6.307-9.587-.827-3.747-8.827-3.747 8.827-9.587.827 7.267 6.307L7.759 28l8.24-4.973z"></path>
</svg>        <div class="feed-length">
            4 min read
        </div>
    </div>

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon feed-icon">
    <path d="M11.453 22.107L17.56 16l-6.107-6.12L13.333 8l8 8-8 8-1.88-1.893z"></path>
</svg>
    <a class="u-permalink" href="/preconfiguring-your-mcp-servers-for-your-team/" aria-label="Preconfiguring your MCP servers for your team"></a>

</article>            <article class="feed public post tag-shipyrd tag-kamal no-image">

    <div class="feed-calendar">
        <div class="feed-calendar-month">
            Apr
        </div>
        <div class="feed-calendar-day">
            13
        </div>
    </div>

    <h2 class="feed-title">Blocking your deploys with Shipyrd</h2>

    <div class="feed-right">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon icon-star">
    <path d="M16 23.027L24.24 28l-2.187-9.373 7.28-6.307-9.587-.827-3.747-8.827-3.747 8.827-9.587.827 7.267 6.307L7.759 28l8.24-4.973z"></path>
</svg>        <div class="feed-length">
            3 min read
        </div>
    </div>

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon feed-icon">
    <path d="M11.453 22.107L17.56 16l-6.107-6.12L13.333 8l8 8-8 8-1.88-1.893z"></path>
</svg>
    <a class="u-permalink" href="/blocking-your-deploys-with-shipyrd/" aria-label="Blocking your deploys with Shipyrd"></a>

</article>            <article class="feed public post tag-kamal tag-docker no-image">

    <div class="feed-calendar">
        <div class="feed-calendar-month">
            Dec
        </div>
        <div class="feed-calendar-day">
            11
        </div>
    </div>

    <h2 class="feed-title">Full SSL from Cloudflare to your Rails app with Kamal</h2>

    <div class="feed-right">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon icon-star">
    <path d="M16 23.027L24.24 28l-2.187-9.373 7.28-6.307-9.587-.827-3.747-8.827-3.747 8.827-9.587.827 7.267 6.307L7.759 28l8.24-4.973z"></path>
</svg>        <div class="feed-length">
            3 min read
        </div>
    </div>

    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" fill="currentColor" class="icon feed-icon">
    <path d="M11.453 22.107L17.56 16l-6.107-6.12L13.333 8l8 8-8 8-1.88-1.893z"></path>
</svg>
    <a class="u-permalink" href="/full-ssl-from-cloudflare-to-your-rails-app-with-kamal/" aria-label="Full SSL from Cloudflare to your Rails app with Kamal"></a>

</article>    </div>

    <nav class="load-more">
    <button class="button button-secondary gh-loadmore">Load more</button>
</nav>

</main>
    </div>

    <footer class="gh-foot gh-outer">
        <div class="gh-foot-inner gh-inner">
            <div class="gh-copyright">
                From The Keyboard © 2026
            </div>
                <nav class="gh-foot-menu">
                    <ul class="nav">
    <li class="nav-sign-up nav-current"><a href="#/portal/">Sign up</a></li>
    <li class="nav-about"><a href="https://www.fromthekeyboard.com/about/">About</a></li>
    <li class="nav-contact"><a href="mailto:nick@fromthekeyboard.com">Contact</a></li>
    <li class="nav-buy-me-a-coffee nav-current"><a href="https://www.fromthekeyboard.com/">Buy Me a Coffee</a></li>
</ul>

                </nav>
            <div class="gh-powered-by">
                <a href="https://ghost.org/" target="_blank" rel="noopener">Powered by Ghost</a>
            </div>
        </div>
    </footer>

</div>


<script
    src="https://code.jquery.com/jquery-3.5.1.min.js"
    integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
    crossorigin="anonymous">
</script>
<script src='https://www.fromthekeyboard.com/assets/built/main.min.js?v=04544d1367'></script>

<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/prism.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>

</body>
</html>