Files
Classic298 9428c871e1 Sticky sessions are optional, worth a try for delivery oddities
Sticky sessions are not needed with WebSockets on, but they are worth trying if streamed responses or tool calls arrive in the browser unreliably. They stay required when WebSockets are turned off. The deployment guides now link to one explanation instead of repeating it.
2026-11-03 18:02:51 +01:00

12 KiB

slug, sidebar_position, title, description
slug sidebar_position title description
/deployment/aws-ecs 2 AWS ECS / Fargate Deploy Open WebUI on AWS ECS with Fargate, shared data services, Secrets Manager, and an Application Load Balancer.

Open WebUI on AWS ECS / Fargate

Run Open WebUI as an ECS service on Fargate. This guide assumes you already manage an AWS account and VPC; it walks through the application settings and deployment sequence using the ECS console, with CLI commands for verification.

For an overview of the architecture, see the existing Container Service guide. For EKS or another Kubernetes cluster, use Kubernetes Deployment.

1. Prepare the AWS Services

Component Prepare before creating the service
Container image Mirror ghcr.io/open-webui/open-webui:v0.13.0-slim into ECR and use its immutable digest. Slim supports every service in this guide and leaves out the local machine-learning stack; see slim. Match the image architecture to the Fargate task.
ECS and networking An ECS cluster, private subnets, and security groups. Allow image pulls, secret retrieval, log delivery, model APIs, and the backing-service connections. Use NAT or appropriate VPC endpoints for these paths.
Database RDS PostgreSQL or Aurora PostgreSQL, an application database and role, and the vector extension enabled by a database administrator.
Redis An ElastiCache Redis-compatible endpoint or another Redis service. Match Open WebUI's Redis mode and TLS settings to the actual service.
Files An S3 bucket for application uploads.
Models and extraction Reachable chat and embedding APIs plus a private Tika service. Model inference is separate from the ECS application task.
HTTPS An Application Load Balancer, HTTPS listener and certificate, DNS hostname, and an IP-type target group forwarding to port 8080.

Use task security groups to allow inbound 8080 only from the load balancer. Choose internal or internet-facing load balancing according to your organization's access requirements. Fargate's awsvpc networking requires IP targets; see ECS with an Application Load Balancer.

Create separate IAM roles for the task's application access and ECS execution. The execution role needs image-pull, CloudWatch Logs, and secret-retrieval permissions, including KMS decryption where required. The task role needs the required S3 bucket/object permissions. Use task-role credentials for S3 instead of embedding AWS access keys in the task definition. See the ECS task execution role for execution-side permissions.

2. Create the Application Task Definition

In the ECS console, create a Linux Fargate task definition named openwebui:

Setting Starting value
Network mode awsvpc
Task resources 1 vCPU and 4 GiB memory; tune after measuring workload.
Container name openwebui
Image Your pinned ECR image digest.
Container port 8080/TCP
Persistent filesystem None; use the external database and S3.
Logs awslogs, with an existing CloudWatch log group and stream prefix.
Application command Keep the image's normal entry point and command.

Set these non-secret environment values, replacing the example endpoints and bucket:

WEBUI_URL=https://ai.example.com
UVICORN_WORKERS=1
ENABLE_DB_MIGRATIONS=false
ENABLE_OLLAMA_API=false
WEBSOCKET_MANAGER=redis
VECTOR_DB=pgvector
PGVECTOR_CREATE_EXTENSION=false
OPENAI_API_BASE_URL=https://models.example.com/v1
RAG_EMBEDDING_ENGINE=openai
RAG_EMBEDDING_MODEL=REPLACE_WITH_EMBEDDING_MODEL_ID
RAG_OPENAI_API_BASE_URL=https://embeddings.example.com/v1
CONTENT_EXTRACTION_ENGINE=tika
TIKA_SERVER_URL=http://REPLACE_WITH_PRIVATE_TIKA_ENDPOINT:9998
STORAGE_PROVIDER=s3
S3_BUCKET_NAME=REPLACE_WITH_BUCKET
S3_REGION_NAME=REPLACE_WITH_AWS_REGION

Create the credentials in Secrets Manager and map them into the container's Secrets settings:

Environment variable Secret value
WEBUI_SECRET_KEY A stable random signing key, identical on every instance. Generate once with openssl rand -hex 32.
DATABASE_URL The PostgreSQL connection URL, with your provider's required TLS parameters. PGVector uses it too unless you set PGVECTOR_DB_URL.
REDIS_URL The Redis connection URL, including authentication and TLS where configured. WebSockets use it too unless you set WEBSOCKET_REDIS_URL.
OPENAI_API_KEY Chat provider API key.
RAG_OPENAI_API_KEY Embedding provider API key. Defaults to OPENAI_API_KEY when unset.
WEBUI_ADMIN_EMAIL and WEBUI_ADMIN_PASSWORD Initial administrator credentials for an empty database. Keep the password in the secret store.
LICENSE_KEY Optional issued Enterprise license key.

The environment variable name and secret ARN are separate fields. For example, this is a fragment of a task definition's container configuration:

{
  "secrets": [
    {
      "name": "DATABASE_URL",
      "valueFrom": "arn:aws:secretsmanager:REGION:ACCOUNT_ID:secret:openwebui-database-SUFFIX"
    }
  ]
}

Repeat for every secret variable; two variables may reference the same secret. Environment-injected secrets are read when the task starts, so rotation requires replacement tasks. See ECS secret injection.

Do not store SQLite or local vector data on the task's ephemeral disk. Switching a populated installation to PostgreSQL or S3 does not migrate its existing data.

3. Initialize the Database with One Standalone Task

Create a second task-definition family, openwebui-migrate, copied from the application definition. Remove its HTTP health check, if configured, because this task exits instead of serving HTTP.

Use the same pinned application image as the service. Set ENABLE_DB_MIGRATIONS=true and override the container command as follows:

Field Value
Executable / entry point python
Arguments, as two separate values -c and import open_webui.config

Importing this module runs the schema migrations when that flag is true and exits with an error if they fail. It is an internal entry point, not a stable migration CLI, so recheck it against the migration code when you change versions. It initializes the schema; normal application startup subsequently initializes runtime settings and the administrator account.

The migration container needs the same database connection, signing key, network access, and image-pull permissions. Run exactly one execution at a time, with automatic retries disabled, while all application instances using that database are stopped. Continue only when it exits successfully and the logs show no migration error.

Use Run new task, select Fargate, set task count to 1, and use the application subnets and security groups without a load balancer. A standalone task is not maintained by an ECS service; see standalone tasks.

Expected result: the task reaches STOPPED, the openwebui container exit code is 0, and its logs show successful migrations. STOPPED alone is not a success signal.

4. Create the ECS Service

Create an ECS service using the application task definition, with ENABLE_DB_MIGRATIONS=false and its normal command. Start with desired task count 1 and connect the ALB target group to container openwebui, port 8080.

Set the target group's health-check path to /ready, which answers once startup has finished and the database and Redis respond. Start with a service health-check grace period of 300 seconds and adjust it to the measured startup time. /health serves as a separate process-liveness check. Model APIs and S3 permissions need the checks under Verify Before Adding Users.

Set ALB idle timeouts for your streaming workload. Target-group stickiness is optional; it is required only with ENABLE_WEBSOCKET_SUPPORT=false. See Session Affinity. Verify WebSockets and streamed responses through the ALB.

Use the AWS CLI to wait and inspect service events, replacing the identifiers:

aws ecs wait services-stable --cluster CLUSTER --services openwebui
aws ecs describe-services --cluster CLUSTER --services openwebui \
  --query 'services[0].{running:runningCount,desired:desiredCount,events:events[0:5]}'

Open the HTTPS hostname configured in WEBUI_URL. The initial administrator credentials create the first account during startup. Once verification passes, increase the desired count and optionally configure Service Auto Scaling. Budget PostgreSQL and Redis connections for the maximum task count.

Verify Before Adding Users

  • Sign in with the initial administrator account and verify that open sign-up is disabled. Configure your identity provider before enabling wider access.
  • Select a model and stream a response. Reopen the saved conversation.
  • Upload a small document containing a distinctive fact. Confirm indexing completes and a question about that fact retrieves the source.
  • Replace an application instance and confirm the same account, conversation, and uploaded file remain available.
  • With multiple instances, test repeated requests and WebSocket reconnection through the real ingress, checking for login loops and inconsistent state.

The initial administrator environment variables only create an account when the database has no users; changing them later does not reset its password. Rotate the initial password in the application after setup. Many application settings persist after first launch; review configuration persistence before expecting an environment change to replace a saved setting.

For enterprise deployments, verify license status separately from service health. See licensing and branding for the application settings and license network requirements; inject the key through this platform's secret mechanism rather than Kubernetes Secrets.

Updates and Recovery

Use a maintenance window for schema-changing updates:

  1. Save the deployed task definition and service configuration. Block new traffic, suspend service autoscaling and deployment automation, set desired count to zero, and verify all old application tasks are stopped. Stop any standalone tasks sharing the database as well.
  2. Take coordinated database and S3 backups and retain the signing key.
  3. Register a new migration-task revision using the new image. Run one standalone migration task and require exit code 0 before continuing.
  4. Register the application-task revision with that same image and migrations disabled. Update the service while its desired count remains zero, then restore the desired count and verify the service before resuming traffic and autoscaling.

An ECS rollback changes the image, not the database schema. Do not enable automatic rollback to an incompatible old application across a schema change; restore a compatible database/storage backup when required. See backup and restore.

Troubleshooting and Removal

Symptom Check
Task cannot start or pull image Execution role, ECR permissions, subnet egress/VPC endpoints, architecture, and Secrets Manager access.
ALB reports unhealthy targets IP target type, container port, task security group, /ready, startup logs, and database and Redis connectivity.
Chats work but uploads fail Task-role S3 permissions, bucket name/region, and extraction/embedding endpoints.
Login loops across tasks Shared signing key, common database, and Redis URL.
Streams disconnect ALB idle timeout, client reconnection, and Redis mode.

Deleting the ECS service does not delete RDS, S3, or Secrets Manager resources provisioned separately. Remove resources deliberately according to your retention policy; keep restoreable backups before removing persistent services.