Skip to content

Commit 53c6bda

Browse files
author
Ben Lilley
committed
feat: initial import
1 parent dcf1e23 commit 53c6bda

25 files changed

+855
-1
lines changed

IISUrlRewrite.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<rewrite>
3+
<rules>
4+
<rule name="Redirect to HTTPS" stopProcessing="true">
5+
<match url=".*" />
6+
<conditions>
7+
<add input="{HTTPS}" pattern="^OFF$" />
8+
<add input="{HTTP_HOST}" pattern="^localhost(:[0-9]+)?$" negate="true" />
9+
</conditions>
10+
<action type="Redirect" url="https://{HTTP_HOST}/{R:0}" />
11+
</rule>
12+
</rules>
13+
</rewrite>

Program.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace umbraco_example
2+
{
3+
public class Program
4+
{
5+
public static void Main(string[] args)
6+
=> CreateHostBuilder(args)
7+
.Build()
8+
.Run();
9+
10+
public static IHostBuilder CreateHostBuilder(string[] args) =>
11+
Host.CreateDefaultBuilder(args)
12+
.ConfigureUmbracoDefaults()
13+
.ConfigureWebHostDefaults(webBuilder =>
14+
{
15+
webBuilder.UseStaticWebAssets();
16+
webBuilder.UseStartup<Startup>();
17+
});
18+
}
19+
}

Properties/launchSettings.json

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"$schema": "https://json.schemastore.org/launchsettings.json",
3+
"iisSettings": {
4+
"windowsAuthentication": false,
5+
"anonymousAuthentication": true,
6+
"iisExpress": {
7+
"applicationUrl": "https://localhost"
8+
}
9+
},
10+
"profiles": {
11+
"IIS Express": {
12+
"commandName": "IISExpress",
13+
"launchBrowser": true,
14+
"environmentVariables": {
15+
"ASPNETCORE_ENVIRONMENT": "Development"
16+
}
17+
},
18+
"Umbraco.Web.UI": {
19+
"commandName": "Project",
20+
"dotnetRunMessages": true,
21+
"launchBrowser": true,
22+
"applicationUrl": "",
23+
"environmentVariables": {
24+
"ASPNETCORE_ENVIRONMENT": "Development"
25+
}
26+
}
27+
}
28+
}

README.md

Lines changed: 144 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,144 @@
1-
# container-umbraco-example
1+
# Umbraco Container Example
2+
This repository is an example of how you may create your own Umbraco instance using Webslice Containers. We recommend creating your own repository, however this can serve as an example of how you may want to create your Umbraco project.
3+
4+
This document will assume your local system is using Ubuntu Linux (22.04 LTS Jammy). Your instructions may be different depending on your system. On the container side, the instructions should remain the same.
5+
6+
## Requirements
7+
First you'll need to install the .NET SDK onto your local system.
8+
For Ubuntu linux you can install it via snap using `snap install --classic dotnet-sdk` Depending on your version, distro and OS you will need to run your own commands.
9+
After that, you will need to install Umbraco `dotnet new -i Umbraco.Templates`.
10+
You can choose which version you wish to use like so. `dotnet new -i Umbraco.Templates:10.3.2`
11+
> Note we are currently only able to support Umbraco version 10 and up. Umbraco version below 10 requires .NET versions lower than 6 which is not available as a standard container image.
12+
13+
For our Webslice Container, we will want to create a SSH user that GitHub will use to connect to our container. We recommend creating a new user specifically for GitHub in the event of a compromise.
14+
15+
## Creating the Umbraco Project
16+
To create the project you will want to run the following command: `dotnet new umbraco --name <Project Name/Directory>`
17+
Once that is done you will now have a new Umbraco project under the same name as the project name.
18+
There's a couple of changes we need to make in the file `Properties/launchSettings.json`.
19+
Under `issSetings`, you will need to change `applicationUrl` to `http://localhost`. After that you will need to change `sslPort` to `80`.
20+
Next under `Umbraco.Web.UI` you will need to remove all of the URLs in `applicaationUrl` and leave the list empty.
21+
22+
After all of that, your `launchSettings.json` should look like this.
23+
```json
24+
{
25+
"$schema": "https://json.schemastore.org/launchsettings.json",
26+
"iisSettings": {
27+
"windowsAuthentication": false,
28+
"anonymousAuthentication": true,
29+
"iisExpress": {
30+
"applicationUrl": "http://localhost"
31+
}
32+
},
33+
"profiles": {
34+
"IIS Express": {
35+
"commandName": "IISExpress",
36+
"launchBrowser": true,
37+
"environmentVariables": {
38+
"ASPNETCORE_ENVIRONMENT": "Development"
39+
}
40+
},
41+
"Umbraco.Web.UI": {
42+
"commandName": "Project",
43+
"dotnetRunMessages": true,
44+
"launchBrowser": true,
45+
"applicationUrl": "",
46+
"environmentVariables": {
47+
"ASPNETCORE_ENVIRONMENT": "Development"
48+
}
49+
}
50+
}
51+
}
52+
```
53+
54+
Lastly for our project, we'll need to ensure that Umbraco doesn't run the installation wizard. You can do this step after you have deployed the project first onto a Webslice Container or before hand where you'll have to define some variables.
55+
56+
We'll start with the latter. To start, we'll need our default admin login details. You'll need to add in the following underneath `CMS`.
57+
```json
58+
"Umbraco": {
59+
"CMS": {
60+
"Unattended": {
61+
"InstallUnattended": true,
62+
"UnattendedUserName": "tester",
63+
"UnattendedUserEmail": "[email protected]",
64+
"UnattendedUserPassword": "P@ssw0rd"
65+
},
66+
```
67+
Next you'll need to enter a `ConnectionString`. For this example, we'll assume you're using SQLite.
68+
```json
69+
"ConnectionStrings": {
70+
"umbracoDbDSN": "Data Source=|DataDirectory|/Umbraco.sqlite.db;Cache=Shared;Foreign Keys=True;Pooling=True",
71+
"umbracoDbDSN_ProviderName": "Microsoft.Data.Sqlite"
72+
}
73+
```
74+
For more information on ConnectionStrings, you can check out Umbraco's documentation [here](https://docs.umbraco.com/umbraco-cms/reference/configuration/connectionstringssettings).
75+
With those two done. Your `appsettings.json` file should look something like this:
76+
```json
77+
{
78+
"$schema": "appsettings-schema.json",
79+
"Serilog": {
80+
"MinimumLevel": {
81+
"Default": "Information",
82+
"Override": {
83+
"Microsoft": "Warning",
84+
"Microsoft.Hosting.Lifetime": "Information",
85+
"System": "Warning"
86+
}
87+
}
88+
},
89+
"Umbraco": {
90+
"CMS": {
91+
"Unattended": {
92+
"InstallUnattended": true,
93+
"UnattendedUserName": "tester",
94+
"UnattendedUserEmail": "[email protected]",
95+
"UnattendedUserPassword": "P@ssw0rd"
96+
},
97+
98+
"Global": {
99+
"Id": "9580700d-ac3c-4039-876a-d79fa92bf392",
100+
"SanitizeTinyMce": true
101+
},
102+
"Content": {
103+
"AllowEditInvariantFromNonDefault": true,
104+
"ContentVersionCleanupPolicy": {
105+
"EnableCleanup": true
106+
}
107+
}
108+
}
109+
},
110+
"ConnectionStrings": {
111+
"umbracoDbDSN": "Data Source=|DataDirectory|/Umbraco.sqlite.db;Cache=Shared;Foreign Keys=True;Pooling=True",
112+
"umbracoDbDSN_ProviderName": "Microsoft.Data.Sqlite"
113+
}
114+
}
115+
```
116+
117+
If you want to run the Installation wizard, run the wizard once, take the `appsettings.json` file from the deployed website directory then add `Unattended` object with only`InstallUnattended` inside. You do not need to add the admin user details.
118+
119+
## Setting up the Container
120+
For our Webslice Container, we need to make some changes. The first change we need to make is to clear our the `/container/application/public` directory. A simple `rm -rf /container/application/public/*` will do the trick.
121+
Next we'll need to change our supervisor config under `/container/config/supervisord.conf`.
122+
The only line you need to edit is to change `command=/usr/bin/dotnet Example.dll` to `command=/usr/bin/dotnet <Project Name>.dll`.
123+
124+
## Configuring up GitHub Actions
125+
After creating a GitHub repo, what you can do now is create your workflow file. We recommend adjusting your workflow to your project's requirements.
126+
For the sake of this example, we will provide a workflow file that you can find under `.github/workflows/umbraco.yml-example`. Ensure to rename to file by removing the `-example` once you have made your changes.
127+
The workflow file here has a couple of environment variables we will need to add into our GitHub repository.
128+
129+
Go into your repository's `Settings` tab then go into `Secrets and variables` then into the subcategory `Actions`.
130+
131+
Once there you will need to add three environment variables. `SSH_HOST`, `SSH_USER`, `SSH_KEY`. `SSH_PASSWORD` is also available if you want to use a password instead of a private/public key (although you will need to uncomment a line from the workflow file).
132+
133+
You will want to add the IP address for your Webslice Container into `SSH_HOST`, your SSH username into `SSH_USER` and your choice between private key into `SSH_KEY` or password into `SSH_PASSWORD`.
134+
135+
## Finishing up
136+
To make sure the initial set up of the wizard is gone through, you will want to download the `appsettings.json` from the server and copy it over to the repository. This will save the configurations you've made through the wizard as without saving it, every time you compile the project, it will overwrite those settings with the default settings.
137+
138+
After this, any push or pull request that is done to the repository the Action will run. This will build, test and then upload the compiled build up to the container. You will need to restart the Container from the Webslice Console for the changes to take effect.
139+
140+
## Adding new Packages
141+
To add new packages, you can simply add them like other .NET packages. If you go to the Packages tab underneath your Umbraco control panel, you can click on whichever package you want and it will give you the command to run. Do this in your repository, commit and push the changes then GitHub actions will push the Package to your server.
142+
143+
## Enforcing HTTPS
144+
You can check out our [.NET/ASP.NET SSL documentation](https://webslice.com/docs/containers/features/ssl/#netaspnet) for more information.

Startup.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
namespace umbraco_example
2+
{
3+
public class Startup
4+
{
5+
private readonly IWebHostEnvironment _env;
6+
private readonly IConfiguration _config;
7+
8+
/// <summary>
9+
/// Initializes a new instance of the <see cref="Startup" /> class.
10+
/// </summary>
11+
/// <param name="webHostEnvironment">The web hosting environment.</param>
12+
/// <param name="config">The configuration.</param>
13+
/// <remarks>
14+
/// Only a few services are possible to be injected here https://github.com/dotnet/aspnetcore/issues/9337.
15+
/// </remarks>
16+
public Startup(IWebHostEnvironment webHostEnvironment, IConfiguration config)
17+
{
18+
_env = webHostEnvironment ?? throw new ArgumentNullException(nameof(webHostEnvironment));
19+
_config = config ?? throw new ArgumentNullException(nameof(config));
20+
}
21+
22+
/// <summary>
23+
/// Configures the services.
24+
/// </summary>
25+
/// <param name="services">The services.</param>
26+
/// <remarks>
27+
/// This method gets called by the runtime. Use this method to add services to the container.
28+
/// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940.
29+
/// </remarks>
30+
public void ConfigureServices(IServiceCollection services)
31+
{
32+
services.Configure<ForwardedHeadersOptions>(options =>
33+
{
34+
// Sets the expected Forward headers
35+
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
36+
// Both functions allows any local network or proxy to connect.
37+
options.KnownNetworks.Clear();
38+
options.KnownProxies.Clear();
39+
});
40+
41+
services.AddUmbraco(_env, _config)
42+
.AddBackOffice()
43+
.AddWebsite()
44+
.AddComposers()
45+
.Build();
46+
}
47+
48+
/// <summary>
49+
/// Configures the application.
50+
/// </summary>
51+
/// <param name="app">The application builder.</param>
52+
/// <param name="env">The web hosting environment.</param>
53+
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
54+
{
55+
if (env.IsDevelopment())
56+
{
57+
app.UseDeveloperExceptionPage();
58+
}
59+
60+
// This adds the forwarded headers from above.
61+
app.UseForwardedHeaders();
62+
63+
// Enforces HTTPS redirection
64+
app.UseHttpsRedirection();
65+
66+
// Adds our own rewriter that uses the IISUrlRewrite.xml file
67+
app.UseRewriter(new RewriteOptions().AddIISUrlRewrite(env.ContentRootFileProvider, "IISUrlRewrite.xml"));
68+
69+
app.UseUmbraco()
70+
.WithMiddleware(u =>
71+
{
72+
u.UseBackOffice();
73+
u.UseWebsite();
74+
})
75+
.WithEndpoints(u =>
76+
{
77+
u.UseInstallerEndpoints();
78+
u.UseBackOfficeEndpoints();
79+
u.UseWebsiteEndpoints();
80+
});
81+
}
82+
}
83+
}

Views/.DS_Store

6 KB
Binary file not shown.

Views/Partials/.DS_Store

6 KB
Binary file not shown.

Views/Partials/blockgrid/area.cshtml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@using Umbraco.Extensions
2+
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockGridArea>
3+
4+
<div class="umb-block-grid__area"
5+
data-area-col-span="@Model.ColumnSpan"
6+
data-area-row-span="@Model.RowSpan"
7+
data-area-alias="@Model.Alias"
8+
style="--umb-block-grid--grid-columns: @Model.ColumnSpan;--umb-block-grid--area-column-span: @Model.ColumnSpan; --umb-block-grid--area-row-span: @Model.RowSpan;">
9+
@await Html.GetBlockGridItemsHtmlAsync(Model)
10+
</div>

Views/Partials/blockgrid/areas.cshtml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@using Umbraco.Extensions
2+
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockGridItem>
3+
@{
4+
if (Model?.Areas.Any() != true) { return; }
5+
}
6+
7+
<div class="umb-block-grid__area-container"
8+
style="--umb-block-grid--area-grid-columns: @(Model.AreaGridColumns?.ToString() ?? Model.GridColumns?.ToString() ?? "12");">
9+
@foreach (var area in Model.Areas)
10+
{
11+
@await Html.GetBlockGridItemAreaHtmlAsync(area)
12+
}
13+
</div>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@using Umbraco.Extensions
2+
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockGridModel>
3+
@{
4+
if (Model?.Any() != true) { return; }
5+
}
6+
7+
<div class="umb-block-grid"
8+
data-grid-columns="@(Model.GridColumns?.ToString() ?? "12");"
9+
style="--umb-block-grid--grid-columns: @(Model.GridColumns?.ToString() ?? "12");">
10+
@await Html.GetBlockGridItemsHtmlAsync(Model)
11+
</div>

Views/Partials/blockgrid/items.cshtml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
@using Umbraco.Cms.Core.Models.Blocks
2+
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<IEnumerable<BlockGridItem>>
3+
@{
4+
if (Model?.Any() != true) { return; }
5+
}
6+
7+
<div class="umb-block-grid__layout-container">
8+
@foreach (var item in Model)
9+
{
10+
11+
<div
12+
class="umb-block-grid__layout-item"
13+
data-content-element-type-alias="@item.Content.ContentType.Alias"
14+
data-content-element-type-key="@item.Content.ContentType.Key"
15+
data-element-udi="@item.ContentUdi"
16+
data-col-span="@item.ColumnSpan"
17+
data-row-span="@item.RowSpan"
18+
style=" --umb-block-grid--item-column-span: @item.ColumnSpan; --umb-block-grid--item-row-span: @item.RowSpan; ">
19+
@{
20+
var partialViewName = "blockgrid/Components/" + item.Content.ContentType.Alias;
21+
try
22+
{
23+
@await Html.PartialAsync(partialViewName, item)
24+
}
25+
catch (InvalidOperationException)
26+
{
27+
<p>
28+
<strong>Could not render component of type: @(item.Content.ContentType.Alias)</strong>
29+
<br/>
30+
This likely happened because the partial view <em>@partialViewName</em> could not be found.
31+
</p>
32+
}
33+
}
34+
</div>
35+
}
36+
</div>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage<Umbraco.Cms.Core.Models.Blocks.BlockListModel>
2+
@{
3+
if (Model?.Any() != true) { return; }
4+
}
5+
<div class="umb-block-list">
6+
@foreach (var block in Model)
7+
{
8+
if (block?.ContentUdi == null) { continue; }
9+
var data = block.Content;
10+
11+
@await Html.PartialAsync("blocklist/Components/" + data.ContentType.Alias, block)
12+
}
13+
</div>

0 commit comments

Comments
 (0)