diff --git a/src/Umbraco.Infrastructure/Install/FilePermissionHelper.cs b/src/Umbraco.Infrastructure/Install/FilePermissionHelper.cs
index ccb3e4a0da..d3777d4113 100644
--- a/src/Umbraco.Infrastructure/Install/FilePermissionHelper.cs
+++ b/src/Umbraco.Infrastructure/Install/FilePermissionHelper.cs
@@ -51,7 +51,6 @@ public class FilePermissionHelper : IFilePermissionHelper
{
hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.Bin),
hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.Umbraco),
- hostingEnvironment.MapPathWebRoot(_globalSettings.UmbracoPath),
hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.Packages),
};
}
diff --git a/src/Umbraco.Web.UI/Program.cs b/src/Umbraco.Web.UI/Program.cs
index e91f6ba60d..8fca919b0a 100644
--- a/src/Umbraco.Web.UI/Program.cs
+++ b/src/Umbraco.Web.UI/Program.cs
@@ -3,7 +3,9 @@ WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.CreateUmbracoBuilder()
.AddBackOffice()
.AddWebsite()
+#if UseDeliveryApi
.AddDeliveryApi()
+#endif
.AddComposers()
.Build();
@@ -23,6 +25,9 @@ app.UseUmbraco()
})
.WithEndpoints(u =>
{
+ /*#if (UmbracoRelease = 'LTS')
+ u.UseInstallerEndpoints();
+ #endif */
u.UseBackOfficeEndpoints();
u.UseWebsiteEndpoints();
});
diff --git a/templates/Umbraco.Templates.csproj b/templates/Umbraco.Templates.csproj
index 57830bff09..b75df9f9a5 100644
--- a/templates/Umbraco.Templates.csproj
+++ b/templates/Umbraco.Templates.csproj
@@ -19,6 +19,7 @@
+
UmbracoProject\Views\Partials\blocklist\%(RecursiveDir)%(Filename)%(Extension)
UmbracoProject\Views\Partials\blocklist
@@ -47,7 +48,7 @@
-
+
<_PackageFiles Include="%(_TemplateJsonFiles.DestinationFile)">
%(_TemplateJsonFiles.RelativeDir)
diff --git a/templates/UmbracoDockerCompose/.env b/templates/UmbracoDockerCompose/.env
new file mode 100644
index 0000000000..38985be5c5
--- /dev/null
+++ b/templates/UmbracoDockerCompose/.env
@@ -0,0 +1 @@
+DB_PASSWORD=Password1234
diff --git a/templates/UmbracoDockerCompose/.template.config/dotnetcli.host.json b/templates/UmbracoDockerCompose/.template.config/dotnetcli.host.json
new file mode 100644
index 0000000000..aaab590168
--- /dev/null
+++ b/templates/UmbracoDockerCompose/.template.config/dotnetcli.host.json
@@ -0,0 +1,24 @@
+{
+ "$schema": "https://json.schemastore.org/dotnetcli.host.json",
+ "symbolInfo": {
+ "ProjectName": {
+ "longName": "ProjectName",
+ "shortName": "P"
+ },
+ "DatabasePassword": {
+ "longName": "DatabasePassword",
+ "shortName": "dbpw"
+ },
+ "Port":
+ {
+ "longName": "Port",
+ "shortName": "p"
+ }
+ },
+ "usageExamples": [
+ "dotnet new umbraco-compose -P MyProject",
+ "dotnet new umbraco-compose --ProjectName MyProject",
+ "dotnet new umbraco-compose -P -MyProject -dbpw MyStr0ngP@ssword",
+ "dotnet new umbraco-compose -P -MyProject --DatabasePassword MyStr0ngP@ssword"
+ ]
+}
diff --git a/templates/UmbracoDockerCompose/.template.config/ide.host.json b/templates/UmbracoDockerCompose/.template.config/ide.host.json
new file mode 100644
index 0000000000..ae8c5fb05c
--- /dev/null
+++ b/templates/UmbracoDockerCompose/.template.config/ide.host.json
@@ -0,0 +1,23 @@
+{
+ "$schema": "https://json.schemastore.org/ide.host.json",
+ "order": 0,
+ "icon": "../../icon.png",
+ "description": {
+ "id": "UmbracoDockerCompose",
+ "text": "Umbraco Docker Compose - Docker compose for Umbraco CMS and associated database"
+ },
+ "symbolInfo": [
+ {
+ "id": "ProjectName",
+ "isVisible": true
+ },
+ {
+ "id": "DatabasePassword",
+ "isVisible": true
+ },
+ {
+ "id": "Port",
+ "isVisible": true
+ }
+ ]
+}
diff --git a/templates/UmbracoDockerCompose/.template.config/template.json b/templates/UmbracoDockerCompose/.template.config/template.json
new file mode 100644
index 0000000000..6f6877b7e0
--- /dev/null
+++ b/templates/UmbracoDockerCompose/.template.config/template.json
@@ -0,0 +1,49 @@
+{
+ "$schema": "https://json.schemastore.org/template.json",
+ "author": "Umbraco HQ",
+ "classifications": [
+ "Web",
+ "CMS",
+ "Umbraco"
+ ],
+ "name": "Umbraco Docker Compose",
+ "description": "Creates the prerequisites for developing Umbraco in Docker containers",
+ "groupIdentity": "Umbraco.Templates.UmbracoDockerCompose",
+ "identity": "Umbraco.Templates.UmbracoDockerCompose",
+ "shortName": "umbraco-compose",
+ "tags": {
+ "type": "item"
+ },
+ "symbols": {
+ "ProjectName": {
+ "type": "parameter",
+ "description": "The name of the project the Docker Compose file will be created for",
+ "datatype": "string",
+ "replaces": "UmbracoProject",
+ "isRequired": true
+ },
+ "DatabasePassword": {
+ "type": "parameter",
+ "description": "The password to the database, will be stored in .env file",
+ "datatype": "string",
+ "replaces": "Password1234",
+ "defaultValue": "Password1234"
+ },
+ "Port": {
+ "type": "parameter",
+ "description": "The port forward on the docker container, this is the port you use to access the site",
+ "datatype": "string",
+ "replaces": "TEMPLATE_PORT",
+ "defaultValue": "44372"
+ },
+ "ImageName": {
+ "type": "generated",
+ "generator": "casing",
+ "parameters": {
+ "source": "ProjectName",
+ "toLower": true
+ },
+ "replaces": "umbraco_image"
+ }
+ }
+}
diff --git a/templates/UmbracoDockerCompose/Database/Dockerfile b/templates/UmbracoDockerCompose/Database/Dockerfile
new file mode 100644
index 0000000000..4e74b6435e
--- /dev/null
+++ b/templates/UmbracoDockerCompose/Database/Dockerfile
@@ -0,0 +1,21 @@
+FROM mcr.microsoft.com/azure-sql-edge:latest
+
+ENV ACCEPT_EULA=Y
+
+USER root
+
+RUN mkdir /var/opt/sqlserver
+
+RUN chown mssql /var/opt/sqlserver
+
+ENV MSSQL_BACKUP_DIR="/var/opt/mssql"
+ENV MSSQL_DATA_DIR="/var/opt/mssql/data"
+ENV MSSQL_LOG_DIR="/var/opt/mssql/log"
+
+EXPOSE 1433/tcp
+COPY setup.sql /
+COPY startup.sh /
+COPY healthcheck.sh /
+
+ENTRYPOINT [ "/bin/bash", "startup.sh" ]
+CMD [ "/opt/mssql/bin/sqlservr" ]
diff --git a/templates/UmbracoDockerCompose/Database/healthcheck.sh b/templates/UmbracoDockerCompose/Database/healthcheck.sh
new file mode 100644
index 0000000000..2964e17dc4
--- /dev/null
+++ b/templates/UmbracoDockerCompose/Database/healthcheck.sh
@@ -0,0 +1,15 @@
+value="$(/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "$SA_PASSWORD" -d master -Q "SELECT state_desc FROM sys.databases WHERE name = 'umbracoDb'" | awk 'NR==3')"
+
+# This checks for any non-zero length string, and $value will be empty when the database does not exist.
+if [ -n "$value" ]
+then
+ echo "ONLINE"
+ return 0 # With docker 0 = success
+else
+ echo "OFFLINE"
+ return 1 # And 1 = unhealthy
+fi
+
+# This is useful for debugging
+# echo "Value is:"
+# echo "$value"
diff --git a/templates/UmbracoDockerCompose/Database/setup.sql b/templates/UmbracoDockerCompose/Database/setup.sql
new file mode 100644
index 0000000000..466030dd50
--- /dev/null
+++ b/templates/UmbracoDockerCompose/Database/setup.sql
@@ -0,0 +1,10 @@
+USE [master]
+GO
+
+IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = 'UmbracoDb')
+ BEGIN
+ CREATE DATABASE [umbracoDb]
+ END;
+GO
+
+USE UmbracoDb;
\ No newline at end of file
diff --git a/templates/UmbracoDockerCompose/Database/startup.sh b/templates/UmbracoDockerCompose/Database/startup.sh
new file mode 100644
index 0000000000..c4fad8f0ae
--- /dev/null
+++ b/templates/UmbracoDockerCompose/Database/startup.sh
@@ -0,0 +1,23 @@
+#!/bin/bash
+set -e
+
+# Taken from: https://github.com/CarlSargunar/Umbraco-Docker-Workshop
+if [ "$1" = '/opt/mssql/bin/sqlservr' ]; then
+ # If this is the container's first run, initialize the application database
+ if [ ! -f /tmp/app-initialized ]; then
+ # Initialize the application database asynchronously in a background process. This allows a) the SQL Server process to be the main process in the container, which allows graceful shutdown and other goodies, and b) us to only start the SQL Server process once, as opposed to starting, stopping, then starting it again.
+ function initialize_app_database() {
+ # Wait a bit for SQL Server to start. SQL Server's process doesn't provide a clever way to check if it's up or not, and it needs to be up before we can import the application database
+ sleep 15s
+
+ #run the setup script to create the DB and the schema in the DB
+ /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P "$SA_PASSWORD" -d master -i setup.sql
+
+ # Note that the container has been initialized so future starts won't wipe changes to the data
+ touch /tmp/app-initialized
+ }
+ initialize_app_database &
+ fi
+fi
+
+exec "$@"
diff --git a/templates/UmbracoDockerCompose/docker-compose.yml b/templates/UmbracoDockerCompose/docker-compose.yml
new file mode 100644
index 0000000000..7acae5d8d6
--- /dev/null
+++ b/templates/UmbracoDockerCompose/docker-compose.yml
@@ -0,0 +1,102 @@
+services:
+ umb_database:
+ container_name: umbraco_image_database
+ build:
+ context: ./Database
+ environment:
+ SA_PASSWORD: ${DB_PASSWORD}
+ MSSQL_SA_PASSWORD: ${DB_PASSWORD}
+ ports:
+ - "1433:1433"
+ - "1434:1434"
+ volumes:
+ - umb_database:/var/opt/mssql
+ networks:
+ - umbnet
+ healthcheck:
+ # This healthcheck is to make sure that the database is up and running before the umbraco container starts.
+ # It works by querying the database for the state of the umbracoDb database, ensuring it exists.
+ test: ./healthcheck.sh
+ interval: 5m
+ timeout: 5s
+ retries: 3
+ start_period: 15s # Bootstrap duration, for this duration failures does not count towards max retries.
+ start_interval: 5s # How long after the health check has started to run the healthcheck again.
+
+ umbraco_image:
+ image: umbraco_image
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ - ConnectionStrings__umbracoDbDSN=Server=umb_database;Database=umbracoDb;User Id=sa;Password=${DB_PASSWORD};TrustServerCertificate=true;
+ - ConnectionStrings__umbracoDbDSN_ProviderName=Microsoft.Data.SqlClient
+ volumes:
+ - umb_media:/app/wwwroot/media
+ - umb_scripts:/app/wwwroot/scripts
+ - umb_styles:/app/wwwroot/css
+ - umb_logs:/app/umbraco/Logs
+ - umb_views:/app/Views
+ - umb_data:/app/umbraco
+ - umb_models:/app/umbraco/models
+ build:
+ context: .
+ dockerfile: UmbracoProject/Dockerfile
+ args:
+ - BUILD_CONFIGURATION=Debug
+
+ depends_on:
+ umb_database:
+ condition: service_healthy
+ restart: always
+ ports:
+ - "TEMPLATE_PORT:8080"
+ networks:
+ - umbnet
+ develop:
+ # This allows you to run docker compose watch, after doing so the container will rebuild when the models are changed.
+ # Once a restart only feature is implemented (https://github.com/docker/compose/issues/11446)
+ # It would be really nice to add a restart only watch to \Views, since the file watchers for recompilation of Razor views does not work with docker.
+ watch:
+ - path: ./UmbracoProject/umbraco/models
+ action: rebuild
+
+# These volumes are all made as bind mounts, meaning that they are bound to the host machine's file system.
+# This is to better facilitate local development in the IDE, so the views, models, etc... are available in the IDE.
+# This can be changed by removing the driver and driver_opts from the volumes.
+volumes:
+ umb_media:
+ driver: local
+ driver_opts:
+ type: none
+ device: ./UmbracoProject/wwwroot/media
+ o: bind
+ umb_scripts:
+ driver: local
+ driver_opts:
+ type: none
+ device: ./UmbracoProject/wwwroot/scripts
+ o: bind
+ umb_styles:
+ driver: local
+ driver_opts:
+ type: none
+ device: ./UmbracoProject/wwwroot/css
+ o: bind
+ umb_logs:
+ umb_views:
+ driver: local
+ driver_opts:
+ type: none
+ device: ./UmbracoProject/Views
+ o: bind
+ umb_data:
+ umb_models:
+ driver: local
+ driver_opts:
+ type: none
+ device: ./UmbracoProject/umbraco/models
+ o: bind
+ umb_database:
+
+networks:
+ umbnet:
+ driver: bridge
diff --git a/templates/UmbracoProject/.dockerignore b/templates/UmbracoProject/.dockerignore
new file mode 100644
index 0000000000..2f32bfe4fe
--- /dev/null
+++ b/templates/UmbracoProject/.dockerignore
@@ -0,0 +1,25 @@
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/.idea
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
diff --git a/templates/UmbracoProject/.template.config/dotnetcli.host.json b/templates/UmbracoProject/.template.config/dotnetcli.host.json
index dfd6f80184..b18020b6de 100644
--- a/templates/UmbracoProject/.template.config/dotnetcli.host.json
+++ b/templates/UmbracoProject/.template.config/dotnetcli.host.json
@@ -8,12 +8,25 @@
},
"UmbracoVersion": {
"longName": "version",
- "shortName": "v"
+ "shortName": "v",
+ "isHidden": true
+ },
+ "UmbracoRelease": {
+ "longName": "release",
+ "shortName": "r"
},
"UseHttpsRedirect": {
"longName": "use-https-redirect",
"shortName": ""
},
+ "UseDeliveryApi": {
+ "longName": "use-delivery-api",
+ "shortName": "da"
+ },
+ "Docker": {
+ "longName": "add-docker",
+ "shortName": ""
+ },
"SkipRestore": {
"longName": "no-restore",
"shortName": ""
@@ -58,6 +71,18 @@
"longName": "PackageTestSiteName",
"shortName": "p",
"isHidden": true
+ },
+ "ModelsBuilderMode": {
+ "longName": "models-mode",
+ "shortName": "mm"
+ },
+ "StarterKit": {
+ "longName": "starter-kit",
+ "shortName": "sk"
+ },
+ "DevelopmentMode": {
+ "longName": "development-mode",
+ "shortName": "dm"
}
},
"usageExamples": [
diff --git a/templates/UmbracoProject/.template.config/ide.host.json b/templates/UmbracoProject/.template.config/ide.host.json
index 1a302779cc..90de3b977a 100644
--- a/templates/UmbracoProject/.template.config/ide.host.json
+++ b/templates/UmbracoProject/.template.config/ide.host.json
@@ -9,11 +9,22 @@
"symbolInfo": [
{
"id": "UmbracoVersion",
- "isVisible": true
+ "isVisible": false
},
{
"id": "UseHttpsRedirect",
"isVisible": true,
+ "persistenceScope": "templateGroup",
+ "defaultValue": "true"
+ },
+ {
+ "id": "UseDeliveryApi",
+ "isVisible": true,
+ "persistenceScope": "templateGroup"
+ },
+ {
+ "id": "ModelsBuilderMode",
+ "isVisible": true,
"persistenceScope": "templateGroup"
},
{
@@ -54,6 +65,23 @@
{
"id": "NoNodesViewPath",
"isVisible": true
+ },
+ {
+ "id": "Docker",
+ "isVisible": true
+ },
+ {
+ "id": "StarterKit",
+ "isVisible": true
+ },
+ {
+ "id": "UmbracoRelease",
+ "isVisible": true
+ },
+ {
+ "id": "DevelopmentMode",
+ "isVisible": true,
+ "defaultValue": "IDEDevelopment"
}
]
}
diff --git a/templates/UmbracoProject/.template.config/starterkits.template.json b/templates/UmbracoProject/.template.config/starterkits.template.json
new file mode 100644
index 0000000000..5d2a5dabf9
--- /dev/null
+++ b/templates/UmbracoProject/.template.config/starterkits.template.json
@@ -0,0 +1,47 @@
+{
+ "$schema": "https://json.schemastore.org/template.json",
+ "symbols": {
+ "StarterKit": {
+ "displayName": "Starter kit",
+ "type": "parameter",
+ "datatype": "choice",
+ "description": "Choose a starter kit to install.",
+ "defaultValue": "None",
+ "replaces": "STARTER_KIT_NAME",
+ // The choice here should be the name of the starter kit package, since it will be used directly for package reference.
+ "choices": [
+ {
+ "choice": "None",
+ "description": "No starter kit."
+ },
+ {
+ "choice": "Umbraco.TheStarterKit",
+ "description": "The Umbraco starter kit.",
+ "displayName": "The Starter Kit"
+ }
+ ]
+ },
+ // Used to determine the version of the starter kit to install.
+ // there should be cases for Latest, LTS and Custom for every starterkit added above.
+ // This has the benefit that all maintenance of starter kits in template can be done from this file.
+ "StarterKitVersion": {
+ "type": "generated",
+ "generator": "switch",
+ "replaces": "STARTER_KIT_VERSION",
+ "parameters": {
+ "evaluator": "C++",
+ "datatype": "string",
+ "cases": [
+ {
+ "condition": "(StarterKit == 'Umbraco.TheStarterKit' && (UmbracoRelease == 'Latest' || UmbracoRelease == 'Custom'))",
+ "value": "14.0.0"
+ },
+ {
+ "condition": "(StarterKit == 'Umbraco.TheStarterKit' && UmbracoRelease == 'LTS')",
+ "value": "13.0.0"
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/templates/UmbracoProject/.template.config/template.json b/templates/UmbracoProject/.template.config/template.json
index b17352476e..e342cdaeb8 100644
--- a/templates/UmbracoProject/.template.config/template.json
+++ b/templates/UmbracoProject/.template.config/template.json
@@ -18,6 +18,7 @@
"sourceName": "UmbracoProject",
"defaultName": "UmbracoProject1",
"preferNameDirectory": true,
+ "additionalConfigFiles": [ "starterkits.template.json"],
"sources": [
{
"modifiers": [
@@ -26,6 +27,13 @@
"exclude": [
".gitignore"
]
+ },
+ {
+ "condition": "(!Docker)",
+ "exclude": [
+ "Dockerfile",
+ ".dockerignore"
+ ]
}
]
}
@@ -46,13 +54,72 @@
"defaultValue": "net8.0",
"replaces": "net8.0"
},
+ "UmbracoRelease": {
+ "displayName": "Umbraco Version",
+ "description": "The Umbraco release to use, either latest or latest long term supported",
+ "type": "parameter",
+ "datatype": "choice",
+ "defaultValue": "Latest",
+ "choices": [
+ {
+ "choice": "Latest",
+ "description": "The latest umbraco release"
+ },
+ {
+ "choice": "LTS",
+ "description": "The most recent long term supported version",
+ "displayName": "Long Term Supported"
+ }
+ ],
+ "isRequired": false
+ },
"UmbracoVersion": {
- "displayName": "Umbraco version",
- "description": "The version of Umbraco.Cms to add as PackageReference.",
+ "displayName": "Custom Version",
+ "description": "The selected custom version of Umbraco, this is obsoleted, and will be removed in a future version of the template.",
"type": "parameter",
"datatype": "string",
- "defaultValue": "*",
- "replaces": "UMBRACO_VERSION_FROM_TEMPLATE"
+ "defaultValue": "null",
+ "replaces": "CUSTOM_VERSION",
+ "isRequired": false
+ },
+ "FinalVersion" : {
+ "type": "generated",
+ "generator": "switch",
+ "datatype": "text",
+ "description": "The calculated version of Umbraco to use",
+ "replaces": "UMBRACO_VERSION_FROM_TEMPLATE",
+ "parameters": {
+ "evaluator": "C++",
+ "datatype": "text",
+ "cases": [
+ {
+ "condition": "(UmbracoRelease == 'Latest')",
+ "value": "*"
+ },
+ {
+ "condition": "(UmbracoRelease == 'LTS')",
+ "value": "13.4.1"
+ }
+ ]
+ }
+ },
+ "DotnetVersion":
+ {
+ "type": "generated",
+ "generator": "switch",
+ "datatype": "text",
+ "description": "Not relevant at the moment, but if we need to change the dotnet version based on the Umbraco version, we can do it here",
+ "replaces": "DOTNET_VERSION_FROM_TEMPLATE",
+ "parameters": {
+ "evaluator": "C++",
+ "datatype": "text",
+ "cases": [
+ {
+ "condition": "(true)",
+ "value": "net8.0"
+ }
+ ]
+ }
},
"UseHttpsRedirect": {
"displayName": "Use HTTPS redirect",
@@ -61,6 +128,20 @@
"datatype": "bool",
"defaultValue": "false"
},
+ "UseDeliveryApi": {
+ "displayName": "Use Delivery API",
+ "description": "Enables the Delivery API",
+ "type": "parameter",
+ "datatype": "bool",
+ "defaultValue": "false"
+ },
+ "Docker": {
+ "displayName": "Add Docker file",
+ "description": "Adds a docker file to the project.",
+ "type": "parameter",
+ "datatype": "bool",
+ "defaultValue": "false"
+ },
"SkipRestore": {
"displayName": "Skip restore",
"description": "If specified, skips the automatic restore of the project on create.",
@@ -244,6 +325,58 @@
"defaultValue": "",
"replaces": "PACKAGE_PROJECT_NAME_FROM_TEMPLATE"
},
+ "DevelopmentMode": {
+ "type": "parameter",
+ "displayName": "Development mode",
+ "datatype": "choice",
+ "description": "Choose the development mode to use for the project.",
+ "defaultValue": "BackofficeDevelopment",
+ "choices": [
+ {
+ "choice": "BackofficeDevelopment",
+ "description": "Enables backoffice development, allowing you to develop from within the backoffice, this is the default behaviour.",
+ "displayName": "Backoffice Development"
+ },
+ {
+ "choice": "IDEDevelopment",
+ "description": "Configures appsettings.Development.json to Development runtime mode and SourceCodeAuto models builder mode, and configures appsettings.json to Production runtime mode, Nothing models builder mode, and enables UseHttps",
+ "displayName": "IDE Development"
+ }
+ ]
+ },
+ "ModelsBuilderMode": {
+ "type": "parameter",
+ "displayName": "Models builder mode",
+ "datatype": "choice",
+ "description": "Choose the models builder mode to use for the project. When development mode is set to IDEDevelopment this only changes the models builder mode appsetttings.development.json",
+ "defaultValue": "Default",
+ "replaces": "MODELS_MODE",
+ "choices": [
+ {
+ "choice": "Default",
+ "description": "Let DevelopmentMode determine the models builder mode."
+ },
+ {
+ "choice": "InMemoryAuto",
+ "description": "Generate models in memory, automatically updating when a content type change, this means no need for app rebuild, however models are only available in views.",
+ "displayName": "In Memory Auto"
+ },
+ {
+ "choice": "SourceCodeManual",
+ "description": "Generate models as source code, only updating when requested manually, this means a interaction and rebuild is required when content type(s) change, however models are available in code.",
+ "displayName": "Source Code Manual"
+ },
+ {
+ "choice": "SourceCodeAuto",
+ "description": "Generate models as source code, automatically updating when a content type change, this means a rebuild is required when content type(s) change, however models are available in code.",
+ "displayName": "Source Code Auto"
+ },
+ {
+ "choice": "Nothing",
+ "description": "No models are generated, this is recommended for production assuming generated models are used for development."
+ }
+ ]
+ },
"Namespace": {
"type": "derived",
"valueSource": "name",
diff --git a/templates/UmbracoProject/Dockerfile b/templates/UmbracoProject/Dockerfile
new file mode 100644
index 0000000000..e3eda648dd
--- /dev/null
+++ b/templates/UmbracoProject/Dockerfile
@@ -0,0 +1,33 @@
+FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
+USER $APP_UID
+WORKDIR /app
+EXPOSE 8080
+EXPOSE 8081
+
+FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
+ARG BUILD_CONFIGURATION=Release
+WORKDIR /src
+COPY ["UmbracoProject/UmbracoProject.csproj", "UmbracoProject/"]
+RUN dotnet restore "UmbracoProject/UmbracoProject.csproj"
+COPY . .
+WORKDIR "/src/UmbracoProject"
+RUN dotnet build "UmbracoProject.csproj" -c $BUILD_CONFIGURATION -o /app/build
+
+FROM build AS publish
+ARG BUILD_CONFIGURATION=Release
+RUN dotnet publish "UmbracoProject.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+# We need to make sure that the user running the app has write access to the umbraco folder, in order to write logs and other files.
+# Since these are volumes they are created as root by the docker daemon.
+USER root
+RUN mkdir umbraco
+RUN mkdir umbraco/Logs
+RUN chown $APP_UID umbraco --recursive
+#if (UmbracoRelease = 'LTS')
+RUN chown $APP_UID wwwroot/umbraco --recursive
+#endif
+USER $APP_UID
+ENTRYPOINT ["dotnet", "UmbracoProject.dll"]
diff --git a/templates/UmbracoProject/UmbracoProject.csproj b/templates/UmbracoProject/UmbracoProject.csproj
index ee8dd5e56e..019d5d2990 100644
--- a/templates/UmbracoProject/UmbracoProject.csproj
+++ b/templates/UmbracoProject/UmbracoProject.csproj
@@ -1,13 +1,20 @@
- net8.0
+ DOTNET_VERSION_FROM_TEMPLATE
enable
enable
Umbraco.Cms.Web.UI
+
+
+
+
@@ -21,11 +28,13 @@
true
+
false
false
+
diff --git a/templates/UmbracoProject/appsettings.Development.json b/templates/UmbracoProject/appsettings.Development.json
index 17b9f86361..0521b835ed 100644
--- a/templates/UmbracoProject/appsettings.Development.json
+++ b/templates/UmbracoProject/appsettings.Development.json
@@ -25,6 +25,11 @@
//#endif
"Umbraco": {
"CMS": {
+ //#if (UseHttpsRedirect || DevelopmentMode == "IDEDevelopment")
+ "Global": {
+ "UseHttps": false
+ },
+ //#endif
//#if (UsingUnattenedInstall)
"Unattended": {
"InstallUnattended": true,
@@ -36,12 +41,22 @@
"Content": {
"MacroErrors": "Throw"
},
+ //#if (DevelopmentMode == "IDEDevelopment")
+ "Runtime": {
+ "Mode": "Development"
+ },
+ //#if (ModelsBuilderMode == "Default")
+ "ModelsBuilder": {
+ "ModelsMode": "SourceCodeAuto"
+ },
+ ////#else
+ //"ModelsBuilder": {
+ // "ModelsMode": "MODELS_MODE"
+ //},
+ //#endif
+ //#endif
"Hosting": {
"Debug": true
- },
- "RuntimeMinification": {
- "UseInMemoryCache": true,
- "CacheBuster": "Timestamp"
}
}
}
diff --git a/templates/UmbracoProject/appsettings.json b/templates/UmbracoProject/appsettings.json
index 6678478951..23520bbe6b 100644
--- a/templates/UmbracoProject/appsettings.json
+++ b/templates/UmbracoProject/appsettings.json
@@ -20,7 +20,7 @@
"CMS": {
"Global": {
"Id": "TELEMETRYID_FROM_TEMPLATE",
- //#if (UseHttpsRedirect)
+ //#if (UseHttpsRedirect || DevelopmentMode == "IDEDevelopment")
"UseHttps": true,
//#endif
//#if (HasNoNodesViewPath)
@@ -37,6 +37,24 @@
"Unattended": {
"UpgradeUnattended": true
},
+ //#if (UseDeliveryApi)
+ "DeliveryApi": {
+ "Enabled": true
+ },
+ //#endif
+ //#if (ModelsBuilderMode != "Default" && DevelopmentMode == "BackOfficeDevelopment")
+ "ModelsBuilder": {
+ "ModelsMode": "MODELS_MODE"
+ },
+ //#endif
+ //#if (DevelopmentMode == "IDEDevelopment")
+ "Runtime": {
+ "Mode": "Production"
+ },
+ "ModelsBuilder": {
+ "ModelsMode": "Nothing"
+ },
+ //#endif
"Security": {
"AllowConcurrentLogins": false
}