Skip to main content

Changelog

All notable changes to this package are documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[0.8.1]​

Fixed​

  • status --cluster <name> no longer fails a cluster without services, such as an sst.aws.Cluster for task runners, which is how EcsEventRecorder says to check one. status --stage still fails a stage's cluster without services.
  • status --stage <stage> --cluster <name> failed with "No registered services match this cluster" when the cluster was given by name rather than ARN, or ran none of the stage's services, such as a cluster for task runners. It now matches names, and checks another cluster on its own, without the stage's URL.
  • The hint status prints when something needs attention names --cluster when that is what it checked, instead of --stage <stage>.
  • When status needs attention, the attention list always says why. A failed or unfinished rollout, a missing image, or a failing /up used to exit 1 with an empty list.
  • The note about a cluster without the ECS events log group names the log group and points a cluster LaravelService didn't create at EcsEventRecorder, instead of saying to deploy with ecsEvents.

[0.8.0]​

Removed​

  • The Composer package (kirschbaum-development/sst-laravel): SST Laravel is an npm package only. Its php artisan sst-laravel:* commands ran the npm CLI; use npx sst-laravel instead. Remove it from an app with composer remove kirschbaum-development/sst-laravel, and first remove LOG_STDERR_FORMATTER=Kirschbaum\SST\Logging\JsonFormatter from the environment if you set it yourself.
  • queue:status, and the job, schedule, and queue size events it read, which the Composer package logged. process_exit events stay.
  • doctor no longer checks for the Composer package.
  • The revision field of logs --json, and thrownAt of logs:errors, which came from the Composer package's formatter.

Changed​

  • The JSON logs always use Monolog's JSON formatter, which leaves the stack trace out. Apps that had the Composer package installed get a new task definition on the next deploy. logs:errors groups an exception by its class and the file that threw it.

[0.7.6]​

Added​

  • EcsEventRecorder records the ECS events of a cluster that LaravelService didn't create, such as an sst.aws.Cluster for task runners, the way ecsEvents does, so status --cluster <name> --since 24h reports its stopped tasks.

Changed​

  • logs:errors groups an exception by the first frame of the app's own code in its trace, with the package's formatter, instead of the file that threw it: the database errors of different queries no longer share one group of Connection.php. The file that threw it is in thrownAt. The package's formatter adds app_frame to context.exception.

Fixed​

  • queue:status exited 2 on every run: CloudWatch Logs Insights rejected three of its queries ("Cycle found in operation dependency graph"), as they named a result like the field they read (latest(size) as size).
  • status needed attention on every service with target tracking auto scaling: its AlarmLow alarm is in ALARM whenever the load is low. Alarms that only drive auto scaling are listed but never need attention.
  • logs:errors showed the class of an exception from a text log with doubled backslashes (Illuminate\\Database\\QueryException), in a group apart from the same exception in JSON logs.

[0.7.5]​

Made for agents and scripts that check a stage on a schedule. See Monitoring.

Added​

  • status --since 24h (or --start/--end) adds a read-only report of the window: deploys and whether they rolled back, every task that stopped with its stop reason and exit codes (task runners included), background processes that exited with an error, ECS service events, and the CloudWatch alarms on the cluster, its services, and load balancers (--alarm-prefix for more). --json prints one JSON document with an attention list.
  • logs:errors groups the Laravel and PHP errors of a window with CloudWatch Logs Insights, with counts and first and last seen.
  • queue:status reports failed jobs, queue sizes, the failed_jobs table, and when each scheduled task last ran and whether it failed, without a shell in a container. Without any of the package's events in the window it exits 2; pass --no-samples for an app without a scheduler.
  • logs --start and --end for exact windows, --json for JSON Lines with the service, ECS task, deploy (revision), and level of each line, and --limit, which says where to continue.
  • ecsEvents (on by default) records the cluster's ECS events, task stops with exit codes, deployments, and service actions, in /sst/cluster/<cluster>/sst-laravel/ecs-events for 30 days, through a small Lambda function and two EventBridge rules. It keeps only the fields status reads, never a task's overrides, which can hold secrets. ECS itself lists stopped tasks for about an hour.
  • config.logFormat (default json): SST Laravel sets LOG_STDERR_FORMATTER to a JSON formatter when the environment sets none, so each log entry and its stack trace is one CloudWatch event. Set text for Laravel's text lines.
  • The Composer package (composer require kirschbaum-development/sst-laravel) now ships a JSON log formatter with stack traces (lines stay under the 16 KB Fargate keeps in one log event) and the service, ECS task, and revision of each line, and, in the containers SST Laravel deploys, logs failed jobs and scheduled task runs and samples the queue sizes every minute from the scheduler. SST_LARAVEL_MONITORING, SST_LARAVEL_SAMPLE_QUEUES, and SST_LARAVEL_QUEUES configure it.
  • The web image raises PHP-FPM's log_limit from ServerSideUp's 8 KB to 64 KB, so a long log line from a request is no longer wrapped into several.
  • Background processes log a process_exit JSON line when they exit, also when s6 restarts them in place.
  • Each container gets SST_LARAVEL_SERVICE: web, reverb, or the worker name.

Changed​

  • logs reads the stage's log groups instead of looking them up through a running task, so it works when the app is crash-looping or scaled to zero, and it reads every service and the short-lived tasks in the cluster. Without a service argument it prints all of them. It no longer needs the AWS CLI.
  • logs follows new lines by default only in a terminal. Without one, it prints the window and exits.
  • ssh, command:run, logs, env:push, and env:pull never prompt without a terminal (or with CI set): a choice they can't make is an error that lists the options, or names the flag to pass (--stage, --force).
  • scheduler: true runs php artisan schedule:run at the start of every minute in a shell loop, instead of php artisan schedule:work, which writes the output and errors of the tasks together, so a line a task logged ended up after its "Running" line.
  • status, logs:errors, and queue:status exit 1 when something needs attention and 2 when they could not check (status used to exit 1 for both). Every command exits 2 for a usage error, such as an unknown option or a missing value.
  • status --stage without deployment outputs on the machine checks the stage's cluster, found by name, and says the expected revisions were not verified, instead of failing.
  • Progress and diagnostics of these commands, such as Auto-detected cluster, go to stderr, also through the php artisan sst-laravel:* commands.
  • The first deploy with this version gives every service a new task definition (SST_LARAVEL_SERVICE, and LOG_STDERR_FORMATTER unless the environment sets it). Log filters and metric filters that match Laravel's text lines need updating for JSON logs, or set config.logFormat: "text".

[0.7.4]​

Changed​

  • Enabling web.loadBalancer.accessLogs now disables nginx access logs by default, keeping request-log noise out of CloudWatch. Set web.accessLogs: true to keep both. An ALB access-log config with enabled: false leaves nginx access logs on by default; error logs and Laravel application logs are unaffected.
  • The environment is no longer stored in the container images. The deploy uploads the variables of config.environment.file or RemoteEnvVault, with the ones SST Laravel adds, to a private S3 bucket per component, and ECS sets them when a container starts. The bucket only lets the services' execution roles read the files, and refuses plain HTTP. Each change uploads a new file, so the services get a new task definition and a rollback gets its own environment; a replaced file is kept for 30 days. The container writes the variables to the app's .env when it starts, so artisan commands and code that reads the file work as before. Values that span lines go to a Secrets Manager secret, ${VAR} references are filled in the way Laravel fills them in, and variables the image sets (PHP_*, NGINX_*, AUTORUN_*, ...) are left out with a warning, as Laravel ignored them in the .env. No configuration change is needed. See How the containers get the variables.
  • Images built by earlier versions still contain the environment. Rotate the secrets that were in it, and delete those images from ECR when you no longer need to roll back to them.
  • Deploy roles of your own need to create, describe, and restore a Secrets Manager secret, create an S3 bucket and an IAM policy, and upload, tag, list, and delete files in the bucket. Execution roles that you bring with advanced.executionRole get a policy attached that lets them read the environment.

Added​

  • config.environment.kms encrypts the environment with a customer-managed KMS key that only the services can decrypt (about $1 a month).
  • config.environment.inImage copies the .env into the images as before, for now. It is deprecated and will be removed.

[0.7.3]​

Added​

  • config.phpExtensions installs additional PHP extensions in web, worker, and Reverb images while keeping the defaults. config.buildCommands runs custom shell commands as root during the image build, after extensions are installed and before application files are copied. Containers continue to run as www-data.

[0.7.2]​

Fixed​

  • Dockerfiles work with SST 4.17.1's docker-build 0.0.14 provider. Replace COPY --exclude with a read-only context mount that excludes .sst without copying it into any layer. No provider pin or changes to existing application provider configuration are needed.
  • Retain managed web, worker, and Reverb image resources by default, preventing old-resource deletion from removing a replacement's identical digest. Other resources keep their existing lifecycle. Image transforms and dependencies are preserved. Retention must be persisted before a separate replacement; retained manifests require deliberate ECR cleanup. See the upgrade sequence.
  • Verified deploys compare ECS to task definitions emitted by SST and check every referenced private ECR image. A healthy older revision after rollback, missing service, missing image, or zero-task service cannot pass.

Changed​

  • Breaking: Add deployment: app.deployment to sst.config.ts outputs when upgrading; the init template now includes it. deploy and status --stage require this metadata and do not scan unrelated services. Multiple components use an array. External task image checks are explicitly registered via taskDefinitions. Verification additionally needs ecs:DescribeTaskDefinition and ecr:DescribeImages. --no-wait still skips verification; standalone status --cluster reports diagnostic-only results.
  • Add actual provider Check RPC regression tests, local Pulumi engine replacement tests, and container source-exclusion tests. AWS/ECR integration remains mocked; test boundaries are documented in the deployment guide.

[0.7.1]​

Fixed​

  • Containers start on the current ServerSideUp images. On 2026-10-08 the serversideup/php tags for PHP 8.1 to 8.5 moved to ServerSideUp v5, which ships s6-overlay 3.2.3.2. The package registered the background processes in /etc/s6-overlay/s6-rc.d/user, which that s6-overlay treats as a deprecated layout: it then ignores the image's own nginx and php-fpm services and writes to /etc at boot, which fails as www-data (cannot create /etc/s6-overlay/s6-rc.d/user/type: Permission denied). Every web container failed to start, with or without background processes, and ECS rolled the deploy back. The processes are now registered in /etc/s6-overlay/user-bundles.d/user/contents.d, and each one depends on s6-overlay's base bundle, as s6-overlay recommends. The containers still run as www-data.
  • In workers, the container stops when Horizon or the scheduler exits, so ECS replaces the task, as documented. The finish scripts never ran as intended (execline ran them as one command from the service folder), so s6 restarted the process in place instead. The container now stops with the process's exit code. Custom tasks, Reverb, and the processes in the web container are still restarted in place.

Changed​

  • sst-laravel deploy waits until every service runs the revision it deployed and the health endpoint (--path, default /up) answers. It exits with an error when ECS rolls the deployment back, the deployment is stopped, the health endpoint returns an error, or the rollout doesn't finish within 30 minutes (--timeout). Before, it returned as soon as sst deploy did, so CI stayed green while ECS rolled a failed deploy back. --no-wait returns right after sst deploy. The check reads the ECS service deployments, so it needs ecs:ListServices, ecs:DescribeServices, ecs:ListServiceDeployments, and ecs:DescribeServiceRevisions.
  • status checks the last ECS deployment of each service instead of counting the running tasks, so it fails after a rollback even though the previous revision still answers on the URL. It checks the health endpoint once the rollout is done. Without --wait, a rollout in progress makes it exit with an error. --wait waits up to 30 minutes by default, instead of 10, because a rollout includes draining the old tasks.
  • status and deploy use the region of the aws provider in sst.config.ts when it sets one.
  • The workflow github-iam prints deploys with npx sst-laravel deploy, so the job fails on a rollback.
  • PHP 7.4 and 8.0 are no longer supported: config.php fails with a clear error, and init doesn't offer them. ServerSideUp v5 has no images for them, and their last images run an s6-overlay that doesn't read user-bundles.d.
  • The worker image installs s6-overlay 3.2.3.2 instead of 3.2.0.2, the same version as the web image, so both read the background processes from the same place.
  • The web image build fails with a message when Docker uses a base image older than ServerSideUp v5, such as a copy of the tag downloaded before the change, instead of building an image that silently skips the background processes. Run docker pull serversideup/php:<version>-fpm-nginx to fix it.
  • Background process dependencies are written as dependencies.d entries and checked before anything is built: a task can depend on the other tasks of its container, base, and in the web container nginx and php-fpm. Before, a typo only showed when the container failed to start. Task names that s6-overlay uses (user2, base, top, fix-attrs, legacy-cont-init, legacy-services, and names starting with s6rc-) are rejected, as user, nginx, and php-fpm were.
  • Worker images no longer include the Horizon and scheduler s6 services when the worker doesn't run them.

[0.7.0]​

Added​

  • nodes on LaravelService: the ECS cluster and the sst.aws.Service of web, Reverb, and each worker (by worker name), to add alarms, permissions, or outputs of your own.
  • php artisan sst-laravel:status, sst-laravel:doctor, sst-laravel:guide, and sst-laravel:skill:install, so every CLI command has an Artisan command.

Changed​

  • The cluster and the services are created under the LaravelService component, so resource options passed to it (provider, protect, dependsOn) apply to them too. Aliases move the existing resources on the next deploy instead of replacing them.
  • The env file from config.environment.file is written by a resource the images wait for, the same one RemoteEnvVault uses, instead of while the config runs. The variables SST Laravel adds are quoted, so values with $, #, or spaces work, and APP_URL is added when web.domain is an object too. The file is readable by its owner only.
  • A missing config.environment.file prints a warning instead of deploying an empty env file silently.
  • Each LaravelService has its own build folder, .sst/laravel/<name>, so two components in one app no longer overwrite each other's env file and background processes. The images are rebuilt once on the next deploy.
  • The images get the app without the .sst folder. They carried the files the component generates there, including a second copy of the env file, and in an app with several components the other components' env files. The Dockerfiles declare # syntax=docker/dockerfile:1 for COPY --exclude, so the first build fetches that Dockerfile syntax from Docker Hub.
  • Worker images copy their background processes last, so the layers before them (system packages, PHP extensions) are the same for every worker and come from the build cache.
  • ssh, logs, command:run, and status find the cluster by its exact name, including the app name, and the tasks by their ECS service. A stage named dev could match development before, and two apps with the same component name could match each other's cluster. status lists the services by their names.
  • Two workers with the same name fail with a clear message.
  • The CLI reads the app name from what the app() function of sst.config.ts returns, ignoring comments. It took the first name: in the file, which could be a worker's or a commented-out one, and env:push and env:pull then used the wrong secret path.

Fixed​

  • transform and forceUpgrade on LaravelService reach the ECS cluster, as on SST's Cluster component. They were accepted but ignored.

[0.6.2]​

Added​

  • status checks the app URL that the last sst-laravel deploy of the stage saved when --url isn't given, so npx sst-laravel status --stage dev --wait is enough after a deploy. deploy takes the URL from the url output of sst.config.ts (the config from init returns it), or from the load balancer address when the outputs have only one, and keeps it in .sst/laravel/urls.json.

Changed​

  • The onboarding prompt fetches docs/agent-setup.md from the latest npm release through jsDelivr instead of from the main branch, so agents no longer get instructions for commands that aren't released yet. The publish workflow clears the jsDelivr cache after each release.
  • docs/agent-setup.md has the agent run npx sst-laravel guide and follow it, instead of loading the skill it just installed, which most agents only see after a restart. The skill is installed for later sessions. The rules and the report that repeated the skill are gone; the skill's report now also lists the skill files, the .dockerignore, and what was checked when a blocker remains.
  • The agent asks where the environment variables should live, and explains the options, instead of always using an env file: an env file on this machine, or RemoteEnvVault in AWS Secrets Manager, plus SST secrets and config.environment.vars. It recommends RemoteEnvVault for teams and CI, keeps a setup the project already has, and never asks for secret values in the chat. docs/environment-variables.md has a new "Which one to use" section.
  • The agent helps users without AWS access set it up: IAM Identity Center with aws configure sso, the region, and the permissions the first deploy needs. The plan shows the AWS account and identity in use. doctor suggests aws configure sso when there is no login, and docs/getting-started.md has a new AWS access section.

[0.6.1]​

Fixed​

  • Linking an sst.aws.Mysql or sst.aws.Aurora database injects the DB_* variables, as documented. Only sst.aws.Postgres did before.
  • env:pull writes values the way the deploy does, and env:push reads quoted values the way Laravel does (escapes, multi-line values, comments after the closing quote, export). Before, every pull and push added a backslash to values containing ".
  • env:push and env:pull use the path of the RemoteEnvVault in sst.config.ts, filling in $app.name and $app.stage. They used the default path even when the vault set another one. The new --path option sets it when it can't be read from the config.
  • config.opcache takes effect. The Dockerfiles ignored it: web containers always had OPcache on and workers always off. OPcache is now on in every container unless config.opcache is false. Unused build args are no longer passed.
  • Worker and Reverb images build when the project's .dockerignore excludes node_modules, as the one the first deploy writes does. The image copied its s6 config from the package in node_modules; it is now copied into .sst/laravel first.
  • config.environment.vars can be an Output. Before, the Reverb variables and NGINX_ACCESS_LOG were dropped when it was.
  • The RemoteEnvFile resource is created under the LaravelService component, as intended, so resource options on the component apply to it. An alias moves the existing one instead of replacing it.

[0.6.0]​

Added​

  • size option (small | medium | large) on web, workers[], and reverb mapping to valid Fargate cpu/memory pairs. Explicit cpu/memory still win over size.
  • advanced block on web, workers[], and reverb as the escape hatch for SST experts (architecture, storage, logging, health, executionRole, loadBalancer, transform).
  • envFrom as the preferred name for the per-link environment callback (environment still works).
  • sst-laravel doctor command: one readiness check for tools, a reachable Docker daemon, AWS login (with the profile in use) and region, the installed dependencies and built assets, sst.config.ts (app name, PHP version), the stage env file (--stage, default dev) and its drivers, trusted proxies, and git-ignored secrets. It asks git check-ignore about each real env file instead of pattern-matching .gitignore, which passed .env.production for .env.dev. Warnings (warn) don't block; FIX items do.
  • sst-laravel status command: running tasks plus an optional /up health check in one non-interactive summary. --wait keeps checking while the tasks start, since the deploy returns before they pass the health check. It points out that the load balancer address serves http only.
  • sst-laravel logs: --no-follow prints the recent logs and exits, --filter narrows them with a CloudWatch filter pattern, and the output has no color codes.
  • sst-laravel deploy prints the status --wait command when it finishes, and a note when the app runs on the http-only load balancer address.
  • sst-laravel skill:install command: installs or updates the agent skill from the installed package, so it matches the version in use. With Laravel Boost 2.0+ set up, it adds the skill to .ai/skills and runs boost:update; otherwise it copies it to .agents/skills and the folder of each agent set up in the project.
  • The first deploy writes a .dockerignore when the project has none, so the image skips .git, node_modules, every .env* file, local SQLite databases, uploads, logs, and tests. An existing file only gets the .sst lines, as before (and no longer grows a blank line on every deploy).
  • sst-laravel guide command: prints the agent deploy guide (the skill), or the short config reference with --reference.
  • docs/llms.txt: short agent quick reference (minimal config, common recipes, failure checklist).
  • docs/why-sst-laravel.md: what SST is, and what the setup gives you (infrastructure as code, auto-scaling, linked AWS resources, security without long-lived AWS keys).
  • docs/agent-setup.md: setup instructions for agents to fetch. They install the package, install or update the skill with skill:install, and follow it.
  • loadBalancer options on web, reverb, and workers with a load balancer, so hardening it no longer needs hand-written transform callbacks (#7). Documented in docs/load-balancer.md:
    • loadBalancer.sslPolicy sets the SSL security policy on the HTTPS/TLS listeners only. HTTP listeners, which reject an SSL policy, are left untouched.
    • loadBalancer.ingressCidrs only accepts traffic to the load balancer from the given IPv4/IPv6 ranges, with one security group rule per listener port. It takes a plain list or { v4, v6, ports }.
    • loadBalancer.accessLogs ships the load balancer access logs to S3. The package creates the bucket (private, HTTPS only, delivery limited to the load balancers of the account and region, logs kept 90 days unless retentionDays says otherwise), or delivers to a bucket you own.
  • advanced.transform entries for the load balancer, its listeners, and its security group now run after the defaults and options above, so they compose instead of one replacing the other.

Changed​

  • Breaking: loadBalancer on web, workers[], and reverb no longer takes the SST load balancer config (rules, ports, domain, health, ...). It now holds the load balancer options (see Added). Move the SST config to advanced.loadBalancer. Any key loadBalancer does not know fails the deploy before anything is created.
  • Load balancers are now hardened by default. On the next deploy, existing load balancers are updated in place:
    • HTTPS listeners use ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09, the policy AWS recommends, instead of ELBSecurityPolicy-2016-08. Clients that only speak TLS 1.0 or 1.1 can no longer connect. Set loadBalancer.sslPolicy to pick another policy.
    • The security group only opens the ports the load balancer listens on, instead of every port and protocol. New connections can fail for a moment while the rules are replaced.
    • Application load balancers drop HTTP headers with an invalid name (anything other than letters, digits, and hyphens). Set dropInvalidHeaderFields to false in advanced.transform.loadBalancer to keep them.
  • init now generates a minimal config (web only, env file, no domain/database/workers) with cheapest-VPC guidance. The default VPC has no NAT ($0.50/month); nat: "ec2" ($13/month) is documented for keeping containers in private subnets.
  • init names the app after the composer project or the folder instead of APP_NAME, which turned every fresh app into laravel, and warns when the name is still generic: SST keys its state by app name and stage, so two projects with the same name in one AWS account overwrite each other. It sets config.php to the local PHP version, because the image copies the local vendor/ folder, and adds .sst to .gitignore.
  • status, logs, ssh, command:run, and github-iam take the region from the active AWS profile when AWS_REGION is not set, instead of falling back to us-east-1.
  • SST passthroughs (architecture, storage, logging, health, executionRole, loadBalancer, transform) moved behind advanced. The old top-level keys still work but log a deprecation warning; advanced wins when both are set. The exception is loadBalancer, which has no top-level alias (see above).
  • Per-service permissions now override the top-level permissions instead of being silently dropped.
  • The README agent prompt is now one line that points the agent to docs/agent-setup.md. The skill (SKILL.md) uses plain words with doctor/status wired into every phase.
  • Before writing any config, the agent now shows a plan and waits for a yes: a few bullets on why SST Laravel, what it found in the app, questions only the user can answer (a database, background work, a domain), what will be created with the monthly cost, how the deploy works, and how to remove it. It no longer leaves out a database silently when the app uses one.
  • init installs @kirschbaum-development/sst-laravel in the project when it is missing, since sst.config.ts imports it.
  • doctor checks that the package is installed in the project.
  • init installs the skill the same way as skill:install. It only uses Laravel Boost when boost.json lists agents (boost:update fails otherwise).
  • Documentation moved from the README into topic pages in docs/ (getting started, web, workers, Reverb, environment variables, linking resources, deploying, CLI, troubleshooting), published at docs.kirschbaumdevelopment.com. The README is now a short overview. The CLI reference now also covers command:run, install, and github-iam.

Fixed​

  • Containers in an sst.aws.Vpc without NAT now run in the public subnets with a public IP, like SST's default. They were placed in private subnets with no route to the internet, so they could not pull their image and never started. VPCs with NAT keep their containers in private subnets.
  • app.url and app.reverbUrl return undefined instead of throwing when the web/reverb service is not configured.
  • config.php type corrected from Input<Number> to Input<number>.
  • Aurora database detection no longer reads the async port into a sync variable (always undefined); it uses the engine name when available and an async port check otherwise.
  • Updating .dockerignore for the Docker build is now reported via the component messages.
  • Corrected sst deploy to sst-laravel deploy in RemoteEnvVault docs and the init success message.

[0.5.2]​

Added​

  • Automatic Laravel database environment variables and TLS certificate verification for PlanetScale MySQL (Vitess) and Postgres credentials in an sst.Linkable with provider: 'planetscale'.

[0.5.0]​

Changed​

  • Breaking: Require SST ^4.17.1. New projects created with sst-laravel init install the same supported version range.

[0.3.9]​

Added​

  • web.horizon, web.scheduler, and web.tasks options to run supervised background processes (Horizon, the Laravel scheduler, or custom commands) inside the web container via s6-overlay, without a dedicated worker service. Unlike workers, a crashed process is restarted in place so HTTP traffic is never interrupted.

Fixed​

  • Stale s6 task definitions are now removed from the build directory before regeneration, so disabling horizon/scheduler or renaming a task no longer leaves the old process running (applies to web, workers, and Reverb).
  • Task names are now validated (single safe path segment, not one of the reserved s6 service names user/nginx/php-fpm) and worker names must be a single path segment, preventing generated files from escaping the build directory and from overwriting the stock s6 services in the container image.

[0.3.8]​

Fixed​

  • Forward the cpu, memory, storage, architecture, logging, health, and executionRole service arguments to the underlying sst.aws.Service. These were declared on web, workers[], and reverb but never relayed, so setting them (e.g. cpu/memory) was silently a no-op and services ran on SST's defaults (0.25 vCPU / 0.5 GB) regardless of config.

[0.3.7]​

Changed​

  • Enable additional PHP extensions on the worker Docker image.

[0.3.6]​

Added​

  • web.accessLogs option to silence the web container's nginx access logs (including ALB health-check pings) by pointing NGINX_ACCESS_LOG at /dev/null, while leaving error and application logs intact.

[0.3.5]​

Changed​

  • Redirect HTTP (port 80) traffic to HTTPS by default when a web.domain is configured. Set web.httpsRedirect: false to keep forwarding HTTP straight to the app.

[0.3.4]​

Added​

  • web.healthCheck shortcut for configuring the load balancer health check on the default forward port without specifying the per-port key.

[0.3.3]​

Added​

  • Laravel Reverb service support.
  • Command runner.