<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Hosting Data Apps]]></title><description><![CDATA[Everything you wanted to know about hosting data applications]]></description><link>https://hosting.analythium.io/</link><image><url>https://hosting.analythium.io/favicon.png</url><title>Hosting Data Apps</title><link>https://hosting.analythium.io/</link></image><generator>Ghost 5.47</generator><lastBuildDate>Fri, 24 Apr 2026 10:37:21 GMT</lastBuildDate><atom:link href="https://hosting.analythium.io/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[duty-free.cc]]></title><description><![CDATA[<figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2026/04/image.png" class="kg-image" alt="duty-free.cc" loading="lazy"></figure><!--kg-card-begin: markdown--><p>forum.duty-free.cc is a Russian-language forum focused on information security and hacking-related topics, where users discuss penetration testing, vulnerabilities, exploits, OSINT, and real-world cases. The platform presents itself as a community of cybersecurity professionals and enthusiasts who share experience, publish articles, and discuss methods of defense and attack; however,</p>]]></description><link>https://hosting.analythium.io/duty-free-cc/</link><guid isPermaLink="false">69dd9635bdab85044231d00d</guid><dc:creator><![CDATA[Peter Solymos]]></dc:creator><pubDate>Tue, 14 Apr 2026 01:19:49 GMT</pubDate><content:encoded><![CDATA[<figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2026/04/image.png" class="kg-image" alt="duty-free.cc" loading="lazy"></figure><!--kg-card-begin: markdown--><p>forum.duty-free.cc is a Russian-language forum focused on information security and hacking-related topics, where users discuss penetration testing, vulnerabilities, exploits, OSINT, and real-world cases. The platform presents itself as a community of cybersecurity professionals and enthusiasts who share experience, publish articles, and discuss methods of defense and attack; however, it exists at the intersection of legitimate security research and the underground scene, so topics related to gray or controversial practices may also appear.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[How to Pick the Right Hosting Option for Your Shiny App]]></title><description><![CDATA[You mastered Shiny, your app is production-ready. Here are the different ways of hosting it. This post helps you pick one that best suits your needs!]]></description><link>https://hosting.analythium.io/how-to-pick-the-right-hosting-option-for-your-shiny-app/</link><guid isPermaLink="false">613c19436e829c45bdb95caf</guid><category><![CDATA[Review]]></category><category><![CDATA[Shiny]]></category><category><![CDATA[Docker]]></category><category><![CDATA[DO App Platform]]></category><category><![CDATA[Heroku]]></category><category><![CDATA[RStudio Connect]]></category><category><![CDATA[Shinyapps]]></category><category><![CDATA[ShinyProxy]]></category><category><![CDATA[Shiny Server]]></category><category><![CDATA[VM]]></category><dc:creator><![CDATA[Peter Solymos]]></dc:creator><pubDate>Thu, 04 Nov 2021 12:00:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1542632466-18cb12ee7d78?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fGNvbXBsZXh8ZW58MHx8fHwxNjM1MDI0NjUz&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1542632466-18cb12ee7d78?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDN8fGNvbXBsZXh8ZW58MHx8fHwxNjM1MDI0NjUz&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="How to Pick the Right Hosting Option for Your Shiny App"><p>The Hosting Data Apps website recently celebrated its <a href="https://hosting.analythium.io/hosting-data-apps-6-months-and-40-posts-later/">6-months anniversary</a>. During this time I have written 40 posts, almost all about Shiny hosting options. Some of these posts reviewed particular hosting options, such as Shinyapps.io, Shiny Server, Heroku, and ShinyProxy.</p><p>A lot has been said about the hosting options themselves, but what about the needs of the developers and the users? The goal of this post is to address this shortcoming by <strong>summarizing the </strong><a href="https://hosting.analythium.io/tag/review/"><strong>reviews</strong></a>.</p><h2 id="how-not-to-do-a-review">How not to do a review</h2><p>You might have seen various websites listing comparisons titled &quot;<strong><em>A vs. B</em></strong>&quot;. I was wondering if doing something like that would make sense for the Hosting Data site. Think like &quot;<em>Which is better: Shinyapps or Heroku?</em>&quot;.</p><p>This would instantly give me 36 more articles to write. Plenty of ammunition for the next 9 months by recycling the previous content. Easy-peasy, if all I wanted was to boost the page ranking.</p><p>Instead, I decided that these <strong>A vs. B posts are useless</strong>. They fail to ask the most important question: &quot;<em>which option is better <strong>for what</strong></em>&quot;? This is where developers and the users of the app come into the picture with their <strong>specific needs and constraints</strong>.</p><p>You could say, for example, that &quot;<em>I want to host my portfolio for free and I don&apos;t care about a custom domain name</em>&quot;. Or a nonprofit might say, &quot;<em>we want to host our apps at low cost, we want custom domains, and we want to be able to handle surge traffic, but we don&apos;t want to maintain any servers</em>&quot;.</p><p>These are really specific criteria, and if you ask me, I might say Shinyapps.io is best for you and Heroku with a Docker-based deployment is best for this organization. But how would you or I make such a decision?</p><h2 id="the-3-step-process-to-make-the-decision">The 3 step process to make the decision</h2><p>If you have been developing Shiny apps, you might already have your preferred way of deployment. But as your needs evolve, you will identify additional requirements and might find that your go-to option is not the best anymore. Then you&apos;ll do some research and find the next option.</p><p>If you are not yet familiar with Shiny hosting options, you still need to make an informed choice at some point, so that you are not wasting your time and effort on something that will not serve you well over the long run. Here is the 3 step process that you can follow to help you with this decision.</p><p>Before you begin take a piece of paper.</p><h3 id="1-start-with-the-why">1. Start with the why</h3><p><strong>Why do you want the app or apps deployed? </strong>Are you building a portfolio to boost your career? Are you deploying useful apps for stakeholders or clients of your organization? Are you trying to sell an app as a software-as-a-service (SaaS) offering?</p><p>Write down your answer.</p><p>Getting clear on the why is the most important question. You might even realize that <strong>you don&apos;t need to host</strong> your Shiny app. For example, your app might be used on a laptop as a GUI to analyze data by non-specialists in the field without internet or cell coverage. In this case, no need to move on to step 2, because all you need is to <a href="https://hosting.analythium.io/run-shiny-apps-locally/">run Shiny locally</a>.</p><p>However, if your answer makes it clear to you that your users will be accessing the app over the Internet, move on to step 2.</p><h3 id="2-list-your-requirements">2. List your requirements</h3><p>Answering the Why question will probably reveal important details about your motivations, your audience, the number of apps you are going to host, etc. The answer will also bring you closer to identifying the <strong>requirements</strong> that you&apos;ll need.</p><p>For example, do you need a custom domain, how many users are you expecting, do you need authentication or app-level authorization? Do you want to host a single app or do you need to host many apps? Will you host non-Shiny apps?</p><p>Write these down too.</p><p>The following table lists the important features for many different <strong>Shiny hosting options</strong>. The table lists tiers offered by the same company as a separate option. Use this table to find the options that meet your requirements. For now, just ignore the columns inside the blue rectangle.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://hosting.analythium.io/content/images/2021/10/Screen-Shot-2021-10-31-at-1.22.51-PM.png" class="kg-image" alt="How to Pick the Right Hosting Option for Your Shiny App" loading="lazy" width="2000" height="774" srcset="https://hosting.analythium.io/content/images/size/w600/2021/10/Screen-Shot-2021-10-31-at-1.22.51-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/10/Screen-Shot-2021-10-31-at-1.22.51-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/10/Screen-Shot-2021-10-31-at-1.22.51-PM.png 1600w, https://hosting.analythium.io/content/images/2021/10/Screen-Shot-2021-10-31-at-1.22.51-PM.png 2378w" sizes="(min-width: 720px) 720px"><figcaption>Feature matrix comparing Shiny hosting options</figcaption></figure><p>If you crave a more interactive experience, I made a filterable version:</p><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/iGKQMKuz-ww?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>Here is the link to the page where you can filter the options:</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://hosting.analythium.io/assets/files/shiny-hosting-options.html"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Shiny Hosting Options</div><div class="kg-bookmark-description">Pick the right hosting option for your Shiny app</div><div class="kg-bookmark-metadata"><span class="kg-bookmark-author">Hosting Data Apps</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://hosting.analythium.io/content/images/2021/10/shiny-hosting-options-1.png" alt="How to Pick the Right Hosting Option for Your Shiny App"></div></a></figure><p>Once you filter the table according to your requirements, you&apos;ll see a list of your <strong>ideal hosting options</strong>. Put these in the file or onto the paper too. </p><h3 id="3-identify-your-constraints">3. Identify your constraints</h3><p>The last step involves identifying your <strong>constraints</strong>:</p><ul><li>What is your <strong>budget</strong>?</li><li>What is your current <strong>skill level</strong>?</li><li>How much time do you have <strong>time</strong>?</li></ul><p>Recognizing these constraints will guide you toward an <strong>optimal solution</strong>. This is the point where the columns inside the blue rectangle come in.</p><p>The &quot;<strong>Total Cost</strong>&quot; of ownership (USD/year) covers licensing fees and operating costs for the &quot;Number of Apps&quot; listed in the table. Prices range quite a bit from free to the tens of thousands. Price increases with performance and with the availability of enterprise features, such as custom domains and authentication.</p><p><strong>PaaS</strong> means platform-as-a-service, i.e. it is a fully managed system without you having to worry about the underlying infrastructure. This also means less control over the infrastructure, i.e. when it comes to choosing the <strong>data region</strong> where your app is served from.</p><p><strong>Unlimited app hours</strong> are more common for self-hosted options or paid PaaS plans including a single app. The need to host <strong>multiple apps</strong> will involve some compromises. The ability to host <strong>non-Shiny apps</strong> (Dahs, Streamlit, etc.) is a feature for RStudio Connect and the Docker-based options (<a href="https://shiny.rstudio.com/py/docs/deploy.html?ref=hosting.analythium.io">Shinyapps and Shiny Server can host Shiny for Python</a>).</p><p><strong>Time</strong> as a constraint will depend on how far your current skill level is from the level needed for a specific hosting option. You also have to consider that some options are fully managed PaaS offerings, others you have to manage, or learn how to use Docker.</p><p>If you have to develop <strong>new skills</strong>, it might take longer. If you have to manage your servers, it will take more time to get started and then you are on the hook for maintaining your setup.</p><p>Make your selections inside the columns within the blue area. </p><h3 id="you-are-done">You are done!</h3><p>After the 3-step process, you should see only a few or a single option left. Click on the name of the hosting option and the link will take you to the relevant tag page on the Hosting Data Apps website:</p><ul><li>Follow the instructions in the <strong>tutorials</strong> to get started</li><li>At the end of each post, you&apos;ll find a <em>Further reading</em> section listing <strong>additional resources</strong></li></ul><p>If there is no option left in the table, then you might need to be more realistic about your expectations or relax some of your constraints. For example, to keep costs low, you could spend more time and invest in skill development. But if you have more room in your budget, you might choose a different path. You can also revise your requirements until you find an acceptable solution.</p><h2 id="options-at-a-glance">Options at a glance</h2><p>The following diagram gives an intuitive overview of the different options. The vertical axis represents the <strong>total cost</strong> from the table above: free, low, and high cost. The horizontal axis shows a <strong>range of skills</strong> you need to <a href="https://hosting.analythium.io/the-taxonomy-of-shiny-hosting-options/">set up and manage your hosting solution</a>. It can be as simple as pushing a button, or as complex as managing servers or cloud clusters.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://hosting.analythium.io/content/images/2022/09/2022.png" class="kg-image" alt="How to Pick the Right Hosting Option for Your Shiny App" loading="lazy" width="2000" height="2000" srcset="https://hosting.analythium.io/content/images/size/w600/2022/09/2022.png 600w, https://hosting.analythium.io/content/images/size/w1000/2022/09/2022.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2022/09/2022.png 1600w, https://hosting.analythium.io/content/images/2022/09/2022.png 2312w" sizes="(min-width: 720px) 720px"><figcaption>Costs and complexity associated with different Shiny hosting options</figcaption></figure><p>The hosting options in this diagram are not separated by tiers but rather shown as spanning over a range. The fill colours identify Docker and non-Docker-based options, the stroke styling indicates the PaaS solutions.</p><div class="kg-card kg-callout-card kg-callout-card-yellow"><div class="kg-callout-emoji">&#x26A0;&#xFE0F;</div><div class="kg-callout-text">Starting November 28, 2022, free Heroku Dynos, free Heroku Postgres, and free Heroku Data for Redis will no longer be available &#x2013; see <a href="https://hello.heroku.com/e/36622/-heroku-free-product-plans-faq/m49jd4/1138553151?h=KeNZWXMYkD7V9c11YSkM3-wKpW2ysvxg12dL3_hgXRk&amp;ref=hosting.analythium.io">this FAQ</a> for details.</div></div><h2 id="what-is-next">What is next</h2><p>If you followed the 3-step process to collect all the information you need, it is likely that you have found an option that is best for your needs. Now go ahead and learn more about that option, deploy, and start hosting your app.</p><p>Shiny is a very popular interactive data application framework. As a result, <strong>new hosting options</strong> are popping up every time. As the number of these hosting options grows in the future, I might update this post by adding the new contenders to the table.</p><p>If you know a Shiny hosting option that is not listed in the table, add that to this form so that I can include it next time!</p><!--kg-card-begin: html--><div id="my-reform"></div>

<script>window.Reform=window.Reform||function(){(Reform.q=Reform.q||[]).push(arguments)};</script>
<script id="reform-script" async src="https://embed.reform.app/v1/embed.js"></script>
<script>
    Reform('init', {
        url: 'https://forms.reform.app/analythium/hosting-what-is-next',
        target: '#my-reform',
    })
</script><!--kg-card-end: html--><p></p>]]></content:encoded></item><item><title><![CDATA[Auto deploy Shiny app changes to the DigitalOcean App Platform]]></title><description><![CDATA[Integrate the DigitalOcean App Platform with GitHub for automated deployment of your Shiny app.]]></description><link>https://hosting.analythium.io/auto-deploy-shiny-app-changes-to-the-digitalocean-app-platform/</link><guid isPermaLink="false">61469ec06e829c45bdb961d2</guid><category><![CDATA[DO App Platform]]></category><category><![CDATA[Shiny]]></category><category><![CDATA[Docker]]></category><category><![CDATA[CICD]]></category><dc:creator><![CDATA[Peter Solymos]]></dc:creator><pubDate>Thu, 30 Sep 2021 12:00:00 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1569313888792-5483b9b43fc0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDJ8fGdlYXJib3h8ZW58MHx8fHwxNjMyMDI1MDA4&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1569313888792-5483b9b43fc0?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=MnwxMTc3M3wwfDF8c2VhcmNofDJ8fGdlYXJib3h8ZW58MHx8fHwxNjMyMDI1MDA4&amp;ixlib=rb-1.2.1&amp;q=80&amp;w=2000" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform"><p>I introduced the DigitalOcean App Platform in a previous post and described how to <a href="https://hosting.analythium.io/how-to-host-shiny-apps-on-the-digitalocean-app-platform/">deploy Shiny apps from existing Docker images</a> using the control panel or the command line.</p><p>This post continues the App Platform discussion by looking at how to integrate the App Platform with GitHub and set up continuous integration and deployment (CICD).</p><h2 id="prerequisites">Prerequisites</h2><p>If you have not done so before, go to the <a href="https://www.digitalocean.com/products/app-platform/?ref=hosting.analythium.io" rel="noreferrer noopener">App Platform</a> landing page and sign up for a DigitalOcean account. Log into your account and go to your dashboard. In the left drawer, click on &apos;Apps&apos;.</p><p>For the <a href="https://github.com/analythium/app-platform-shiny?ref=hosting.analythium.io">analythium/app-platform-shiny</a> repository because you will have to give permissions to access the repo.</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://github.com/analythium/app-platform-shiny?ref=hosting.analythium.io"><div class="kg-bookmark-content"><div class="kg-bookmark-title">GitHub - analythium/app-platform-shiny: DigitalOcean App Platform Example for Shiny</div><div class="kg-bookmark-description">DigitalOcean App Platform Example for Shiny. Contribute to analythium/app-platform-shiny development by creating an account on GitHub.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://github.com/fluidicon.png" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform"><span class="kg-bookmark-author">GitHub</span><span class="kg-bookmark-publisher">analythium</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://opengraph.githubassets.com/e31a1ee60efbddcfd66e8c3e848e1122179b5bbae69bae45a6aeec208ac21224/analythium/app-platform-shiny" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform"></div></a></figure><p>Here is what&apos;s inside the repo:</p><pre><code class="language-bash">.
&#x251C;&#x2500;&#x2500; .do
&#x2502;&#xA0;&#xA0; &#x251C;&#x2500;&#x2500; app.yaml
&#x2502;&#xA0;&#xA0; &#x2514;&#x2500;&#x2500; deploy.template.yaml
&#x251C;&#x2500;&#x2500; app
&#x2502;&#xA0;&#xA0; &#x251C;&#x2500;&#x2500; global.R
&#x2502;&#xA0;&#xA0; &#x251C;&#x2500;&#x2500; server.R
&#x2502;&#xA0;&#xA0; &#x2514;&#x2500;&#x2500; ui.R
&#x251C;&#x2500;&#x2500; .gitignore
&#x251C;&#x2500;&#x2500; Dockerfile
&#x251C;&#x2500;&#x2500; LICENSE
&#x251C;&#x2500;&#x2500; README.md
&#x2514;&#x2500;&#x2500; renv.lock</code></pre><p>The <code>.do</code> folder contains a template file that is needed if you want to deploy the Shiny app template from the button in the <code>README</code> file. The <a href="https://hosting.analythium.io/how-to-host-shiny-apps-on-the-digitalocean-app-platform/">app specification</a> (<code>app.yaml</code>) that was introduced before, but it is largely simplified:</p><pre><code class="language-yaml">name: app-platform-shiny
services:
- dockerfile_path: Dockerfile
  github:
    branch: main
    deploy_on_push: true
    repo: analythium/app-platform-shiny
  name: app-platform-shiny
</code></pre><p>The <code>app</code> folder contains <a href="https://hosting.analythium.io/run-shiny-apps-locally/#multiple-files">multiple files for the Shiny app</a>. The <code>Dockerfile</code> uses the <a href="https://hosting.analythium.io/dockerized-shiny-apps-with-dependencies/#use-the-renv-r-package">renv package to handle the dependencies</a> specified in the <code>renv.lock</code> file.</p><p>The app itself, as you will see, is a relatively simple example with some range slider, a dependency that does not require building from source. It also has a file upload button &#x2013; I use the upload functionality to test when a large file upload is required. Large file upload is often restricted, <a href="https://mastering-shiny.org/action-transfer.html?ref=hosting.analythium.io">Shiny itself has a 5 Mb file size limit</a>.</p><h2 id="github-integration">GitHub integration</h2><p>Let&apos;s set up the GitHub integration. Go to the DigitalOcean control panel In your control panel. Click on &apos;Launch New App&apos; under the &apos;App&apos; item in the left side menu:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-17-at-11.41.14-PM-1.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1301" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-17-at-11.41.14-PM-1.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-17-at-11.41.14-PM-1.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-17-at-11.41.14-PM-1.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-17-at-11.41.14-PM-1.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>When you are asked to choose a source, click on the GitHub icon:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-17-at-11.41.27-PM-2.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1301" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-17-at-11.41.27-PM-2.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-17-at-11.41.27-PM-2.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-17-at-11.41.27-PM-2.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-17-at-11.41.27-PM-2.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>Follow the prompts and install the GitHub app for your personal account or the organization of your choice. Select &apos;All repositories&apos; or &apos;Only select repositories&apos; as appropriate. Finally, click &apos;Save&apos;:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-8.31.03-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1194" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-8.31.03-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-8.31.03-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-8.31.03-PM.png 1600w, https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-8.31.03-PM.png 2020w" sizes="(min-width: 720px) 720px"></figure><h2 id="deploy-from-github-repository">Deploy from GitHub repository</h2><p>Now go back to the Apps control panel. Select the repository from the dropdown menu, specify the branch you wish to deploy. If you want to deploy both a development and a production version of the same repository, you can create multiple apps with the same repo but using different branches.</p><p>Leave &apos;autodeploy&apos; checked if you want to trigger new deployments when the code changes, then click &apos;Next&apos;:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-8.33.35-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1293" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-8.33.35-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-8.33.35-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-8.33.35-PM.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-18-at-8.33.35-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>Review the app settings inferred from the <code>Dockerfile</code>, i.e. the HTTP port, etc.:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-8.37.49-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1293" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-8.37.49-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-8.37.49-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-8.37.49-PM.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-18-at-8.37.49-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>Type in the name of the service, select the data region, then click &apos;Next:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-8.38.09-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1293" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-8.38.09-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-8.38.09-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-8.38.09-PM.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-18-at-8.38.09-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>The final step lets you define the performance of the app and the corresponding pricing. Here I use the smallest size under the &apos;Basic&apos; plan for $5 US per month: </p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-8.38.32-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1293" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-8.38.32-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-8.38.32-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-8.38.32-PM.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-18-at-8.38.32-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>After a few minutes, you should see the green checks besides the build and deployment log entries. Building the image might take some time, depending on the number of dependencies in your app:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-9.48.00-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1293" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-9.48.00-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-9.48.00-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-9.48.00-PM.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-18-at-9.48.00-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>Follow the app URL from the control panel to see the app online served over HTTPS:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-9.50.51-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1293" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-9.50.51-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-9.50.51-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-9.50.51-PM.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-18-at-9.50.51-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><h2 id="add-a-custom-domain">Add a custom domain</h2><p>Adding a custom domain is done via the control panel. Click &apos;Add Domain&apos;:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-9.55.41-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1293" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-9.55.41-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-9.55.41-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-9.55.41-PM.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-18-at-9.55.41-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>Follow the prompts and copy the app URL:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-9.57.59-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1293" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-9.57.59-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-9.57.59-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-9.57.59-PM.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-18-at-9.57.59-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>Add a CNAME record in your DNS settings on your DNS providers page (Google Domains shown here), make it point to a domain or subdomain of yours:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-9.57.03-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy"></figure><p>You will see the custom domain listed in the app settings:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-10.01.47-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1293" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-10.01.47-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-10.01.47-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-10.01.47-PM.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-18-at-10.01.47-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>Click on your new custom domain link and check. You might have to wait a bit if your record has not propagated through the name servers:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-10.01.17-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1293" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-10.01.17-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-10.01.17-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-10.01.17-PM.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-18-at-10.01.17-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><h2 id="auto-deploy-updates">Auto deploy updates</h2><p>Next, we will make some changes to the Shiny app and see the app magically update via git. Do it in your forged repo. The small change I made was to edit the app title. Here is the change:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-10.05.00-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="1616" height="1176" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-10.05.00-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-10.05.00-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-10.05.00-PM.png 1600w, https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-10.05.00-PM.png 1616w" sizes="(min-width: 720px) 720px"></figure><p>Once you commit the changes and push to GitHub, it triggers the web-flow pipeline. The new deployment is then listed in the deployment history of your app:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-10.09.35-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1293" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-10.09.35-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-10.09.35-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-10.09.35-PM.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-18-at-10.09.35-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>Visit the custom URL and see the new version deployed:</p><figure class="kg-card kg-image-card"><img src="https://hosting.analythium.io/content/images/2021/09/Screen-Shot-2021-09-18-at-10.10.00-PM.png" class="kg-image" alt="Auto deploy Shiny app changes to the DigitalOcean App Platform" loading="lazy" width="2000" height="1293" srcset="https://hosting.analythium.io/content/images/size/w600/2021/09/Screen-Shot-2021-09-18-at-10.10.00-PM.png 600w, https://hosting.analythium.io/content/images/size/w1000/2021/09/Screen-Shot-2021-09-18-at-10.10.00-PM.png 1000w, https://hosting.analythium.io/content/images/size/w1600/2021/09/Screen-Shot-2021-09-18-at-10.10.00-PM.png 1600w, https://hosting.analythium.io/content/images/size/w2400/2021/09/Screen-Shot-2021-09-18-at-10.10.00-PM.png 2400w" sizes="(min-width: 720px) 720px"></figure><p>Don&apos;t forget to delete the app and the CNAME record if you don&apos;t need them anymore to avoid accruing hosting charges. Dynamic app hosting is not free on DigitalOcean.</p><h2 id="testing-before-deployment">Testing before deployment</h2><p>One potential issue with this GitHub integration is it <a href="https://www.digitalocean.com/community/questions/app-platform-wait-for-tests-to-pass-before-deploying?ref=hosting.analythium.io">does not depend on passing tests before deployment</a>. If you want to test your changes before deployment, here are the steps to follow:</p><ol><li>push changes to the development branch,</li><li>run automated tests for the development branch, e.g. using GitHub actions,</li><li>set up the production branch as a protected branch, so that <a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests?ref=hosting.analythium.io">merging pull requests require passing tests</a>.</li></ol><h2 id="conclusions">Conclusions</h2><p>When we deployed an exiting Docker image, the image was pulled to the App Platform from Docker Hub. In this case, an immutable image was pushed and pulled. </p><p>The GitHub integration described here takes a different approach. It builds the Docker image after changes are pushed to a pre-defined branch in the GitHub repository. The image is built and stored in the <a href="https://www.digitalocean.com/products/container-registry/?ref=hosting.analythium.io">DigitalOcean Container Registry</a>.</p><p>With this approach, you get a new deployment on every git push event. You can debate how much this automated deployment (CD) can be considered continuous integration and deployment (CICD) without actually having the CI part.</p><p>Testing the app before deployment requires additional steps as part of your git workflow. To achieve full CICD experience, you can use the <code><a href="https://hosting.analythium.io/how-to-host-shiny-apps-on-the-digitalocean-app-platform/#programmatic-image-deployment">doctl</a></code><a href="https://hosting.analythium.io/how-to-host-shiny-apps-on-the-digitalocean-app-platform/#programmatic-image-deployment"> command-line utility</a> in GitHub Actions. As it turns out, this route is a bit more involved and there are several gotchas to address. Thus, I will explain it in a follow-up post.</p><h2 id="further-reading">Further reading</h2><ul><li><a href="https://docs.digitalocean.com/products/app-platform/?ref=hosting.analythium.io" rel="noreferrer noopener">App Platform documentation</a></li><li><a href="https://docs.digitalocean.com/products/app-platform/how-to/deploy-from-monorepo/?ref=hosting.analythium.io">Deploy app from a monorepo</a></li><li><a href="https://docs.digitalocean.com/products/app-platform/how-to/troubleshoot-app/?ref=hosting.analythium.io">Troubleshoot your app</a></li></ul>]]></content:encoded></item></channel></rss>