feat: headless admin creation

This commit is contained in:
Timothy Jaeryang Baek
2026-01-09 12:01:36 +04:00
parent 9a9a824fe9
commit 1138929f4d
3 changed files with 57 additions and 0 deletions

View File

@@ -413,6 +413,16 @@ ENABLE_SIGNUP_PASSWORD_CONFIRMATION = (
os.environ.get("ENABLE_SIGNUP_PASSWORD_CONFIRMATION", "False").lower() == "true"
)
####################################
# Admin Account Runtime Creation
####################################
# Optional env vars for creating an admin account on startup
# Useful for headless/automated deployments
WEBUI_ADMIN_EMAIL = os.environ.get("WEBUI_ADMIN_EMAIL", "")
WEBUI_ADMIN_PASSWORD = os.environ.get("WEBUI_ADMIN_PASSWORD", "")
WEBUI_ADMIN_NAME = os.environ.get("WEBUI_ADMIN_NAME", "Admin")
WEBUI_AUTH_TRUSTED_EMAIL_HEADER = os.environ.get(
"WEBUI_AUTH_TRUSTED_EMAIL_HEADER", None
)

View File

@@ -486,6 +486,10 @@ from open_webui.env import (
AIOHTTP_CLIENT_SESSION_SSL,
ENABLE_STAR_SESSIONS_MIDDLEWARE,
ENABLE_PUBLIC_ACTIVE_USERS_COUNT,
# Admin Account Runtime Creation
WEBUI_ADMIN_EMAIL,
WEBUI_ADMIN_PASSWORD,
WEBUI_ADMIN_NAME,
)
@@ -510,6 +514,7 @@ from open_webui.utils.auth import (
decode_token,
get_admin_user,
get_verified_user,
create_admin_user,
)
from open_webui.utils.plugin import install_tool_and_function_dependencies
from open_webui.utils.oauth import (
@@ -588,6 +593,12 @@ async def lifespan(app: FastAPI):
if LICENSE_KEY:
get_license_data(app, LICENSE_KEY)
# Create admin account from env vars if specified and no users exist
if WEBUI_ADMIN_EMAIL and WEBUI_ADMIN_PASSWORD:
if create_admin_user(WEBUI_ADMIN_EMAIL, WEBUI_ADMIN_PASSWORD, WEBUI_ADMIN_NAME):
# Disable signup since we now have an admin
app.state.config.ENABLE_SIGNUP = False
# This should be blocking (sync) so functions are not deactivated on first /get_models calls
# when the first user lands on the / route.
log.info("Installing external dependencies of functions and tools...")

View File

@@ -24,6 +24,8 @@ from opentelemetry import trace
from open_webui.utils.access_control import has_permission
from open_webui.models.users import Users
from open_webui.models.auths import Auths
from open_webui.constants import ERROR_MESSAGES
@@ -420,3 +422,37 @@ def get_admin_user(user=Depends(get_current_user)):
detail=ERROR_MESSAGES.ACCESS_PROHIBITED,
)
return user
def create_admin_user(email: str, password: str, name: str = "Admin"):
"""
Create an admin user from environment variables.
Used for headless/automated deployments.
Returns the created user or None if creation failed.
"""
if not email or not password:
return None
if Users.has_users():
log.debug("Users already exist, skipping admin creation")
return None
log.info(f"Creating admin account from environment variables: {email}")
try:
hashed = get_password_hash(password)
user = Auths.insert_new_auth(
email=email.lower(),
password=hashed,
name=name,
role="admin",
)
if user:
log.info(f"Admin account created successfully: {email}")
return user
else:
log.error("Failed to create admin account from environment variables")
return None
except Exception as e:
log.error(f"Error creating admin account: {e}")
return None