From cc27105d513798a19c956fbf6a222cfec64da7a3 Mon Sep 17 00:00:00 2001 From: Levi Zitting Date: Thu, 1 Oct 2026 00:00:10 -0500 Subject: [PATCH] feat: use S3 media storage and SeaweedFS for local development --- README.md | 12 ++++++++-- docker-compose.yml | 22 ++++++++++++++++++- src/MethodConf.Cms/MethodConf.Cms.csproj | 2 ++ .../Properties/launchSettings.json | 10 +++++++-- .../appsettings.Development.json | 11 ++++++++++ src/MethodConf.Cms/appsettings.json | 16 ++++++++++++++ 6 files changed, 68 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 813de70..de258b8 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,20 @@ The Umbraco CMS and public API for [MethodConf](https://www.methodconf.com/). ## Local Development 1. Copy `.env.example` to `.env` and configure the required values. -2. Run the application: +2. Start local S3 media storage: ```bash -dotnet run --project src/MethodConf.Cms/MethodConf.Cms.csproj +docker compose up -d seaweedfs ``` +3. Run the application: + +```bash +dotnet run --project src/MethodConf.Cms/MethodConf.Cms.csproj --launch-profile Umbraco.Web.UI +``` + +Local media uses SeaweedFS at `http://localhost:8334` with disposable development credentials. + The production image can be built locally with: ```bash diff --git a/docker-compose.yml b/docker-compose.yml index 2745e14..5536d8c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,15 @@ services: + seaweedfs: + image: chrislusf/seaweedfs:4.48@sha256:4e61d15fd35994cb1e43e1e553dff106794841fd9a99ade2fc8c8bfce4d7872d + command: [mini, -dir=/data] + environment: + AWS_ACCESS_KEY_ID: methodconf-local + AWS_SECRET_ACCESS_KEY: methodconf-local-password + S3_BUCKET: methodconf-local + ports: + - '127.0.0.1:8334:8333' + volumes: + - 'seaweedfs-data:/data' backend: build: context: ./ @@ -7,9 +18,17 @@ services: - '${APP_PORT:-8080}:8080' env_file: - .env + environment: + AWS_ACCESS_KEY_ID: methodconf-local + AWS_SECRET_ACCESS_KEY: methodconf-local-password + AWS_SESSION_TOKEN: "" + AWS__ServiceURL: http://seaweedfs:8333 + AWS__ForcePathStyle: "true" + Umbraco__Storage__AWSS3__Media__BucketName: methodconf-local + depends_on: + - seaweedfs volumes: - './src/MethodConf.Cms/umbraco/Data/Umbraco.sqlite.db:/app/umbraco/Data/Umbraco.sqlite.db' - - './src/MethodConf.Cms/wwwroot/media:/app/wwwroot/media' - 'cache:/app/umbraco/Data/TEMP' - 'data-protection-keys:/home/app/.aspnet/DataProtection-Keys' restart: unless-stopped @@ -37,5 +56,6 @@ services: profiles: [ local-email ] volumes: + seaweedfs-data: cache: data-protection-keys: diff --git a/src/MethodConf.Cms/MethodConf.Cms.csproj b/src/MethodConf.Cms/MethodConf.Cms.csproj index 436ad18..7f58aae 100644 --- a/src/MethodConf.Cms/MethodConf.Cms.csproj +++ b/src/MethodConf.Cms/MethodConf.Cms.csproj @@ -10,6 +10,8 @@ + + diff --git a/src/MethodConf.Cms/Properties/launchSettings.json b/src/MethodConf.Cms/Properties/launchSettings.json index 69ee2ad..e82ee30 100644 --- a/src/MethodConf.Cms/Properties/launchSettings.json +++ b/src/MethodConf.Cms/Properties/launchSettings.json @@ -13,7 +13,10 @@ "commandName": "IISExpress", "launchBrowser": true, "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Development", + "AWS_ACCESS_KEY_ID": "methodconf-local", + "AWS_SECRET_ACCESS_KEY": "methodconf-local-password", + "AWS_SESSION_TOKEN": "" } }, "Umbraco.Web.UI": { @@ -22,7 +25,10 @@ "launchBrowser": true, "applicationUrl": "https://localhost:44350;http://localhost:7158", "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" + "ASPNETCORE_ENVIRONMENT": "Development", + "AWS_ACCESS_KEY_ID": "methodconf-local", + "AWS_SECRET_ACCESS_KEY": "methodconf-local-password", + "AWS_SESSION_TOKEN": "" } } } diff --git a/src/MethodConf.Cms/appsettings.Development.json b/src/MethodConf.Cms/appsettings.Development.json index 8f59fff..1dd0229 100644 --- a/src/MethodConf.Cms/appsettings.Development.json +++ b/src/MethodConf.Cms/appsettings.Development.json @@ -1,5 +1,9 @@ { "$schema": "appsettings-schema.json", + "AWS": { + "ServiceURL": "http://localhost:8334", + "ForcePathStyle": true + }, "Serilog": { "MinimumLevel": { "Default": "Information" @@ -14,6 +18,13 @@ ] }, "Umbraco": { + "Storage": { + "AWSS3": { + "Media": { + "BucketName": "methodconf-local" + } + } + }, "CMS": { "Content": { "MacroErrors": "Throw" diff --git a/src/MethodConf.Cms/appsettings.json b/src/MethodConf.Cms/appsettings.json index 3ac7567..ebbd2ec 100644 --- a/src/MethodConf.Cms/appsettings.json +++ b/src/MethodConf.Cms/appsettings.json @@ -14,7 +14,23 @@ "umbracoDbDSN": "", "umbracoDbDSN_ProviderName": "Microsoft.Data.Sqlite" }, + "AWS": { + "Region": "us-east-2" + }, "Umbraco": { + "Storage": { + "AWSS3": { + "Media": { + "BucketName": "", + "Region": "us-east-2", + "MediaBucketPrefix": "media", + "CacheBucketPrefix": "cache", + "CacheRetention": { + "Enabled": false + } + } + } + }, "CMS": { "Global": { "Id": "1569bc40-73b7-4d61-943f-0ee19fd6c39c"