feat(scaleway): add Scaleway provider with containers, postgres, and redis - #234
Conversation
lionello
left a comment
There was a problem hiding this comment.
Looks good so far, although I would have done the resources in this order:
- Service - test with known image
- Build - test with sources
- Redis - standalone test
- Postgres - standalone test
- Project - Compose integration
| - "provider/**" | ||
| - "sdk/v2/**" | ||
| - "tests/**" | ||
| - "examples/**" |
There was a problem hiding this comment.
Perhaps we only need to watch the yaml examples, since most others are generated from those.
…d postgres panic - Add containerPrivacy() to set containers as private when no ingress ports - Prefix public endpoints with https://, keep raw domain for private - Fix nil pointer panic when postgres version is unspecified - Add multi-service project test (public web + private worker + postgres) - Add private service unit tests - Update example to demonstrate all three deployment types - Add iteration notes documenting progress and known limitations Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous fallback loop was redundant since all ports with mode "" default to ingress. Simplified to a single loop returning the first target port. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ress-only limitation Scaleway Serverless Container private networks are egress-only: containers can reach databases/Redis on the PN but cannot receive inbound traffic from other containers. Key changes: - Set ActivateVpcIntegration=true on namespace creation (required at creation time, cannot be changed later) - All container endpoints use public https:// URLs since inter-service communication must go through public endpoints - Document the egress-only limitation and its implications in iteration notes Source: Scaleway docs containers-private-networks reference Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
Scaleway live-validation update pushed in What changed in the PR:
Live validation performed:
Verification after docs/demo update:
|
|
Additional networking clarification pushed in Important distinction from the live E2E demo:
I updated the docs so reviewers don't read the demo as proof that |
|
Corrected hostname validation summary (the prior comment was mangled by shell backtick substitution). Validated the Scaleway DB hostname behavior live and pushed the docs update in f001940. Results:
Docs updated to make the implication explicit: Scaleway supports private DB access, but not literal Docker Compose service-name DNS for managed DBs. The provider should preserve Defang's local/cloud connection-string experience by injecting or rewriting the cloud connection string to the provider-generated private DB endpoint ( |
|
Added a follow-up docs clarification in
This is now documented in both the iteration notes and the E2E demo README. |
Scaleway no longer offers Redis 6.2.7 or 7.2.5. As of 2026-05, the only available version is 8.4.0. Simplify redisVersionFromImage to always return "8.4.0" and update tests accordingly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Scaleway Serverless Containers require a listening HTTP port. Background workers (queue consumers, cron jobs) that don't expose ports fail with "Container is unable to start OR is not listening on port 8080". This adds an automatic health shim: when a service has no ports but has a command defined, the provider wraps the command with a shell script that starts a tiny HTTP responder on $PORT in the background, then execs the original command. The responder tries node, python3, python, and nc in order, using whichever runtime is available in the container image. Validated end-to-end on Scaleway with the mastra-extended sample: the worker container (npm run worker) now starts successfully and processes BullMQ jobs through the Redis queue. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Scaleway Serverless Containers only wake scaled-to-zero instances on inbound HTTP requests. Background workers (queue consumers, cron jobs) that poll Redis/databases internally never receive HTTP traffic, so they stay at zero instances permanently after scaling down. Force min_scale=1 for services that need the health shim (no ports), ensuring they always have at least one running instance. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ation Document the health shim approach for portless background workers, Redis 8.4.0 update, and full end-to-end mastra-extended deployment results including LLM chat and embedding validation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Document the discovery that Scaleway only wakes scaled-to-zero containers on HTTP requests, making min_scale=1 mandatory for background workers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Build-from-source is implemented via Kaniko in Scaleway Serverless Jobs. Multiple docs still claimed it was unsupported. Also updated LLM references to reflect the direct Generative API approach (no LiteLLM sidecar), and checked implementation plan checklist items that are now complete. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Delete docs/scaleway-implementation-plan.md, docs/scaleway-iteration-notes.md, docs/scaleway-pr234-review.md, and examples/scaleway-e2e-demo/ directory. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change 2.0.0-beta.5+dirty to 2.0.0-beta.5 in all example dependency files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add WARNING comment block to build.go explaining that Scaleway Serverless Jobs API does not support secret injection, so credentials are passed as plain-text environment variables. - Replace 0.0.0.0/0 Redis ACL fallback with an error requiring a private network for security. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Update: re-runs the Kaniko build when inputs change, returns previous BuildId during preview. - Delete: no-op since job definitions are cleaned up immediately after each build run. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously only the first page (100 secrets) was fetched. Now iterates through all pages until fewer than page_size results are returned. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The password-shaped placeholder "DryRun1!-%s" is now only used for Scaleway (which validates password complexity during preview). Other providers use the simpler "dry-run-%s" default. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Debug-level logging produces excessive output in production builds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
TestConstructScalewayProjectRejectsBuildOnlyService asserted that build-only services should fail, but the implementation now supports them via the Build resource (tested in project_test.go). Remove the outdated test. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The test now verifies that CreateRedis returns an error when no private network is configured, matching the new security behavior. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>


Summary
Adds the Scaleway Pulumi provider used by the Defang Scaleway BYOC CLI path. It maps Defang Compose projects to Scaleway Serverless Containers, Managed PostgreSQL, Managed Redis, private networking, Kaniko build jobs, and CD state artifacts.
Related CLI PR: DefangLabs/defang#2105.
Implemented
v1alpha2.min_scale=1for those workers.defang-scalewayprovider plugin.project.pbupload to Scaleway Object Storage after successful deployment so CLIcompose ps/services readback works, matching AWS/GCP/Azure behavior.Scaleway platform quirks
/bin/shand one ofnode,python3,python, ornc; a TODO in code documents better future runtime paths.min_scale=1because scaled-to-zero workers cannot wake without inbound HTTP traffic.8.4.0because that is the available Scaleway version in current testing.CD image notes
Pulumi's
plugin install -frejects prerelease provider versions such as2.0.0-beta.5, while the CD program needs that exact version. The Scaleway CD image therefore installs the local provider binary into Pulumi's plugin cache layout manually and the CLI setsPULUMI_HOME=/root/.pulumifor the CD job.Validated test image:
rg.fr-par.scw.cloud/defang-cd/cd:sam-20260511d, digestsha256:f515f0387b57b001b5b91e08d4fbf854fac7847327efa6d9f08913c35b5f14aa.Live validation
Validated on 2026-05-11 with the paired CLI draft branch:
Small app:
compose upcompleted for a Python ingress service with a Composemodels:entry./llmroute successfully called Scaleway Generative API using CLI-created LLM auth config.project.pbupload restoredcompose ps; CLI reportedDEPLOYMENT_COMPLETEDandhealthy.compose downremoved the live Serverless Container and namespace.Mastra Extended:
projects/samples/samples/mastra-extendedsample on Scaleway stackmastraextended.Generate sample items, verified 10 tasks, 10 events, and 20 classified items, waited 15 seconds, then asked the chat UI what to look at first.1 passed.compose downremoved the sample's Serverless Containers, namespace, managed Postgres, and managed Redis; native API checks confirmed cleanup.Test plan
go1.25.9 test ./provider/defangscaleway/...go1.25.9 test ./...fromcd/mastra-extendedUIKnown limitations
HTTP 403; native Scaleway domains worked.compose logsno longer fails on Cockpit endpoint/auth, but product log coverage/labels still need broader workload validation.mastra-extendedexposed two config polish issues:defang config set --randomcan generate a value that fails Scaleway Postgres password policy, and Scaleway Redis currently requiresREDIS_PASSWORDeven when the sample README does not mention it.