<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Build Automation &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/build-automation/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Tue, 25 Feb 2025 21:31:05 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Xojo GitHub Actions</title>
		<link>https://blog.xojo.com/2022/10/19/xojo-github-actions/</link>
		
		<dc:creator><![CDATA[Jürg Otter]]></dc:creator>
		<pubDate>Wed, 19 Oct 2022 12:30:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Build Automation]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=10874</guid>

					<description><![CDATA[Would you like to automate the build processes of Xojo built applications with GitHub Actions? With no user interaction the whole process can be performed:&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Would you like to automate the build processes of Xojo built applications with GitHub Actions? With no user interaction the whole process can be performed: Build all Targets, CodeSign Windows executables, create and sign the installers, package the macOS app in a .dmg and notarize the app, and for Linux create a .tgz package.</p>



<figure class="wp-block-image size-full is-style-default"><img fetchpriority="high" decoding="async" width="1200" height="705" src="https://blog.xojo.com/wp-content/uploads/2022/10/1_Beta-Build.gif" alt="beta build GitHub actions with xojo" class="wp-image-10886"/></figure>



<h2 class="wp-block-heading">What are GitHub Actions?</h2>



<p>If you want to read all about it &#8211; head over to their <a href="https://docs.github.com/en/actions">documentation</a>. To get started, you should at least know about the following terms:</p>



<h3 class="wp-block-heading"><strong>Workflow</strong></h3>



<p>A workflow is a configurable automated process that will run one or more jobs. Workflows are defined by a YAML file checked in to your repository.&nbsp;</p>



<h3 class="wp-block-heading"><strong>Job</strong></h3>



<p>A job is a set of steps in a workflow that execute on the same runner. Each step is either a shell script that will be executed, or an action that will be run.</p>



<h3 class="wp-block-heading"><strong>Runner</strong></h3>



<p>A runner is a machine that runs your workflows when they&#8217;re triggered. GitHub provides <a href="https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources">ready to use runners</a> as preconfigured virtual machines. And of course you can <a href="https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners">host your own runners</a>.</p>



<p>A GitHub Actions workflow can be configured to be triggered when an event occurs in the repository. So how to leverage that? Let&#8217;s talk about the Git Branching strategy that I&#8217;m going to use in this example first.</p>



<h2 class="wp-block-heading">Git Branching Strategy</h2>



<p>Using GitHub obviously means the one is using Git as Source Control. There are quite a few common strategies and workflows to use Git. For this example I&#8217;ll be using the following:</p>



<ul class="wp-block-list"><li>Default Branch: main<br>I want to make sure that all code in the main branch can be compiled at all times. Every push (or Pull Request against the main branch) should automatically build a Beta Version of the app.<br>At some time I want to use the latest commit to build a final version of the application.</li><li>Feature branches: feature/xyz<br>To start working on a new feature or bug fix, I&#8217;ll create a feature branch. As I often commit I don&#8217;t want to build every single commit. There might be commits with &#8220;work in progress&#8221; which won&#8217;t even compile.<br>Once ready: I create a Pull Request against the main branch.</li><li>Pull Request <em>(against main branch)</em><br>This means a feature or bug fix is ready. So a GitHub Action should kick in and build the app. If that fails it simply means the feature isn&#8217;t ready for the main branch. The built Beta Version can be downloaded to do some more manual tests before merging into the main branch.<br>Once the Pull Request is merged <em>(always using a squash commit)</em>, this will result in a single commit to the main branch (of the whole new feature). Same procedure: a Beta of the app is automatically built and ready for to download and test.</li><li>Release a Final Build<br>After adding couple of new features and bug fixes I want to release a final version.<br>Whenever I feel ready, a GitHub Actions Workflow can be started manually. That will build a Final Version, create a Release in the GitHub Repository and upload all Builds to the Release as Assets.</li></ul>



<p>A bit of information before starting to write the <a href="https://docs.github.com/en/actions/using-workflows">GitHub Actions Workflows</a>:</p>



<h2 class="wp-block-heading"><strong>About Workflows</strong></h2>



<p>Workflows are defined by a YAML file checked in to the repository in the .github/workflows directory.</p>



<figure class="wp-block-image size-large is-style-default"><img decoding="async" width="1024" height="234" src="https://blog.xojo.com/wp-content/uploads/2022/10/2_Workflows-yaml-1024x234.png" alt="" class="wp-image-10879" srcset="https://blog.xojo.com/wp-content/uploads/2022/10/2_Workflows-yaml-1024x234.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/10/2_Workflows-yaml-300x69.png 300w, https://blog.xojo.com/wp-content/uploads/2022/10/2_Workflows-yaml-768x176.png 768w, https://blog.xojo.com/wp-content/uploads/2022/10/2_Workflows-yaml-1536x351.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/10/2_Workflows-yaml-2048x469.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading"><strong>YAML files</strong></h3>



<p>A word of precaution when writing and editing YAML files:</p>



<ul class="wp-block-list"><li>Indentation is done by spaces (not by tabs!)</li><li>Indentation has to be exact, or expect to get syntax errors</li></ul>



<h2 class="wp-block-heading"><strong>Xojo GitHub Actions Workflows</strong></h2>



<p>According to the Git Branching Strategy I want to build Beta Releases <em>(on Pull Requests and on Push to the main branch)</em>, and I want to manually create a Release with a Final Build.</p>



<p>This means that there will be two Workflows:</p>



<ul class="wp-block-list"><li><strong>Beta Build</strong></li><li><strong>Create Release</strong></li></ul>



<p>They have something in common. Both need to build the Xojo project and execute the postbuild steps. To avoid duplication I&#8217;m going to write a <a href="https://docs.github.com/en/actions/using-workflows/reusing-workflows">reusable workflow</a>:</p>



<ul class="wp-block-list"><li><strong>Xojo</strong> <em>(Build and PostBuild)</em></li></ul>



<p>A workflow <em>(Beta Build | Create Release)</em> that uses another workflow <em>(Xojo Build and PostBuild)</em> is referred to as a &#8220;caller&#8221; workflow. The reusable workflow is a &#8220;called&#8221; workflow.</p>



<p>This ScreenShot shows the Beta Build workflow which calls the reusable Xojo workflow:</p>



<figure class="wp-block-image size-large is-style-default"><img decoding="async" width="1024" height="403" src="https://blog.xojo.com/wp-content/uploads/2022/10/3_Workflow-Run-1024x403.png" alt="" class="wp-image-10880" srcset="https://blog.xojo.com/wp-content/uploads/2022/10/3_Workflow-Run-1024x403.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/10/3_Workflow-Run-300x118.png 300w, https://blog.xojo.com/wp-content/uploads/2022/10/3_Workflow-Run-768x302.png 768w, https://blog.xojo.com/wp-content/uploads/2022/10/3_Workflow-Run-1536x605.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/10/3_Workflow-Run-2048x806.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p>The Create Release workflow looks similar during it&#8217;s run. It can be started manually on GitHub.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" width="1200" height="694" src="https://blog.xojo.com/wp-content/uploads/2022/10/4_Create-Release.gif" alt="create release with GitHub actions and xojo" class="wp-image-10894"/></figure>



<p>Once finished, a new Release is available in the GitHub repository:</p>



<figure class="wp-block-image size-large is-style-default"><img loading="lazy" decoding="async" width="1024" height="547" src="https://blog.xojo.com/wp-content/uploads/2022/10/5_CreateRelease-Final-1024x547.png" alt="" class="wp-image-10881" srcset="https://blog.xojo.com/wp-content/uploads/2022/10/5_CreateRelease-Final-1024x547.png 1024w, https://blog.xojo.com/wp-content/uploads/2022/10/5_CreateRelease-Final-300x160.png 300w, https://blog.xojo.com/wp-content/uploads/2022/10/5_CreateRelease-Final-768x410.png 768w, https://blog.xojo.com/wp-content/uploads/2022/10/5_CreateRelease-Final-1536x820.png 1536w, https://blog.xojo.com/wp-content/uploads/2022/10/5_CreateRelease-Final-2048x1093.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading">The Set Up</h2>



<p>There is quite a bit to do:</p>



<ul class="wp-block-list"><li>Set up a <strong>Build Mac</strong><br>A Mac of our own is needed. The reason for that is that Xojo isn&#8217;t set up on GitHub&#8217;s virtual macOS machines <em>(one would need to download and install it every single time)</em>. And even if it were, we would need to setup and register Xojo with a License. And Xojo Licenses take a seat on every machine &#8211; so no good idea for a fresh virtual machine on every build.</li><li>Create a <strong>Xojo IDE Communicator</strong><br>Build Automation with Xojo requires to communicate with the Xojo IDE. I&#8217;m going to use the project that Xojo ships in the examples, but modify it a bit.</li><li>Configure the <strong>GitHub Repository Settings</strong><br>There are settings to enforce the chosen Git Branching Strategy. And there are some settings for GitHub Actions that need to be set up.</li><li>Set up a <strong>self-hosted GitHub runner</strong><br>Install the GitHub runner on the Build Mac and link it to the repository.</li><li><strong>Xojo Project</strong> and <strong>Post Build Scripts</strong><br>I&#8217;m going to add a PreBuild Xojo Script. And of course all Post Build Scripts regarding CodeSigning, Installer creation, packaging, Notarization.</li><li>GitHub Actions: <strong>Secrets</strong><br>CodeSigning means certificates and passwords. They get their safe place in the repository Secrets.</li><li>GitHub Actions: <strong>Workflows</strong><br>Once everything is in place&#8230; one can finally start writing the actual workflows.</li></ul>



<p>As you can imagine, guiding you through all these steps is going to be quite a lengthy article.</p>



<h2 class="wp-block-heading"><strong>Source Code &amp; Documentation</strong></h2>



<p>Should you consider using GitHub Actions with your own Xojo projects, then have a look at this repository: <a href="https://github.com/jo-tools/xojo-github-actions">GitHub: jo-tools/xojo-github-actions</a></p>



<p>It contains the full documentation, the source of the modified Xojo IDE Communicator, an Example Xojo Project &#8211; and of course all the GitHub Actions Workflows.</p>



<p>I hope this gives you a lot of helpful hints, ideas and approaches so that you get a head start to get your Xojo Projects built using GitHub Actions Workflows.</p>



<h2 class="wp-block-heading"><strong>That&#8217;s all Folks!</strong></h2>



<p>I hope this brief introduction of how Build Automation for Xojo built Application can be used with GitHub Actions Workflows has been helpful to some, food for thought to others.</p>



<p><em>Jürg Otter is a long term user of Xojo and working for </em><a href="https://www.cmiag.ch/"><em>CM Informatik AG</em></a><em>. Their Application </em><a href="https://cmi-bildung.ch/"><em>CMI LehrerOffice</em></a><em> is a Xojo Design Award Winner 2018. In his leisure time Jürg provides some </em><a href="https://www.jo-tools.ch/xojo/"><em>bits and pieces for Xojo Developers</em></a><em>.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Automated Testing: How We Test Xojo Builds</title>
		<link>https://blog.xojo.com/2021/12/17/automated-testing-how-we-test-xojo-builds/</link>
		
		<dc:creator><![CDATA[Geoff Perlman]]></dc:creator>
		<pubDate>Fri, 17 Dec 2021 22:04:03 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Cross-Platform]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Automated Builds]]></category>
		<category><![CDATA[Automation]]></category>
		<category><![CDATA[Build Automation]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Multi-Platform Development]]></category>
		<category><![CDATA[Rapid Application Development]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Xojo Programming Language]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=9831</guid>

					<description><![CDATA[Xojo has an extensive testing period where actual users test a pre-release version with their projects but if you are wondering what kind of testing we do internally before each pre-release of Xojo, we have quite a bit of automated testing processes. There are over 400 tests just for the compiler alone. Already, we are approaching 300 tests for our Android framework. In total, across all supported platforms, there are over 2500 automated tests. ]]></description>
										<content:encoded><![CDATA[
<p>Xojo has an extensive testing period where actual users test a pre-release version with their projects but if you are wondering what kind of testing we do internally before each pre-release of Xojo,&nbsp;we have quite a bit of automated testing processes. There are over 400 tests just for the compiler alone. Already, we are approaching 300 tests for our Android framework. In total, across all supported platforms, there are over 2500 automated tests. Most tests run every time we do a full build of Xojo (also a fully automated process) which occurs 2 to 5 times a week. When one of these tests fails, the unlucky engineer responsible is informed and gets to work fixing it. More automated tests are being added to our system regularly.</p>



<p>Primarily, <a href="https://blog.xojo.com/2020/09/29/how-do-we-decide-what-goes-into-xojo/\">we focus</a> on the issues having the greatest impact on the Xojo community. However, that focus is not absolute. The engineering team at Xojo is using Xojo all-day, every day. They will often catch bugs in the early stages of the development of a new feature or as a side effect of fixing some other bug, long before that release gets to pre-release testers. The number of combinations of interactions between various parts of the Xojo frameworks is effectively infinite and no system can test everything. That&#8217;s why pre-release testing by actual users is so important. When you look at the bugs that are reported, 95.6% have only one user reporting them. Though we provide, in fact require, users to search Feedback before submitting a case, users often describe the same bug in varying ways resulting in&nbsp;duplicates. Given both the infinite number of interactions and some number of duplicate reports, the fact that overwhelming majority of reports have just one user is understandable. That we focus on the reports that have multiple users is also understandable. And of course there are exceptions, if it&#8217;s obvious that a new bug is going to effect a lot of users, we will get to work on it ASAP.&nbsp;In addition, if an engineer is working in a particular part of the IDE or a particular framework, since they have take the time to refamiliarize themselves with that code, they will often look for bugs that have been reported against it.&nbsp;</p>



<p>Development tools are special because the type of people who use them are more likely to report bugs and are more likely to want to search the list of open cases, get updates about bugs and more. While it&#8217;s important to report bugs, and we can’t stress enough how much we appreciate the time and care you take in doing so, even if the bug is fixed, you still have to wait for the release in which it&#8217;s fixed. Even our engineers have to wait for bugs fixes just like you do. Still, when you run into a bug, please search <a href="http://www.xojo.com/download">Feedback</a> first to see if it&#8217;s been reported, perhaps think of a few ways it could have been reported and do a few searches. If you find a match, add yourself to the case. If you don&#8217;t, please file a case. If you haven&#8217;t found a workaround, ask on the <a href="https://forum.xojo.com/">forum</a> or contact us directly and we see what we can do to help. </p>



<p>There is a lot of automated testing that goes on before we put out a pre-release to Testers. And we will continue to add more because automated testing is a terrific and efficient way to test anything that can be automatically tested. We are always on the lookout for ways to improve efficiency in our processes. </p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Xojo Projects in a MonoRepo</title>
		<link>https://blog.xojo.com/2021/08/19/xojo-projects-in-a-monorepo/</link>
		
		<dc:creator><![CDATA[Jürg Otter]]></dc:creator>
		<pubDate>Thu, 19 Aug 2021 14:00:00 +0000</pubDate>
				<category><![CDATA[Community]]></category>
		<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Build Automation]]></category>
		<category><![CDATA[MonoRepo]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=8902</guid>

					<description><![CDATA[Are you working on a solution consisting of several projects? Are you working in a team or as a single developer and want to share code between different projects? If so, then a MonoRepo could be something to think about.]]></description>
										<content:encoded><![CDATA[
<p>Are you working on a solution consisting of several projects? Are you working in a team or as a single developer and want to share code between different projects? If so, then a MonoRepo could be something to think about.</p>



<p>Other IDE&#8217;s have a concept of a solution or workspace consisting of several projects, and you can leverage packages in order to share code between projects. That&#8217;s not as simple as one might think with Xojo. The Xojo Documentation <a href="https://documentation.xojo.com/topics/code_management/sharing_code_among_multiple_projects.html">«Sharing Code»</a> explains three different ways: Copy &amp; Paste between projects, Export/Import Items and as a last option there are External Items.</p>



<p>Copy &amp; Paste is the simplest way. The downside is that after making a fix in a shared code item, it needs to be copied and pasted again and again to all projects that are using it.</p>



<p>Export/Import Items as well as External Items allows to save project items such as Modules or Classes in Binary or XML Format. With a Version Control System such as SVN or Git one should obviously go for XML. However, many don&#8217;t quite like the XML project format. It is readable in plain text, but not as clean and easy compared to Xojo&#8217;s Text format.</p>



<p>Which one would you prefer to read when looking at changes, diffs, conflicts?</p>



<ul class="wp-block-list"><li>On the left: «Xojo XML project format» (*.xojo_xml_project)</li><li>On the right: «Xojo Text project format» (*.xojo_project)</li></ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="475" src="https://blog.xojo.com/wp-content/uploads/2021/07/1_XML-Text-1024x475.png" alt="" class="wp-image-8903" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/1_XML-Text-1024x475.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/07/1_XML-Text-300x139.png 300w, https://blog.xojo.com/wp-content/uploads/2021/07/1_XML-Text-768x356.png 768w, https://blog.xojo.com/wp-content/uploads/2021/07/1_XML-Text-1536x712.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/07/1_XML-Text.png 1824w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>I&#8217;d definitely want to use the <strong>Xojo Text project</strong> format. And I want multiple projects that share code such as Modules with Extension Methods and various helper Methods I&#8217;ve written over the years. Business Logic Classes can be used in console, desktop and web applications &#8211; again, there&#8217;s the need to share code.</p>



<p>So let&#8217;s see how this can be done with MonoRepo. But what is a MonoRepo?</p>



<h2 class="wp-block-heading">MonoRepo</h2>



<p>The name consists of two parts: «Mono» (meaning: single) and «Repo» (short for: Repository). What it means: it&#8217;s a software development strategy where code for multiple projects is stored in the same repository (and therefore in the same main folder).</p>



<h3 class="wp-block-heading"><strong>Advantages:</strong></h3>



<ul class="wp-block-list"><li><strong>Reuse Code:</strong> Functionality can be abstracted into shared Modules or Classes, and be included in multiple projects without the need of a package management system.</li><li><strong>Atomic Commits:</strong> When several projects work together, releases need to sync which versions work with each other. In a MonoRepo it&#8217;s all in one place. Once the projects are ready for an update, you can tag the current state. This will include the state of all dependent projects needed for that release. So no need to know which project in which version or state has been used in version X.</li><li><strong>Collaboration:</strong> Several developers can work on different projects. Shared code can be improved by all developers with the others (or other projects) benefitting, too.</li></ul>



<h3 class="wp-block-heading"><strong>Disadvantages:</strong></h3>



<ul class="wp-block-list"><li><strong>Access Control:</strong> With split repositories for each project, access to a project can be granted based upon need. A MonoRepo however allows read access to all software in the repository.</li><li><strong>Storage:</strong> A developer needs to check out the whole MonoRepo, even if one is working just on a single project included in the MonoRepo. Depending on the software being developed, this can be a significant amount of &#8220;not needed&#8221; storage space.</li></ul>



<h3 class="wp-block-heading"><strong>Personal Thoughts:</strong></h3>



<p>I like the MonoRepo setup because of Xojo&#8217;s support for cross-platform development. Everything is contained in a single repository/folder, all files are located relatively. So you cannot only move the MonoRepo folder to any location on your machine, but also to other machines &#8211; running the same or a different Operating System. Check out the Version Control Repository on your Windows working machine and start coding. Commit/Push the changes, switch to a Mac and check-out/pull the current branch you&#8217;re working on in order to do some platform specific tests. To me that&#8217;s much more convenient and efficient than Remote Debugging.</p>



<h2 class="wp-block-heading">Xojo Projects Setup</h2>



<p>Let&#8217;s see how we can set up a MonoRepo using Xojo. In this example we&#8217;re going to create two projects that share a Class and a Module. There are a few gotchas.</p>



<h3 class="wp-block-heading"><strong>Setup a New MonoRepo</strong></h3>



<p>All we&#8217;re doing is creating a folder: «xojo-projects-monorepo». In a real world situation you&#8217;d sooner or later make a Repository out of this folder in the Version Control System of your choice.</p>



<h3 class="wp-block-heading"><strong>Project One</strong></h3>



<p>Once I have created a new Project named «Project One» the first thing to be done in the Xojo IDE is:</p>



<ul class="wp-block-list"><li>Add a new project item: Folder</li><li>Name the folder according to the project, but in a way that is best represented on disk as a folder: «project_one»</li><li>Move all project items (App, Window1, MainMenuBar) in this folder</li></ul>



<p>That should look like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="577" src="https://blog.xojo.com/wp-content/uploads/2021/07/2_ProjectOne-1024x577.png" alt="" class="wp-image-8904" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/2_ProjectOne-1024x577.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/07/2_ProjectOne-300x169.png 300w, https://blog.xojo.com/wp-content/uploads/2021/07/2_ProjectOne-768x433.png 768w, https://blog.xojo.com/wp-content/uploads/2021/07/2_ProjectOne-1536x865.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/07/2_ProjectOne.png 2004w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Then let&#8217;s save this project as a «Xojo Project» (*.xojo_project) to the «MonoRepo folder»:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="481" src="https://blog.xojo.com/wp-content/uploads/2021/07/3_ProjectOne-saved-1024x481.png" alt="" class="wp-image-8905" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/3_ProjectOne-saved-1024x481.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/07/3_ProjectOne-saved-300x141.png 300w, https://blog.xojo.com/wp-content/uploads/2021/07/3_ProjectOne-saved-768x361.png 768w, https://blog.xojo.com/wp-content/uploads/2021/07/3_ProjectOne-saved.png 1420w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>What do we get to see?</p>



<ul class="wp-block-list"><li>Project_One.xojo_uistate: That&#8217;s the state configuration of the IDE when this project has been saved. In a VCS you can ignore the files «*.xojo_uistate» safely.</li><li>Build Automation.xojo_code: we&#8217;ll come back to that later.</li><li>Project_One.xojo_project: The main project file, containing the references to all included project items, which are stored as individual files.</li><li>Project_One.xojo_resources: This is a binary file containing the AppIcon, and similar resources.</li><li>Folder «project_one»: The folder we&#8217;ve just created. In there you&#8217;ll find the files of the project items you&#8217;ve moved in there: App.xojo_code, MainMenuBar.xojo_menu and Window1.xojo_window</li></ul>



<h3 class="wp-block-heading"><strong>Project Two</strong></h3>



<p>Let&#8217;s make this short. We&#8217;re doing the very same steps again, just for a «Project Two», with all project items in a folder «project_two».</p>



<p>Our MonoRepo now looks like this:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="642" src="https://blog.xojo.com/wp-content/uploads/2021/07/4_ProjectTwo-1024x642.png" alt="" class="wp-image-8906" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/4_ProjectTwo-1024x642.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/07/4_ProjectTwo-300x188.png 300w, https://blog.xojo.com/wp-content/uploads/2021/07/4_ProjectTwo-768x482.png 768w, https://blog.xojo.com/wp-content/uploads/2021/07/4_ProjectTwo.png 1134w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>So far, this is simple and clean. The main project files are in the root folder, all project related items are in their own project folder.</p>



<p>But hey &#8211; just one «Build Automation»? Yup&#8230; That&#8217;s a bit unfortunate. We&#8217;ll come back to that later.</p>



<h3 class="wp-block-heading"><strong>Shared Code</strong></h3>



<p>Now for the more interesting part. Let&#8217;s create a Class and a Module that we want to share in both Projects.</p>



<p><strong>In Project One</strong></p>



<ul class="wp-block-list"><li>add a new folder: «shared_code»</li><li>add a Module containing a Constant to the shared code folder: «MyModule»</li><li>add a Class containing a Method to the shared code folder: «MyClass»</li><li>Save the Xojo Project.</li></ul>



<p>The shared code folder and the to-be-shared project items are now saved as individual files/folders to disk:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="577" src="https://blog.xojo.com/wp-content/uploads/2021/07/5_SharedCode-1024x577.png" alt="" class="wp-image-8907" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/5_SharedCode-1024x577.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/07/5_SharedCode-300x169.png 300w, https://blog.xojo.com/wp-content/uploads/2021/07/5_SharedCode-768x433.png 768w, https://blog.xojo.com/wp-content/uploads/2021/07/5_SharedCode-1536x866.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/07/5_SharedCode.png 2000w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading"><strong>Add Shared Code to Project</strong> Two</h3>



<p>We now want to add this shared code to «Project Two».</p>



<p>On Windows you can do this using drag and drop: Drag the folder «shared_code» from Windows Explorer into the Navigator (left pane) of the Xojo IDE in «Project Two».</p>



<p>On macOS however, this will not work as expected. Due to a bug the project file will be corrupted since it&#8217;s saving wrong locations. To show you: I&#8217;ve done this and opened the «Project_Two.xojo_project» in a Text Editor:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="358" src="https://blog.xojo.com/wp-content/uploads/2021/07/6_macOS-Bug-1024x358.png" alt="" class="wp-image-8908" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/6_macOS-Bug-1024x358.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/07/6_macOS-Bug-300x105.png 300w, https://blog.xojo.com/wp-content/uploads/2021/07/6_macOS-Bug-768x269.png 768w, https://blog.xojo.com/wp-content/uploads/2021/07/6_macOS-Bug-1536x537.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/07/6_macOS-Bug.png 1698w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Oops&#8230; MyClass and MyModule have a weird location: ../../../</p>



<p>As a result, the project won&#8217;t load correctly.</p>



<p>That&#8217;s why I recommend the following steps:</p>



<ul class="wp-block-list"><li>Add any new folders manually in the Xojo IDE: In «Project Two»: Insert Folder «project_two» (name it exactly the same as already existing on disk!).</li><li>Open «Project One», select and right-click to copy the project items «MyClass» and «MyModule»</li><li>Back in «Project Two»: paste the project items in the previously created folder &#8220;shared_code&#8221;</li><li>Close «Project One» again, to have only a single project opened</li></ul>



<p>That&#8217;s what it should look like &#8211; the shared project items are being referenced properly, relative to the root folder of the MonoRepo:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="296" src="https://blog.xojo.com/wp-content/uploads/2021/07/7_macOS-Workaround-1024x296.png" alt="" class="wp-image-8909" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/7_macOS-Workaround-1024x296.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/07/7_macOS-Workaround-300x87.png 300w, https://blog.xojo.com/wp-content/uploads/2021/07/7_macOS-Workaround-768x222.png 768w, https://blog.xojo.com/wp-content/uploads/2021/07/7_macOS-Workaround-1536x444.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/07/7_macOS-Workaround.png 1694w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>So that&#8217;s it. We now have «MyClass» and «MyModule» available in both Projects. And since they are effectively the same files on disk, they&#8217;re shared between them. So from now on any code change will be reflected and used by both projects.</p>



<p>You&#8217;ll only need to do these steps once for a new project item that you&#8217;re going to share between projects. Once they are referenced in the project files, they&#8217;ll point to the same file for all projects. That&#8217;s possible because the project file is in the root of the MonoRepo, and all project items added are being referenced relative to that root folder.</p>



<p>So it doesn&#8217;t matter where the main folder is located &#8211; and the structure works fine for all Operating Systems you can use to code with the Xojo IDE.</p>



<h2 class="wp-block-heading"><strong>Let&#8217;s Code</strong></h2>



<p>Finally make use of this and use the shared code in the projects:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="544" src="https://blog.xojo.com/wp-content/uploads/2021/07/8_UseSharedCode-1024x544.png" alt="" class="wp-image-8910" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/8_UseSharedCode-1024x544.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/07/8_UseSharedCode-300x159.png 300w, https://blog.xojo.com/wp-content/uploads/2021/07/8_UseSharedCode-768x408.png 768w, https://blog.xojo.com/wp-content/uploads/2021/07/8_UseSharedCode-1536x816.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/07/8_UseSharedCode-2048x1088.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>While your projects are evolving you can add more shared Classes, Modules, Methods, Constants, Images, and add them to the other projects in the MonoRepo as explained above.</p>



<p>Enjoy the benefits of your MonoRepo and reusable code!</p>



<h3 class="wp-block-heading"><strong>Watch Out</strong></h3>



<p>Be aware that the Xojo IDE isn&#8217;t designed for shared code. It doesn&#8217;t look at your MonoRepo as a «solution of several projects». It&#8217;s not aware of changes happening outside of an already loaded/opened Project.</p>



<p>That&#8217;s why I recommend to only have one project open at a time, and only open a second project to copy and paste new project items to the other project.</p>



<p>Why? Well, let&#8217;s assume you have both projects opened. You&#8217;re making a change to «MyClass» in «Project One» and save. Since the Xojo IDE with the opened «Project Two» is not aware of this change you still have the previous state loaded in Memory. And chances are that once you&#8217;re saving «Project Two» you&#8217;re going to overwrite the file with the state that «Project Two» currently has, therefore loosing the changes made to «MyClass» in «Project One».</p>



<p>One workaround might be: Frequently save the project after each change. Never switch to another project if not saved. If a second opened project needs that change, switch to it and «Revert to saved». You can do this by simply (un)checking a Build Target to make the project «dirty», so that this Menu Item gets enabled. Then «revert to saved» (without saving changes).</p>



<p>But honestly, it&#8217;s too risky in my opinion. That&#8217;s why I try to only work on a single project at any given time. As always &#8230; the exception proves the rule <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<h3 class="wp-block-heading"><strong>File Type Groups</strong></h3>



<p>If your application uses files with app specific icons, you&#8217;re going to create a <a href="https://documentation.xojo.com/getting_started/using_the_ide/file_type_group_editor.html">File Type Group</a>. In a MonoRepo you need to be aware of how Xojo is saving this. Let&#8217;s have a look at an example:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="591" src="https://blog.xojo.com/wp-content/uploads/2021/07/11_FileTypeGroup-1024x591.png" alt="" class="wp-image-8912" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/11_FileTypeGroup-1024x591.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/07/11_FileTypeGroup-300x173.png 300w, https://blog.xojo.com/wp-content/uploads/2021/07/11_FileTypeGroup-768x444.png 768w, https://blog.xojo.com/wp-content/uploads/2021/07/11_FileTypeGroup-1536x887.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/07/11_FileTypeGroup-2048x1183.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>I have created a «File Type Group» named MyFileTypeGroup and saved it to the shared_code folder. Has this been a good idea?</p>



<ul class="wp-block-list"><li>MyFileTypeGroup.xojo_filetypeset: This is a text file containing information about the custom file type. So far so good, but&#8230; where is the assigned Icon?<br>If you have a close look at the contents of this file you&#8217;ll notice that it references: Project_Two.xojo_resources</li><li>Do you remember&#8230; we&#8217;ve noticed this file and described it like this: Project_Two.xojo_resources: This is a binary file containing the AppIcon, and similar resources.<br>So it contains binary information for both AppIcon&#8217;s, as well as FileType Icons.</li></ul>



<p>Back to the question &#8211; has it been a good idea to save it to a shared code folder?</p>



<p>I don&#8217;t think so&#8230; Well, it works &#8211; even if you add it to a second project. However, when saving the project it will always reference the currently opened project, and save the binary representation of the Icon again to another .xojo_resources file. This leads to unwanted changes to both files.</p>



<p>So don&#8217;t do that&#8230; Always and only save a «File Type Group» per project. Even if this means an unwanted duplication of a project item that you need in several projects.</p>



<p>I just accept that inconvenience &#8211; knowing I&#8217;m using Xojo and the «Text Project format» in a way that it has not been designed for. All the other benefits are worth it.</p>



<h3 class="wp-block-heading"><strong>Build Automation</strong></h3>



<p>Do you remember that we wanted to have a look at that later, when we&#8217;ve noticed that there is only a single «Build Automation.xojo_code» file in our MonoRepo?</p>



<p>Build Automation will be shared between all projects since you can&#8217;t move that to another place. It&#8217;ll always be next to the project file. For our MonoRepo this means: it will be the very same for all projects since we have all projects files in the root repository folder.</p>



<p>What can we do to still have Build Automation «per project»? We need a way to distinguish the projects in IDE- and Build Scripts. What has worked fine for us is to use the «Build Setting: Windows &#8211; Internal Name» and set it to an (internal) project name:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="511" src="https://blog.xojo.com/wp-content/uploads/2021/07/9_App_InternalName-1024x511.png" alt="" class="wp-image-8917" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/9_App_InternalName-1024x511.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/07/9_App_InternalName-300x150.png 300w, https://blog.xojo.com/wp-content/uploads/2021/07/9_App_InternalName-768x383.png 768w, https://blog.xojo.com/wp-content/uploads/2021/07/9_App_InternalName-1536x766.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/07/9_App_InternalName.png 2004w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading"><strong>Pre/Post Build Scripts</strong></h3>



<p>For the Build Steps «Scripts» and «External Scripts» we then need to first add check if we want to run it for the currently to-be-built project:</p>



<pre class="wp-block-preformatted">if (PropertyValue("App.InternalName") &lt;&gt; "project_one") then return</pre>



<p>This is the workaround for this limitation of the Xojo IDE to not have Build Automation «per project» if there are several projects in the same folder (which happens to be the case in our «MonoRepo»). You&#8217;ll see all Scripts in all projects. And since the Xojo IDE will run them all we need to make sure to bail out if it&#8217;s a script for another project.</p>



<p>Having said that, it&#8217;s also a good thing! This obviously also allows you to share Build Scripts between some or even all your projects.</p>



<p>This ScreenShot shows an example of a Script that&#8217;s intended to run only for «Project One»:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="559" src="https://blog.xojo.com/wp-content/uploads/2021/07/10_BuildScripts-1024x559.png" alt="" class="wp-image-8919" srcset="https://blog.xojo.com/wp-content/uploads/2021/07/10_BuildScripts-1024x559.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/07/10_BuildScripts-300x164.png 300w, https://blog.xojo.com/wp-content/uploads/2021/07/10_BuildScripts-768x419.png 768w, https://blog.xojo.com/wp-content/uploads/2021/07/10_BuildScripts-1536x839.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/07/10_BuildScripts-2048x1118.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading"><strong>Copy Files Steps</strong></h3>



<p>No good news here&#8230; there are currently no options to check a «per project» value if a Copy File step should be executed or not. It&#8217;s a «for all projects» or nothing.</p>



<p>The workaround is to copy additional files using a Post Build Script. And if you&#8217;re using the Xojo IDE on all supported OS (Windows, macOS, Linux), then you can leverage conditionals depending on the OS the XOJO IDE is currently running and building in the Scripts, too!</p>



<p>The files to be copied can be stored in a String Array. To know where to copy from (relative to the MonoRepo&#8217;s location, so it doesn&#8217;t matter to where a Developers checks out the repository):</p>



<pre class="wp-block-preformatted">if TargetWindows then
&nbsp; sFolderResources = "%PROJECT_PATH%\resources"
elseif TargetMacOS or TargetLinux then
&nbsp; sFolderResources = "$PROJECT_PATH/resources"
end if</pre>



<p>Where to copy the files to?</p>



<pre class="wp-block-preformatted">Dim sAppBuildPath As String
if TargetWindows then
&nbsp; sAppBuildPath = CurrentBuildLocation
elseif TargetMacOS or TargetLinux then
&nbsp; sAppBuildPath = ReplaceAll(CurrentBuildLocation, "\", "") 'don't escape Path
end if</pre>



<p>This example will use the proper Shell Commands on both Windows or macOS/Linux to copy the list of files:</p>



<pre class="wp-block-preformatted">Dim i As Integer = sCopyFiles.Ubound
while (i &gt; -1)
&nbsp; if TargetWindows then
&nbsp; &nbsp; call DoShellCommand("copy """ + sCopyFiles(i) + """ """ + sCopyToFolder + """ /y /v", 0)
&nbsp; elseif TargetMacOS or TargetLinux then
&nbsp; &nbsp; call DoShellCommand("cp -f """ + sCopyFiles(i) + """ """ + sCopyToFolder + """", 0)
&nbsp; end if
&nbsp; i = i - 1
wend</pre>



<h3 class="wp-block-heading"><strong>Adding a Third Project</strong></h3>



<p>Before you&#8217;re going to add a new project: Make sure you have committed all changes of the MonoRepo in your Version Control System.</p>



<p>If you then create a new project, and do the same steps as described above (move all project items into a new folder «project_three») and save the project to the root folder of the MonoRepo &#8211; what do you guess will happen?</p>



<p>The new project related files are there in the root and in the created folder «project_three». That&#8217;s expected. However, you&#8217;ll notice that the Build Automation files have been overwritten. That&#8217;s unfortunate &#8211; but expected, too. It boils down to the fact that the Xojo IDE with your newly created project is not aware of whatever you have put in Build Automation before. So it&#8217;s going to save the blank Build Automation, since that&#8217;s the state of the opened IDE.</p>



<p>Don&#8217;t worry, just quit the Xojo IDE, then revert the changes to Build Automation in your Version Control System. Reopen the project, and it will now pick up the previous state which you&#8217;ve just reverted. Now it&#8217;s possible to add more build steps for the third project.</p>



<p>Similar issues might happen if you&#8217;re then going to copy-paste shared code items e.g. from «project_one» to the newly added «project_three». After you save, your Version Control system might show a ton of changes in the shared code, e.g. properties being saved as &#8220;True&#8221; when before they&#8217;ve been saved without quotes. So I usually do the same procedure: revert the (unnecessary/unwanted) changes in the shared code items after a copy-paste and save to a new project. That&#8217;s fine since there have been no &#8220;real&#8221; changes to those files. All that&#8217;s important is that the files are being linked properly in the main project file of «project_three».</p>



<h3 class="wp-block-heading"><strong>Everything Else</strong></h3>



<p>I don&#8217;t intend to explain advanced possibilities here. Just two situations you might encounter:</p>



<p>A Method in a shared Module contains Desktop stuff, but you want the rest of the Module to be used in a Console app, too. You can do this using <a href="https://documentation.xojo.com/topics/os_information/conditional_compilation.html">«Conditional Compilation»</a>, e.g. in Code or by selecting a Target («Include in») for a Class/Method in Inspector. </p>



<p>You want or need to build different projects with different Xojo Versions. That might be because of a legacy project. Or that you continue to build for TargetWindows with an older Xojo Version while building for macOS with the newest Xojo Version. Then I&#8217;d suggest to code using the lowest used Xojo Version. Add functionality available only in newer Xojo Versions using <a href="https://documentation.xojo.com/topics/os_information/conditional_compilation.html">Conditional Compilation</a>: </p>



<pre id="block-2f28d7a4-51d5-43f9-9e7c-6699617e4f2c" class="wp-block-preformatted">#If XojoVersion &gt;= 2021.01 Then </pre>



<p>you can even leverage newer Event Handlers (that are only available in newer Xojo Versions) in there using <a href="https://documentation.xojo.com/api/code_execution/addhandler.html">AddHandler</a>. We&#8217;ve done that for example with DarkMode Support for our macOS builds (while the productive Windows builds are still being built with older versions).</p>



<h2 class="wp-block-heading"><strong>About Our MonoRepo</strong></h2>



<p>Our main MonoRepo currently has 12 projects written in Xojo. It&#8217;s a mix of Desktop and Console applications, Commercial and Internal apps. They&#8217;re being worked on by multiple developers, allowing us to code or debug by running the Xojo IDE in different OS environments with ease.</p>



<p>We&#8217;ve been successfully using this approach for more than 14 years with REALbasic, REAL Studio and Xojo, always with their Text Project format.</p>



<p>We have structured our MonoRepo more or less like this:</p>



<ul class="wp-block-list"><li><code>/<br>/project_A<br>/project_B</code><br>Such as you have seen above: All Project files, and the shared BuildAutomation in the root folder. And every project has its own project folder.</li><li><code>/shared</code><br>The common folder is being used in all our projects, no matter if the project effectively needs every bit in there at its current development stage. It&#8217;s kind of our own addition to the Xojo Framework that we can rely on in all our projects.</li><li><code>/shared/controls</code><br>We&#8217;ve subclasses every Control (to have extended functionality, fixes and workarounds) and only use subclassed Controls in all our projects.</li><li><code>/shared/classes<br>/shared/functions<br>/shared/resources</code><br>Same story here. Over the years we&#8217;ve written many Modules with custom <a href="https://documentation.xojo.com/api/language/extends.html">Extensions</a> to Xojo Framework Classes, additional/custom String/XML/JSON functionality, abstracted the encryption related functionality we need, and we have a set of own data structures/types that are not available in the Xojo Framework. And there are some resources we use in about every project, such as the company logo or Toolbar Icons.</li><li><code>/components<br>/components/reporting<br>/components/webservice</code><br>These components are being used in some, but not all projects. Important here is that they need to be functional on their own, without dependencies to app/project related code. Examples known in the Xojo community are e.g. the reporting engine Shorts, or Aloe for WebServices.</li><li><code>/build<br>/build/configuration<br>/build/processing</code><br>Last but not least, in that folder we have all (post) build related functionality. That&#8217;s per-project build settings (being read and used by the post build scripts &#8211; and yes, you&#8217;re right, this could be put into the individual project&#8217;s folders), but also our shared post build processing (again kicked off by post build scripts) which deploy all our builds (Alphas/Betas/Final versions) internally and upload it to our app-update WebServices.<br>I can only recommend to have such (post) build-related stuff under version control! Be it for an emergency fix for an old version (while the build process/configuration of your current version has changed significantly), or to work in a feature branch on new functionality that requires changes to the build processing (without affecting the productive flow).</li></ul>



<h3 class="wp-block-heading"><strong>That&#8217;s All Folks!</strong></h3>



<p>I hope this brief introduction of how one can share code between different Xojo Projects using a MonoRepo has been helpful to some, food for thought to others.</p>



<p><em>Jürg Otter is a long term user of Xojo and working for </em><a href="https://www.cmiag.ch/"><em>CM Informatik AG</em></a><em>. Their Application </em><a href="https://cmi-bildung.ch/"><em>LehrerOffice</em></a><em> is a Xojo Design Award Winner 2018. In his leisure time Jürg provides some </em><a href="https://www.jo-tools.ch/xojo/"><em>bits and pieces for Xojo Developers</em></a><em>.</em></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Running Xojo Web Applications in Docker</title>
		<link>https://blog.xojo.com/2021/05/17/running-xojo-web-applications-in-docker/</link>
		
		<dc:creator><![CDATA[Jürg Otter ]]></dc:creator>
		<pubDate>Mon, 17 May 2021 18:00:00 +0000</pubDate>
				<category><![CDATA[Guest Post]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[Build Automation]]></category>
		<category><![CDATA[Cloud]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Web 2.0]]></category>
		<category><![CDATA[webdev]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=8472</guid>

					<description><![CDATA[You can package your Xojo Web Apps in a Docker Image. That allows you to run an instance of your applications easily in a Docker Container. Docker provides the infrastructure to host the apps, start/stop them, switch between image versions - and much more.]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">What is Docker?</h2>



<p>If you haven&#8217;t heard of Docker, go ahead and read their excellent Documentation: <a href="https://docs.docker.com/get-started/overview/">Docker &#8211; Overview</a>.</p>



<p>I&#8217;m just going to quote some basics from the Overview to give a brief introduction of Docker, Docker image and Docker container:</p>



<p><strong><em>Docker </em></strong><em>is an open platform for developing, shipping, and running applications. It provides the ability to package and run an application in a loosely isolated environment called a container. The isolation and security allow you to run many containers simultaneously on a given host. Containers are lightweight and contain everything needed to run the application, so you do not need to rely on what is currently installed on the host. You can easily share containers while you work, and be sure that everyone you share with gets the same container that works in the same way.</em></p>



<p><em>A </em><strong><em>Docker image </em></strong><em>is a read-only template with instructions for creating a Docker container. Often, an image is based on another image, with some additional customization. To build your own image, you create a Dockerfile with a simple syntax for defining the steps needed to create the image and run it.</em></p>



<p><em>A </em><strong><em>Docker container </em></strong><em>is a runnable instance of an image. You can create, start, stop, move, or delete a container. By default, a container is relatively well isolated from other containers and its host machine. You can control how isolated a container’s network, storage, or other underlying subsystems are from other containers or from the host machine. A container is defined by its image as well as any configuration options you provide to it when you create or start it.</em></p>



<p><em>A </em><strong><em>Docker Registry</em></strong><em> is a stateless, highly scalable server side application that stores and lets you distribute Docker images.</em></p>



<h2 class="wp-block-heading">Why use Docker with a Xojo Web App?</h2>



<p>You can package your Xojo Web Apps in a Docker Image. That allows you to run an instance of your applications easily in a Docker Container. Docker provides the infrastructure to host the apps, start/stop them, switch between image versions &#8211; and much more.</p>



<p>The Docker Images containing your Xojo Web Apps can be copied to other machines. This might be some Linux or macOS machine <em>(Windows seems to be a bit more tricky)</em>, a Cloud Service &#8211; or even a Synology NAS. You then can import the Images on the Docker environment of those machines, and serve your apps from there.</p>



<p>If you&#8217;re pushing the Docker Images to a Registry (e.g. Docker Hub), it gets even more convenient. Docker Hub is a service provided by Docker for finding and sharing container images with your team or the public. So you&#8217;ll build the Docker Image with your Xojo Web App, push it to the Registry. After that, you (or your team, or everyone) can just pull the Images to their Docker infrastructure and run them in a Container.</p>



<h2 class="wp-block-heading">How to build a Docker Image containing a Xojo Web App?</h2>



<p>One could answer obviously: it depends. But let me try to explain the basic required steps. For this example we&#8217;re going to use a macOS machine to build the Xojo Web App and Docker Image. Then we&#8217;ll deploy and run a Docker Container on the local developer machine and on a Synology NAS.</p>



<h3 class="wp-block-heading"><strong>Requirements</strong></h3>



<ul class="wp-block-list"><li>Xojo with a license allowing you to build a Xojo Web App for Target Linux (Intel, 64Bit). </li></ul>



<p>Docker Desktop installed on the macOS developer machine. Download and install it from here: <a href="https://docs.docker.com/docker-for-mac/install/">Docker for macOS</a>. After that you should have the Docker GUI up and running. And in Terminal.app you should have the command line tools available. You can double check this by entering this command: </p>



<pre class="wp-block-preformatted">docker version</pre>



<ul class="wp-block-list"><li>We&#8217;re going to build a Docker Image based on Ubuntu (Linux). To run a Docker Container with this image, we obviously need a machine supporting this. Both macOS and the Synology NAS will work just fine.</li></ul>



<p>Are you ready and set up? So let&#8217;s go and try this.</p>



<h3 class="wp-block-heading"><strong>Build a Xojo Web App</strong></h3>



<p>Open a Xojo Project with a Web Application. I&#8217;m going to use a CRC Calculator I&#8217;ve written. Debug-Run it locally to make sure the Web App works as expected.</p>



<p>Once we&#8217;re ready to build we should think of what we&#8217;re going to need for the Docker Image. Check the following properties in your Xojo Project:</p>



<ul class="wp-block-list"><li>The most obvious one: Tick the &#8220;<strong>Build Target: Linux, x86-64Bit&#8221;. </strong>Since our Docker Image will run Ubuntu / Linux-64Bit, we need the Xojo Web App to run in such an environment.</li></ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="608" src="https://blog.xojo.com/wp-content/uploads/2021/05/1_Build_Target-1024x608.png" alt="" class="wp-image-8508" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/1_Build_Target-1024x608.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/1_Build_Target-300x178.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/1_Build_Target-768x456.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/1_Build_Target-1536x912.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/05/1_Build_Target.png 2000w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list"><li>Then in &#8220;Build Settings &#8211; Shared&#8221;, set the &#8220;<strong>Build &#8211; Port: 80</strong>&#8220;. In fact it doesn&#8217;t really matter which Port you&#8217;re choosing. All that is important for now is that you know which one it is.</li></ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="608" src="https://blog.xojo.com/wp-content/uploads/2021/05/2_Build_Port-1024x608.png" alt="" class="wp-image-8509" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/2_Build_Port-1024x608.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/2_Build_Port-300x178.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/2_Build_Port-768x456.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/2_Build_Port-1536x912.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/05/2_Build_Port.png 2000w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list"><li>That&#8217;s about all we need to do within the Xojo IDE &#8211; so let&#8217;s hit <strong>&#8220;Build&#8221;</strong>. </li></ul>



<p>We now have the built Web App ready. Next step is to package it in a Docker Image.</p>



<h3 class="wp-block-heading"><strong>Dockerfile</strong></h3>



<p>Open the Web App&#8217;s Build Folder in Finder. Next we need to write the instructions to get it in a Docker Image. Open your favourite Text Editor. Create a Text-File with Filename: <em>Dockerfile</em> (no file extension). Save it in the Build folder (next to the application&#8217;s executable file). The Content we&#8217;re saving in Dockerfile is:</p>



<pre class="wp-block-preformatted">#BASE IMAGE
FROM ubuntu:20.04

#INSTALL REQUIRED LIBRARIES
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update &amp;&amp; apt-get install -y libunwind8 libglib2.0

#ADD APPLICATION TO DOCKER IMAGE
ADD / /app/

#EXPOSE PORT AND RUN APPLICATION
EXPOSE 80
WORKDIR /app
CMD /app/CRCCalculatorWeb</pre>



<p>This describes how Docker is going to create the Docker Image. Let&#8217;s briefly explain the steps of this Dockerfile:</p>



<ul class="wp-block-list"><li>We&#8217;re going to use Ubuntu 20.04 as a base image. That about the same as saying: &#8220;Let&#8217;s set up an environment running Ubuntu 20.04 first.&#8221;</li></ul>



<ul class="wp-block-list"><li>We then set an environment variable allowing to install updates without user interaction. Then the system gets updated, and required Libraries installed (libunwind8, libglib2.0).</li></ul>



<ul class="wp-block-list"><li>The whole Content of the Build Folder (or in other words: everything next to the Dockerfile &#8211; that&#8217;s basically our Xojo Web App) is being copied into the image to the location /app</li></ul>



<ul class="wp-block-list"><li>Expose 80: Do you remember? That&#8217;s the &#8220;Build Port&#8221; we&#8217;ve set in the Xojo IDE. So this tells that when running this Image as a Container Instance later we can attach to this &#8220;virtual port&#8221;. It doesn&#8217;t matter if several applications in different Images/Containers use the same port. That&#8217;s because when running an Instance, we can later configure the running Instance to map the Ports, e.g.: &#8220;8088 (external) -&gt; 80 (internal)&#8221;. So a second Web App Instance or App could use e.g.&#8221;8089 (external) -&gt; 80 (internal)&#8221;. That&#8217;s why for our own convenience we can use Port 80 for every of our Xojo Web Apps&#8217;s Docker Image.</li></ul>



<ul class="wp-block-list"><li>Finally, the instructions tell where the working directory is, and with the last command the Xojo Web App is being launched.</li></ul>



<p>Alright &#8211; everything is ready so that we can now create the Docker Image.</p>



<h3 class="wp-block-heading"><strong>Docker Image</strong></h3>



<p>Open Terminal.app and change directory to the Build Folder of the Web App:</p>



<pre class="wp-block-preformatted">cd /path/to/your/xojo-webapp-project/Builds\ -\ CRCCalculatorWeb/Linux\ 64\ bit/CRCCalculatorWeb</pre>



<p>You&#8217;re now in the folder with the Dockerfile and your Web App.</p>



<p>A Docker Image always needs a <strong>Tag</strong>. Such a Tag looks like this:</p>



<pre class="wp-block-preformatted">jotools/crccalculator:1.0.0-dev</pre>



<p>The parts are: (company-name)/(product-name):(version-label-tag)</p>



<p>So&#8230; let&#8217;s build the Docker Image &#8211; enter this in Terminal:</p>



<pre class="wp-block-preformatted">docker build -t jotools/crccalculator:1.0.0-dev .</pre>



<p>What this does is: Build a Docker Image with Tag ___ from &#8220;this current directory&#8221; (the dot at the end).</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2021/05/3_Docker-Build-1024x666.png" alt="pastedGraphic_2.png" class="wp-image-8497" width="904" height="588" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/3_Docker-Build-1024x666.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/3_Docker-Build-300x195.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/3_Docker-Build-768x500.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/3_Docker-Build.png 1140w" sizes="auto, (max-width: 904px) 100vw, 904px" /></figure>



<p><em>Side-Note: If you&#8217;re re-building an Image with the same Tag of an already existing Image, it gets overwritten. You could also first remove an existing image like this:</em></p>



<pre class="wp-block-preformatted"><br>docker image rm jotools/crccalculator:1.0.0-dev</pre>



<p>You can now launch the Docker Desktop .app and find your Image there:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="590" src="https://blog.xojo.com/wp-content/uploads/2021/05/4_Docker-Image-1024x590.png" alt="" class="wp-image-8510" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/4_Docker-Image-1024x590.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/4_Docker-Image-300x173.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/4_Docker-Image-768x442.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/4_Docker-Image-1536x885.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/05/4_Docker-Image-2048x1180.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>If you prefer to see the image using the command line:</p>



<pre class="wp-block-preformatted">docker image ls</pre>



<h3 class="wp-block-heading"><strong>Run Docker Container</strong></h3>



<p>Let&#8217;s now take the Image and run a new Docker Container using that Image. We will configure the Docker Container Instance to use the local Port 8088. In Docker Desktop GUI:</p>



<ul class="wp-block-list"><li>Select the Image, click on the Button &#8220;Run&#8221;</li></ul>



<ul class="wp-block-list"><li>Expand the optional settings, enter a Container Name of your choice and Map the &#8220;LocalPort: 8088&#8221; to &#8220;Container Port: 80&#8221;</li></ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="590" src="https://blog.xojo.com/wp-content/uploads/2021/05/5_Docker-Container-Setup-1024x590.png" alt="" class="wp-image-8511" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/5_Docker-Container-Setup-1024x590.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/5_Docker-Container-Setup-300x173.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/5_Docker-Container-Setup-768x442.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/5_Docker-Container-Setup-1536x885.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/05/5_Docker-Container-Setup-2048x1180.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list"><li>Then&#8230; click on &#8220;Run&#8221;</li></ul>



<p>And that&#8217;s it &#8211; we have the Container up and running:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="590" src="https://blog.xojo.com/wp-content/uploads/2021/05/6_Docker-Container-Running-1-1024x590.png" alt="" class="wp-image-8513" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/6_Docker-Container-Running-1-1024x590.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/6_Docker-Container-Running-1-300x173.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/6_Docker-Container-Running-1-768x442.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/6_Docker-Container-Running-1-1536x885.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/05/6_Docker-Container-Running-1-2048x1180.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>If you prefer the command line:</p>



<pre class="wp-block-preformatted">docker run -d --publish=8088:80 --name crccalculator jotools/crccalculator:1.0.0-dev</pre>



<p>Let&#8217;s access our Xojo built Web App running in the local Docker Container using Safari:</p>



<figure class="wp-block-image size-large is-resized"><img loading="lazy" decoding="async" src="https://blog.xojo.com/wp-content/uploads/2021/05/7_Safari-Test-1024x651.png" alt="pastedGraphic_6.png" class="wp-image-8500" width="889" height="563"/></figure>



<p><em>Side-Note: If you just want to try this example project then you can pull the image like this in Terminal.app:</em></p>



<pre class="wp-block-preformatted">docker pull jotools/crccalculator:1.0.0</pre>



<h3 class="wp-block-heading"><strong>Export Docker Image</strong></h3>



<p>The easiest way is to push the Image to a Registry such as Docker Hub. That obviously requires a registration &#8211; so we won&#8217;t cover this here and now.</p>



<p>Let&#8217;s export the Image using Terminal.app.</p>



<p>You should still be in the Build &#8211; directory of the Xojo Web App. If not, change to that folder.</p>



<p>Then export the Docker Image to a file like this:</p>



<pre class="wp-block-preformatted">docker save jotools/crccalculator:1.0.0-dev | gzip &gt; ./CRCCalculatorWeb.dockerimage.tgz</pre>



<p>This command is saving the Image/Tag to a .tgz located in the current directory.</p>



<h3 class="wp-block-heading"><strong>Run Docker Image on a Synology NAS</strong></h3>



<p>If you have a Synology NAS supporting Docker &#8211; this is how you can run the exported Image on your NAS:</p>



<ul class="wp-block-list"><li>First of course: Install the Synology Docker Package</li></ul>



<ul class="wp-block-list"><li>Copy the exported <em>CRCCalculatorWeb.dockerimage.tgz</em> to a Share on the NAS</li></ul>



<ul class="wp-block-list"><li>Launch the Docker .app on the NAS</li></ul>



<ul class="wp-block-list"><li>Under &#8220;Images&#8221;: Add -&gt; From File -&gt; (choose your <em>CRCCalculatorWeb.dockerimage.tgz</em>) </li></ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="662" src="https://blog.xojo.com/wp-content/uploads/2021/05/8_Synology_Docker-Image-1024x662.png" alt="" class="wp-image-8517" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/8_Synology_Docker-Image-1024x662.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/8_Synology_Docker-Image-300x194.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/8_Synology_Docker-Image-768x497.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/8_Synology_Docker-Image-1536x994.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/05/8_Synology_Docker-Image-2048x1325.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list"><li>Select the imported Image, click on &#8220;Run&#8221;</li></ul>



<ul class="wp-block-list"><li>Enter a Containername of your choice:</li></ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="662" src="https://blog.xojo.com/wp-content/uploads/2021/05/9_Synology_Docker-Container-1-1024x662.png" alt="" class="wp-image-8518" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/9_Synology_Docker-Container-1-1024x662.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/9_Synology_Docker-Container-1-300x194.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/9_Synology_Docker-Container-1-768x497.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/9_Synology_Docker-Container-1-1536x994.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/05/9_Synology_Docker-Container-1-2048x1325.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list"><li>Click the Button &#8220;Advanced Settings&#8221;: Same story here &#8211; Map the Local&lt;-&gt;Container Port. In this example: Local 8099 &lt;-&gt; Container 80</li></ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="662" src="https://blog.xojo.com/wp-content/uploads/2021/05/10_Synology_Docker-Container-2-1024x662.png" alt="" class="wp-image-8522" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/10_Synology_Docker-Container-2-1024x662.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/10_Synology_Docker-Container-2-300x194.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/10_Synology_Docker-Container-2-768x497.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/10_Synology_Docker-Container-2-1536x994.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/05/10_Synology_Docker-Container-2-2048x1325.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<ul class="wp-block-list"><li>Finish the assistant. The Container should now be up and running:</li></ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="662" src="https://blog.xojo.com/wp-content/uploads/2021/05/11_Synology_Docker-Container-Running-1024x662.png" alt="" class="wp-image-8523" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/11_Synology_Docker-Container-Running-1024x662.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/11_Synology_Docker-Container-Running-300x194.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/11_Synology_Docker-Container-Running-768x497.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/11_Synology_Docker-Container-Running-1536x994.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/05/11_Synology_Docker-Container-Running-2048x1325.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<p>Let&#8217;s access our Xojo built Web App running in the Docker Container of the Synology NAS using Safari:</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="662" src="https://blog.xojo.com/wp-content/uploads/2021/05/12_Safari-Test-1024x662.png" alt="" class="wp-image-8524" srcset="https://blog.xojo.com/wp-content/uploads/2021/05/12_Safari-Test-1024x662.png 1024w, https://blog.xojo.com/wp-content/uploads/2021/05/12_Safari-Test-300x194.png 300w, https://blog.xojo.com/wp-content/uploads/2021/05/12_Safari-Test-768x497.png 768w, https://blog.xojo.com/wp-content/uploads/2021/05/12_Safari-Test-1536x994.png 1536w, https://blog.xojo.com/wp-content/uploads/2021/05/12_Safari-Test-2048x1325.png 2048w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>



<h2 class="wp-block-heading"><strong>What next?</strong></h2>



<p>There are a lot of features and possibilities which we won&#8217;t cover here. Let&#8217;s just pick a couple and briefly explain without going into detail. You&#8217;ll find excellent documentation on Docker&#8217;s Website if you want or need to dig in further.</p>



<h3 class="wp-block-heading"><strong>Docker and Persisted Storage</strong></h3>



<p>Note that this example has no persisted storage. Which means that you can save files within a Container &#8211; but once you stop or remove the Container (e.g. to run a new Container with a newer Image version) the created data is gone. That&#8217;s a good thing &#8211; as a Container will always behave the same when deployed, not being cluttered with data that has come from somewhere.</p>



<p>If your Web App requires to store data on the filesystem you should add a Volume. In the Dockerfile add a line like this:</p>



<pre class="wp-block-preformatted">VOLUME /data</pre>



<p>You then can have your WebApp save data to the folder /data.</p>



<p>If you run a Container from such an Image &#8211; have a look at the Advanced Settings. Since the Image exposes a Volume, you can choose a local folder (on the machine where Docker is serving the Container) to be attached to /data. Same story on the Synology NAS.</p>



<p>Once you remove the Docker Container, the Data will still be there. So you can run another Container (e.g. with a newer version of your app), attach the same/existing data-folder. That way you can continue and keep existing data.</p>



<h3 class="wp-block-heading"><strong>Environment Variables</strong></h3>



<p>Especially if you&#8217;re going to Deploy the Docker Image on various environments, you might want some &#8220;settings&#8221;. One approach is to use Environment Variables in the Dockerfile:</p>



<pre class="wp-block-preformatted">ENV MY_CUSTOM_SETTING=4430</pre>



<p>Again in the Advanced options when running a Container you can override these Environment Variables to fit your needs.</p>



<h3 class="wp-block-heading"><strong>Build Automation</strong></h3>



<p>If you&#8217;re building regularly and don&#8217;t want to enter commands in the command line after every build you could think about a Post Build Script which builds the Docker Image and optionally even pushes it to a Registry (e.g. Docker Hub).</p>



<p>An example is available here: <a href="https://www.jo-tools.ch/xojo/xojowebapp2docker/">Example Project &#8211; Xojo Web App 2 Docker</a></p>



<h3 class="wp-block-heading"><strong>Docker Registry</strong></h3>



<p>The easiest way is to distribute a local Docker Image is to use a Registry such as Docker Hub. That obviously requires a registration and your Docker Client to be signed in. You can then push the Docker Image to the Registry, and pull it from there on the Docker Clients.</p>



<pre class="wp-block-preformatted">docker push jotools/crccalculator:1.0.0-dev</pre>



<pre class="wp-block-preformatted">docker pull jotools/crccalculator:1.0.0-dev</pre>



<h3 class="wp-block-heading"><strong>Restart policy</strong></h3>



<p>In order to automatically launch a Docker Container after a reboot (of the host machine; of the Docker daemon): see Docker&#8217;s <a href="https://docs.docker.com/config/containers/start-containers-automatically/">Restart Policy Documentation</a>.&nbsp;</p>



<p>This command changes the restart policy for an already running container named crccalculator:</p>



<pre class="wp-block-preformatted">docker update --restart unless-stopped crccalculator</pre>



<p>And this command will ensure all currently running containers will be restarted unless stopped:</p>



<pre class="wp-block-preformatted">docker update --restart unless-stopped $(docker ps -q)</pre>



<h2 class="wp-block-heading"><strong>That&#8217;s all Folks!</strong></h2>



<p>I hope this brief introduction of how a Xojo built Web Application can be used with Docker has been helpful to some, food for thought to others.</p>



<p>I wish you all the best and I&#8217;m curious if the Xojo Forum will get new posts in the near future with Docker Hub Links to interesting Xojo Web Apps which you do provide to the community.</p>



<p><em><em>Jürg Otter is a long term user of Xojo and working for </em><a href="https://www.cmiag.ch/"><em>CM Informatik AG</em></a><em>. Their Application </em><a href="https://cmi-bildung.ch/"><em>CMI LehrerOffice</em></a><em> is a Xojo Design Award Winner 2018. In his leisure time Jürg provides some </em><a href="https://www.jo-tools.ch/xojo/"><em>bits and pieces for Xojo Developers</em></a><em>.</em></em></p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
