Our blog contains the activity stream of Orchard Dojo: general news, new resources or tutorials are announced here.

Hosting Orchard Core at Exoscale

It's not all about hyperscalers: You can run your Orchard Core app in the cloud even if not using Azure, AWS, or some other giant like these. Let's see how we can do this with Exoscale! Blog post series overview This post is part of our series about hosting Orchard Core at European cloud providers. Orchard Core has built-in support for a lot of Azure services, including Media storage, secret storage, e-mail delivery and sending SMS, AI search, and even observability with Azure Application Insights with the Lombiq module. AWS also has support for Media storage. For cloud-hosted full-text search we can use Elasticsearch, and Redis to aid with horizontal scaling. How does using a smaller cloud provider, without specific support from Orchard Core, compare? We've looked into hosting a vanilla Orchard Core app as a proof of concept, and are sharing our experiences here. The goal was to run Orchard Core with a minimal hosting environment, but with a stateless web server (so, keeping the database and Media storage separate). This could've been simplified to only use a web server (and keep the database in a local SQLite file, as well as use local Media files), but we wanted to go a bit more realistic than that. To be able to play around with the web server from the GUI too, we've chosen Windows as the OS if available. Additionally, we also checked if the platform helps with any of the other common infrastructure requirements, like sending e-mails or observability. Note that while we usually received some credits from the cloud providers for testing, they are not paying for these reviews, and any endorsement or critique is our own. What's Exoscale? Exoscale is a cloud provider from Switzerland, with hosting locations back at home, as well as in Germany, Austria, Bulgaria, and since July also in Croatia. As far as services interesting for Orchard Core hosting go, they offer VMs with load balancing, AWS S3-compatible object storage, and databases as a service. Managed Kubernetes is also available, but for the sake of this post, trying to host a simple app, we won't create a cluster. Instead of Redis, you can create Valkey instances (Valkey is an open-source fork of Redis), which, for now, should just work with Orchard Core's Redis support. While OpenSearch is also available, that's incompatible with Orchard's Elasticsearch integration. DNS management is also available, though that's something I'd keep at Cloudflare for a real-life app. I'd also use Cloudflare as a CDN, despite Exoscale offering a CDN layer (with Akamai) on top of their object storage; but since in Orchard Core we don't serve Media files from storage directly, that wouldn't help anyway. If you want to send e-mails, implement observability, or add search and indexing other than with Lucene on the web server, you're on your own. Creating an Orchard Core hosting environment You surely already guessed, but we'll need three Exoscale services: A Compute Instance, i.e. a VM, for the web server. A DBaaS database; we'll use PostgreSQL. We could also create SQL Server instances, but not only would the minimum 2-core VM be an overkill for our purposes, it's also much more expensive, starting at about EUR 247/month (vs a Postgres DBaaS starting at EUR 42/month). Object Storage for Media. Let's start with the server! I went with the Swiss zone, since there's no place like home, and opted with a 2-CPU plan with 2 GB of RAM. For this site, 1 CPU would also be more than enough (while to cater for Windows, I'm more comfortable with 2 GB of RAM instead of 1), but there's no 1-CPU 2 GB RAM instance type. [image alt="Creating an Exoscale Compute Instance"]BlogPost/other-posts/2025/hosting-orchard-core-at-exoscale/creating-a-compute-instance.webp[/image] You may notice two things here: On the right, there's a warning about having to create Security Groups for ingress rules first. (Somewhat confusingly the ADD button below it actually creates the compute instance, not a Security Group.) To be able to actually connect to the VM, we also need to edit the default Security Group (or perhaps more diligently, create a new one), then open up the ingress port 80 with TCP (for HTTP), as well as add a rule for RDP. As a last step, you'll also need to add 0.0.0.0/0 (i.e. all IPs) under External Sources, allowing anyone to connect to our web server. Those ENABLE buttons for instances Mega and up mean that you need to ask Exoscale support to allow them "after a manual screening process". This I find a bit strange. Until the server started, so in the meantime, I created an Object Storage bucket in the same zone (to minimize latency, these resources should all be in the same zone): [image alt="Creating an Object Storage bucket"]BlogPost/other-posts/2025/hosting-orchard-core-at-exoscale/adding-bucket.webp?2[/image] It seems that unlike with other cloud providers where you create a storage account, then a bucket under it, here everyone shares the same storage account. Thus, bucket names should be globally unique. This doesn't seem appealing at a first glance, but apart from the naming issue, I didn't find any practical problem with it. Somewhat counterintuitively, the storage access and secret keys are API keys. You can create these following the docs; for the sake of simplicity, I created a key for the Owner role, but for a production app, you should follow the docs' recommendations and create a restricted role just to access this bucket. Finally, we also need a single-node Postgres database server: [image alt="Creating a managed database"]BlogPost/other-posts/2025/hosting-orchard-core-at-exoscale/adding-postgresql-dbaas.webp[/image] Note that this runs on its own VM. The IP filter is necessary for the web server to access the DB server; the provided CIDR matches the exact IP of it. This is everything we need, so now we can continue with setting up Orchard Core in this environment. Deploying Orchard Core to the web server You can deploy an ASP.NET Core app, including an Orchard Core-using one, with Web Deploy to IIS, using automated deployment from a GitHub Actions workflow, or just by copying its publish outputs to the server. Here, I opted with the simplest option: I published the web app to a folder from Visual Studio (but running dotnet publish from the CLI would be equally suitable), and copied the resulting files to the server via Remote Desktop. Then I could simply run the web app: [image alt="The Orchard Core app running under Windows Server"]BlogPost/other-posts/2025/hosting-orchard-core-at-exoscale/app-running.webp[/image] The app listens to port 80 because I added an appsettings.Production.json file configuring it: { "Kestrel": { "Endpoints": { "HttpEndpoint": { "Url": "http://*:80" } } } } This allows you to simply open the IP of the server in a browser, or point a DNS A record to it. Our site is now available on the internet! ...after we allowed the exe of our web app through the Windows Firewall, that is. You may notice that this is a really barebones approach: There's no IIS, no HTTPS, no proper deployment. And you're right! This is a focused example of getting Orchard Core running, but we'll return to the missing pieces later. Setting up Orchard Core Running the Orchard Core setup is standard: Just fill out the usual settings on the setup screen, and point the app to the Postgres DB. For the latter, you can copy the Postgres connection string from the Exoscale Console, take the password of the default user from the DB's Users menu, and ask your favorite AI tool to turn them into an Npgsql connection string that .NET uses. Once setup finishes, you can configure Media storage too. I've elaborated above how to set up a bucket; the service URL for it will be in the format https://sos-{zone}.exo.io, with our Switzerland zone being ch-dk-2. Now it's time to configure the connection for the app. Again, you can use the appsettings.Production.json file to add something like below, resulting in the following full file: { "Kestrel": { "Endpoints": { "HttpEndpoint": { "Url": "http://*:80" } } }, "OrchardCore": { "OrchardCore_Media_AmazonS3": { "ServiceURL": "https://sos-ch-dk-2.exo.io", "Credentials": { "SecretKey": "add the secret of the user you created", "AccessKey": "add the access key of the user you created" }, "CreateBucket": true, "RemoveBucket": true, "BucketName": "oc-media" } } } Be sure to change the ServiceURL value to that of your instance, as indicated on its Overview page (under "S3 endpoint"). That's actually an undocumented configuration key that comes very handy when, as we do here, you connect to an S3 account outside of AWS. Now restart the app (so it reads the updated configuration file) and enable the Amazon Media Storage feature from the Orchard Core admin. It'll work, despite it not running in Amazon. Magic! And with this, our app fully works! Why would you (not) use Exoscale? OK, so we've seen that running Orchard Core under Exoscale works. This is not a huge surprise, but it's nice to get it verified and have the basics figured out. Why would we do this, though, instead of choosing the beaten path with Azure or AWS, for example? European Exoscale is not just hosting in Europe, but the company itself is also based in a European country. If that matters for you, either for sentimental reasons or as a matter of company policy (like using a provider that's not under the US CLOUD Act), it can be a big plus. Note though, that while Switzerland is highly aligned with the EU legally, it's not an EU member state, nor part of the European Economic Area. Costs Exoscale can be a lot cheaper. At €17/month, the Exoscale server provides roughly the same as an A1_v2 Azure VM, which costs €45/month. However, the smallest managed Postgres instance at €42/month is way above what we'd use on Azure for an entry-level app, where an S0 Azure SQL DB would be around €13/month. So, in the end, Exoscale costs around EUR 60/month, while the roughly equivalent service in Azure would be basically the same. We do get more with Exoscale (a dedicated VM for the DB, and I think the web server is faster too), a lot more room to grow, but the cost advantage, in itself, disappears, at least in the beginning. For an entry-level app the storage is cents in both cases, but if you increase your usage, Exoscale's storage costs can be dramatically lower (EUR 0,00002750/GB vs Azure's Standard Hot tier at EUR 0,0185/GB). Network costs at Exoscale (EUR 0,02/GB for egress) and per-operation costs at Azure (there's no simple number for this) complicate things, though, so be sure to calculate what's applicable for your app. All this being said, at Azure, we'd rather use App Services: This is a higher-level "websites as a service", offering a bunch of convenience features like automated deployment, staged publishing, and configuration management. The smallest proper App Services-based infrastructure (with a staging slot and separate staging and production DBs) comes at around €90/month, though, but that also contains a lot of features lacking from VMs. Simplicity Without consulting any resource, just by playing with the Console, I could fully understand the Exoscale offering (I think...) within like half an hour. Getting the full Orchard Core environment running wouldn't have been much more, have I not written this post at the same time (plus getting stuck on the mentioned storage configuration). The cons Coming from frequently using the cushy but extremely complex ecosystem of Azure, using a more basic provider like Exoscale is certainly an interesting change. It seems to me that ultimately, there's a lot of work to do if you want to have a full-blown, highly automated hosting environment for Orchard Core, with an option for horizontal scaling. Below are the features that I'd consider necessary, and while these are given with Azure, you need to roll your own solutions with Exoscale: Staged publishing (blue-green deployment): You'd need to set up multiple VMs or multiple sites, and manage swapping staging with production somehow on your own. Automated deployments: I think under a Windows server, the easiest would be to set up Web Deploy and use it from an automation platform like GitHub Actions. Observability: You'd either need to host an observability platform yourself, or use an external service. The lack of a search/indexing service is less of an issue, because you can just use the Elastic Cloud (what's the option in Azure and AWS too), and I'd consider the lack of an e-mail service not a huge issue either (you can just use something like SendGrid). Managed Valkey is good, but starting at €43/month, it's not priced for an easy entry (just as Postgres), although it also provides a lot more resources than the lowest tiers of Azure Cache for Redis do (for a lower price). Yes, you could build an all-in-one infrastructure with Kubernetes, and have containers with services for all the above features (and a DB and storage as well), but that's a large complexity you need to manage. Using Terraform, supported by Exoscale, to ramp up your infrastructure can cut down on manual repetition (and aid portability to other providers to an extent), but is also work that you have to invest. And at the entry level, managed solutions for services like SQL and Redis (instead of hosting your own VMs/containers) can be more cost-efficient too (but that flips if your app's demand increases).There are also three notable things I very much didn't like about Exoscale's pricing: All prices on the pricing page are shown for usage hours only. That's necessary, but a metric frequently a lot more useful is the monthly cost. While I can always multiply by 730 to get an approximation of a month, it would be much clearer to have it indicated in the pricing table already. Also, I'd welcome seeing these hourly and monthly costs indicated in the Exoscale Console, when creating resources, too. The Pricing Calculator helps, and it does show monthly costs too, but it's better to show this information everywhere. The prices in EUR, CHF, and USD are exactly the same. Given that 1 CHF is 1,07 EUR, and 1 EUR is 1,16 USD as of writing this, there's a significant difference in your costs depending on what you pay with (you pay almost 25% more in CHF than USD). According to the website, "Your account can be setup in either CHF, EUR or USD, depending on your initial legal residence." This seems like an arbitrary disadvantage for Swiss users, and an advantage to non-EU ones. The latter is a surprising policy for a company primarily targeting EU customers. I'd welcome the price differences to disappear.You can only pay in advance, at least as a new customer. This requires you to either be ready to top up your balance any time you get a low credit notification, or you need to park an excessive amount at Exoscale. In either case, it's also a manual process. It would be better if they would just charge my card after each month's usage. So, what should I do?Based on the feature set, Exoscale can be a good choice to host your Orchard Core app if you don't need anything beyond what's easily possible with the existing offering, or if you already invested into a portable Kubernetes-based infrastructure. However, I think the particularities of Exoscale's pricing are not for everyone. And if you need help hosting Orchard Core at Exoscale, Azure, or onboard of a satellite (not kidding), drop us a line!

Latest tutorials

Hosting Orchard Core at Exoscale
zoltan.lehoczky
Step away from that Node.js
sara.el-saig

Featured tags

AI
SMS
IIS
MCP
API
SEO
SSL
All tags >

Export contents as setup recipe, Shape Debug Mode to dynamic cache - This week in Orchard (24/07/2020)

Export contents as setup recipe and import recipe from JSON are about to make it easier to manipulate data and setup your Orchard Core site. Edit cached shapes using the Shape Debug mode to see your changes right away. We think if you are an Orchard Core developer, you will find these features very useful. These are the bigger topics for this week! Orchard Core updates Export Contents As Setup recipe This is a new feature that allows you to use a checkbox when you want to export some content and remove any information that would reuse properties like the content item ID, author, owner. Let's see an example for this and create a deployment plant that contains only that All content deployment step and see the JSON schema of the Blog content item that you can get if you install your site using the Blog recipe. So, if you leave this checkbox unchecked, you will see the following content. Nothing special here, you see the same content as you saw before. The content item has an ID, a version ID, and the dates when this content item was published and modified. But let's see what will happen if we put a tick in that checkbox! In this case, all the IDs are regenerated (for now it's not the case for the contained content items) and the values for the owner and the author are coming from the AdminUsername parameter. But be aware of the note that you can read under the checkbox: If checked, you will have to manually declare variables for the Content Picker fields, Taxonomy fields, Tags fields, and List item ids and replace them where needed in the recipe. Any reference to these content items will be lost. And the logic in the ContentDeploymentSource is about checking the value of the ExportAsSetupRecipe boolean property. If you want to export contents as a setup recipe, then the related properties of the objectData will be changed as you can see in the recipe file. We have to mention one new thing here. If you add the All features deployment step to your plan that exports the state of all features, you can say to ignore the disabled features. In that case, your recipe will only contain the enabled features and not the disabled ones. Import Recipe from JSON If you navigate to Configuration -> Import/Export in the admin UI, you will see a new option called JSON Import. This new feature will let you type some JSON and then run it, so you can execute some custom recipe steps from this UI. This new edition comes with the Deployment feature and it's using permission which is the Import permission. Let's say you want to change the site theme of your site for the default one. To do that you can use the following JSON. You can see you can do it in the same way as you would do it in a recipe file. Fix modules referencing other modules You may notice how many modules are referencing other modules for no need. Mostly this is just because they are doing so to get transitive references. The solution was to take direct references on the required abstractions/core projects instead of transitively depending on other modules to provide those references. Dean Marcussen also reviewed other references, removed superfluous references, and ordered them all. Migrate the OpenID module to OpenIddict 3.0 OpenIddict 3.0 has matured enough to envision using it in Orchard Core 1.0 RTM for both the server and validation features. As part of this migration, a few properties will be added to OpenIdServerSettings and OpenIdValidationSettings and others will be renamed for clarity. Due to this change, existing deployments will have to be updated to use the revamped settings. No exception should be thrown and the migration should be limited to re-configuring the server/validation options using the UI and/or updating custom recipes to use the new names. An important aspect of this migration is that the validation feature will now internally use the OpenIddict validation handler instead of the Microsoft JWT bearer handler, even with external OAuth 2.0 authorization servers. Unlike the MSFT JWT handler, the OpenIddict validation handler uses the new Microsoft.IdentityModel.JsonWebTokens stack and comes with JWT token type validation enforced by default, which is required by the not-yet-standardized JWT access token specification. This change will break existing deployments targeting OAuth 2.0 authorization servers that don't issue "typ": "at+jwt" access tokens. At least the following implementations are known to be impacted: Azure AD/B2C. IdentityServer3.IdentityServer4, except its latest 4.0 version (unless 4.0 is configured to use a different typ header) OpenIddict-based deployments are not impacted, as the validation handler includes special logic to deal with the tokens produced by OpenIddict 1.0 and 2.0, whose JWT tokens always include a special token_usage claim to prevent token substitution attacks, which has the same purpose as the "typ": "at+jwt" header. To ensure the validation feature can still be used with servers that don't issue "typ": "at+jwt" access tokens, an opt-in option was added to the validation configuration UI. This option can only be enabled when configuring a remote OAuth 2.0 server and is not shown when using a local OpenID server or a server located in another tenant, as OpenIddict 3.0 always issue "typ": "at+jwt" access tokens. Demos Shape Debug Mode to Dynamic Cache If you have a lot of menu shapes in your site and if you want to edit the templates you can't do that easily because the items are cached. The solution here is to provide an easy way to disable the cache, so in that case, the menus will not be cached. To set the cache mode, head to Configuration -> Settings -> General, where you will find a new tab called Cache. The settings here are very similar to the resource settings, the default is that the cache would be enabled in production and disabled otherwise. You can say I want to enable or disable it all the time. And there is a very useful option called Enabled with cache debug mode. Let's select this one and see what will happen! Now navigate to the homepage of your site and view the page source. Everywhere where is a cached block you will get a little piece of information about the given block. It shows you the cache ID, the dependencies that it's using, how long it's cached for, and any of the variations that are present. You will also see where is the end of the block. Let's see how it works! You will find a CacheStatement class that is about to check the value of the cacheOptions.DebugMode and if it's true, then it will add the additional content to the source of the page. If you are interested in more details about the cache settings, head to YouTube, and see the recording of the demo! News from the community Orchard Core workshops The contributors of Orchard Core will hold some unique online workshops in September 2020. So even with Orchard Harvest postponed due to the coronavirus pandemic we'll get some new learning events. Are you looking to get up to speed with Orchard? Check out the workshops' details on the Orchard Core homepage! Orchard Dojo Newsletter Now we have 154 subscribers of the Lombiq's Orchard Dojo Newsletter! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

Sortable lists, IScopedDistributedCache - This week in Orchard (17/01/2020)

Get ready for a deep dive! In our post, we will introduce the IScopedDitributedCache service and show how to use it in the RoleStore. And we are going to solve the mystery about do you need the Model prefix to access different kinds of properties of a model in Liquid and in Razor too? Orchard Core updates Document recipes new Lucene settings There is new documentation on the updated Lucene index settings. Now to create an index from a recipe, it's not just about passing the name of the analyzer. You have to provide the following: AnalyzerName: the name of the analyzer, that you want to use. IndexLatest: a boolean value that indicates that if you want to index the latest or just the published versions. IndexedContentTypes: the list of types you want to index. Re-use in some places the ContentItem Liquid property There was a change in the Liquid TemplateContext, that broke some properties, that are available in the templates. If your AliasPart, AutoroutePart or Workflows patterns don't work anymore, it's because of the previous change. Now, this issue has been fixed. For example in an Autoroute pattern that used to render the custom URL of the content type you could do something like: {{ ContentItem.DisplayText | slugify }} That will generate a nice text for your routes. But in some cases, you have to write {{ Model.ContentItem.DisplayText | slugify }}. Maybe using the Model prefix is collateral damage, but maybe it has a purpose. Anytime we have a Liquid template for a shape we do Model.ContentItem to get the ContentItem. In Razor everything is Model.Something. It has to be because in Razor we are doing C# and the current context is the page and the page is a class that doesn't have our properties like @ContentItem. So the only thing we could get is the @Model that is typed to the generic type of the RazorPage and Model will provide all the properties like the ContentItem. Because we do too much Razor, it could be possible that we reused this approach into some Liquid patterns. In Liquid it's not necessary to have the Model prefix. But it appears that there is already a way in Fluid to use a first-level model without a custom prefix (so we don't need a Model prefix), by setting the TemplateContext.Model property. In conclusion: in Liquid that is easier to write {{ ContentItem.DisplayText }}, you don't need the Model prefix. But in Razor, you have to use the Model prefix. Constraint admin controllers to mapped routes Since we can change the prefix of the admin route, we have to ensure that every admin controller's actions have the correct prefix to use. There is an implementation of the IActionConstraint, called AdminActionConstraint, that checks if we are in the admin and the route doesn't start with the admin URL prefix (_adminUrlPrefix), then it will create a warning log entry. So, the AdminActionConstraint applies a convention that restraints all AdminControllers or [Admin] controllers to use the mapped route only, and not the default route applied by MVC. Fix the recipes not found bug in the documentation We have a guide about how to create a new decoupled CMS Website using Orchard Core. It told you to add the OrchardCore.Application.Cms.Core.Targets NuGet package to your new ASP.NET Core project, because this package won't contain the themes. And when you do a decoupled CMS site you will don't need the themes, because you want to create your own front end. The issue is with this package on the master branch is that the setup doesn't contain any recipe in the RC1 version. The community fixed that bug for now, but it's just in the dev branch yet. So, if you follow the guide and you using the RC1 version of that package, when you arrive at the setup screen you will not be able to set up the site because there will be no recipe to choose from. Mitigation is to use the OrchardCore.Application.Cms.Targets package, that contains all the themes and recipes. Of course, in this case, you will get several unwanted themes, but you will not be blocked to continue following the guide. So, it's not the perfect solution, but when there will be a new version of Orchard Core, we can rewrite this back to use the OrchardCore.Application.Cms.Core.Targets NuGet. There is also a hint about if you are using the nightly builds of Orchard Core then you should use the Core package instead. Creating IScopedDitributedCache The main goal is to increase the performance of Orchard Core and try to make it faster from time to time. To measure that, check the blog posts Liquid template page and start to remove everything from there. Just to see how fast could be the performance if we didn't render anything. Then start to remove stuff from the controller that displays content. For example, let's take a look at the ItemController. This is the controller, that renders content items by default. Take a closer look at the Display method of this controller! It first loads the content item. If it's not there, we return a 404. Then we check the ViewContent permission for this content item for the current user. We return Forbid if they authenticated but don't have the proper permission, or return Challange if the user is anonymous. Now let's build the display! That will build a shape containing all the part shapes and everything for this content item. So, it will render the display of this content item and we send this shape to a view that will just call Display of the shape. That's what we do in this method. The thing that made it slow actually is that one which checks the permissions, the _authorizationService.AuthorizeAsync. The user is anonymous and checking that the anonymous users could see something was the bottleneck of the performance. For each display of the site, there would be a database query just to authorize the anonymous user to be able to see something. This is actually a regression. Once you remove this code the controller will be much faster. An authenticated user would have added Claims cached in the User object. But in the case of an anonymous user, nothing was cached. Each request for an anonymous user would ask the permission for the anonymous user from the RoleStore. The RoleStore would do a query all the time. There is a new service, called ScopedDistributedCache. The idea is to use a distributed cache, such that we would store the Roles document in memory if we have a single node or in a store that is shared across every node if you have multiple nodes. Scoped means if you do multiple queries on the same cache entry for the same request, then we will load it from the DistributedCache only once. That will be much faster if you have multiple queries. You can see the usage of the ScopedDistributedCache in the RoleStore. Instead of injecting the IMemoryCache (that puts everything in the memory that shared by all the request) here comes the IScopedDitributedCache. The code is much simpler with that: you just pass it an object. Check the GetRolesAsync and the UpdateRolesAsync methods of the RoleStore. Demos Make lists sortable with ordering setting Let's say you have a site that you set up using the Blog recipe. In that recipe you can find a Blog content type, that is used as a container of the Blog Post content items. To behave the Blog content type this way, you need to add the ListPart to it, which will add the list behavior. Here you could see a new option before the Contained Content Types list, called Enable Ordering. If you check this option you will enable the manual ordering of the items. Let's put a tick here! Now head to the Content -> Content Items page and select the one named Blog (or just simply hit Blog from the menu). Here you can see the list of the blog posts contained in this blog content item. Let's add more posts to it to see the power of this new feature! By using a simple drag and drop, you can set the order of the different items and save it on the fly. Check out the following GIF to see how the reordering works! This feature is under development, but you can find the code in this pull request. And don't forget to watch the recording about this demo, where you can also hear an informative discussion about some interesting questions to solve, for example, what about reordering content items that have a published and a draft version too? News from the community New Orchard Core site: Buzz Interactive Buzz believes that great digital products are built on intelligent strategy and outstanding technical abilities. They partner with vibrant clients and help them create future-proof platforms for web, app, and VR. And they use Orchard Core for their site! If you are interested in more websites using Orchard and Orchard Core, don't forget to visit Show Orchard. Show Orchard is a website for showing representative Orchard CMS (and now Orchard Core) websites all around the internet. It was started by Ryan Drew Burnett, but since he doesn't work with Orchard anymore, as announced earlier it is now maintained by our team at Lombiq Technologies. Tell us about your .NET performance challenges! - Hastlayer developer survey Help us build the nerdiest .NET thing, Hastlayer: It turns performance-critical sections of .NET programs into computer chips! If you fill out our short questionnaire you can win a cool compute accelerator board worth $265! Check it out here: https://forms.office.com/Pages/ResponsePage.aspx?id=Wt6elek45kStyIVVO-uCIMkFNjqW2E1Pm4v3YMcflMNUOVlDNUE3MlpDS044VDI1OEFSMUgxUkxSTC4u The reason we're asking this is that we're building a .NET hardware accelerator, Hastlayer (https://github.com/Lombiq/Hastlayer-SDK it turns your program into a chip!) and want to better understand what other developers do. Thank you in advance! Orchard Dojo Newsletter Now we have 113 subscribers of the Lombiq's Orchard Dojo Newsletter! We have started this newsletter to inform the community around Orchard with the latest news about the platform. By subscribing to this newsletter, you will get an e-mail whenever a new post published to Orchard Dojo, including This week in Orchard of course. Do you know of other Orchard enthusiasts who you think would like to read our weekly articles? Tell them to subscribe here! If you are interested in more news around Orchard and the details of the topics above, don't forget to check out the recording of this week's Orchard meeting!

Performance-tuning modules you should know about

These modules are really useful if you want to squeeze out the performance of your Orchard website: Mini Profiler for profiling Orchard.Caching for a wide variety of caching solutions Cache for output caching (included in Orchard as of Orchard 1.7) Combinator for bundling and minifying static resources (stylesheets, scripts)