Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions ct/temporal.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env bash
_CS_DEFAULT_URL="https://raw.githubusercontent.com/community-scripts/DevScripts/main"
_cs_boot="${COMMUNITY_SCRIPTS_CORE_DIR:-$(dirname "${BASH_SOURCE[0]}")/../../core}/core/build.func"
source "$_cs_boot" 2>/dev/null || source <(curl -fsSL "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/core/build.func")
# Copyright (c) 2021-2026 community-scripts ORG
# Author: Renan Bastos (renanbastos93)
# License: MIT | https://github.com/community-scripts/DevScripts/raw/main/LICENSE
# Source: https://github.com/temporalio/temporal

APP="Temporal"
var_tags="${var_tags:-workflow;automation}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-13}"
#var_arm64="${var_arm64:-yes}" # unset = ask the user; server, UI and CLI all ship linux_arm64 assets, but not yet run on arm64
var_unprivileged="${var_unprivileged:-1}"

header_info "$APP"
variables
color
catch_errors

function update_script() {
header_info
check_container_storage
check_container_resources

if [[ ! -d /opt/temporal ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi

if check_for_gh_release "temporal" "temporalio/temporal"; then
msg_info "Stopping Temporal"
systemctl stop temporal-ui temporal
msg_ok "Stopped Temporal"

CLEAN_INSTALL=1 fetch_and_deploy_gh_release "temporal" "temporalio/temporal" "prebuild" "latest" "/opt/temporal" "temporal_*_linux_$(arch_resolve).tar.gz"

msg_info "Migrating Temporal Database"
set -a && source /etc/temporal/temporal.env && set +a
$STD /opt/temporal/temporal-sql-tool --db temporal update-schema --schema-name postgresql/v12/temporal
$STD /opt/temporal/temporal-sql-tool --db temporal_visibility update-schema --schema-name postgresql/v12/visibility
msg_ok "Migrated Temporal Database"

msg_info "Starting Temporal"
systemctl start temporal temporal-ui
msg_ok "Started Temporal"
msg_ok "Updated Temporal successfully!"
fi

if check_for_gh_release "temporal-ui" "temporalio/ui-server"; then
msg_info "Stopping Temporal UI"
systemctl stop temporal-ui
msg_ok "Stopped Temporal UI"

CLEAN_INSTALL=1 fetch_and_deploy_gh_release "temporal-ui" "temporalio/ui-server" "prebuild" "latest" "/opt/temporal-ui" "ui-server_*_linux_$(arch_resolve).tar.gz"

msg_info "Starting Temporal UI"
systemctl start temporal-ui
msg_ok "Started Temporal UI"
msg_ok "Updated Temporal UI successfully!"
fi

if check_for_gh_release "temporal-cli" "temporalio/cli"; then
CLEAN_INSTALL=1 fetch_and_deploy_gh_release "temporal-cli" "temporalio/cli" "prebuild" "latest" "/opt/temporal-cli" "temporal_cli_*_linux_$(arch_resolve).tar.gz"
msg_ok "Updated Temporal CLI successfully!"
fi
exit
}

start
build_container
description

msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW}Access it using the following URL:${CL}"
echo -e "${GATEWAY}${BGN}http://${IP}:8080${CL}"
echo -e "${INFO}${YW}gRPC endpoint for workers and SDKs: ${IP}:7233${CL}"
206 changes: 206 additions & 0 deletions install/temporal-install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
#!/usr/bin/env bash

# Copyright (c) 2021-2026 community-scripts ORG
# Author: Renan Bastos (renanbastos93)
# License: MIT | https://github.com/community-scripts/DevScripts/raw/main/LICENSE
# Source: https://github.com/temporalio/temporal

source /dev/stdin <<<"$FUNCTIONS_FILE_PATH"
color
verb_ip6
catch_errors
setting_up_container
network_check
update_os

PG_VERSION="17" setup_postgresql
PG_DB_NAME="temporal" PG_DB_USER="temporal" PG_DB_SCHEMA_PERMS="true" setup_postgresql_db

fetch_and_deploy_gh_release "temporal" "temporalio/temporal" "prebuild" "latest" "/opt/temporal" "temporal_*_linux_$(arch_resolve).tar.gz"
fetch_and_deploy_gh_release "temporal-ui" "temporalio/ui-server" "prebuild" "latest" "/opt/temporal-ui" "ui-server_*_linux_$(arch_resolve).tar.gz"
fetch_and_deploy_gh_release "temporal-cli" "temporalio/cli" "prebuild" "latest" "/opt/temporal-cli" "temporal_cli_*_linux_$(arch_resolve).tar.gz"

msg_info "Configuring Temporal"
mkdir -p /etc/temporal/config/dynamicconfig /etc/temporal/ui
ln -sf /opt/temporal-cli/temporal /usr/local/bin/temporal
cat <<EOF >/etc/temporal/temporal.env
SQL_PLUGIN=postgres12
SQL_HOST=127.0.0.1
SQL_PORT=5432
SQL_USER=temporal
SQL_PASSWORD=${PG_DB_PASS}
EOF
chmod 600 /etc/temporal/temporal.env
cat <<'EOF' >/etc/temporal/config/production.yaml
# enable-template
log:
stdout: true
level: info

persistence:
defaultStore: postgres-default
visibilityStore: postgres-visibility
numHistoryShards: 4
datastores:
postgres-default:
sql:
pluginName: {{ env "SQL_PLUGIN" | quote }}
databaseName: "temporal"
connectAddr: {{ printf "%s:%s" (env "SQL_HOST") (env "SQL_PORT") | quote }}
connectProtocol: "tcp"
user: {{ env "SQL_USER" | quote }}
password: {{ env "SQL_PASSWORD" | quote }}
maxConns: 20
maxIdleConns: 20
maxConnLifetime: "1h"
postgres-visibility:
sql:
pluginName: {{ env "SQL_PLUGIN" | quote }}
databaseName: "temporal_visibility"
connectAddr: {{ printf "%s:%s" (env "SQL_HOST") (env "SQL_PORT") | quote }}
connectProtocol: "tcp"
user: {{ env "SQL_USER" | quote }}
password: {{ env "SQL_PASSWORD" | quote }}
maxConns: 10
maxIdleConns: 10
maxConnLifetime: "1h"

global:
membership:
maxJoinDuration: 30s
broadcastAddress: "127.0.0.1"

services:
frontend:
rpc:
grpcPort: 7233
membershipPort: 6933
bindOnIP: "0.0.0.0"

matching:
rpc:
grpcPort: 7235
membershipPort: 6935
bindOnLocalHost: true

history:
rpc:
grpcPort: 7234
membershipPort: 6934
bindOnLocalHost: true

worker:
rpc:
grpcPort: 7239
membershipPort: 6939
bindOnLocalHost: true

clusterMetadata:
enableGlobalNamespace: false
failoverVersionIncrement: 10
masterClusterName: "active"
currentClusterName: "active"
clusterInformation:
active:
enabled: true
initialFailoverVersion: 1
rpcName: "frontend"
rpcAddress: "127.0.0.1:7233"

dcRedirectionPolicy:
policy: "noop"

archival:
history:
state: "disabled"
visibility:
state: "disabled"

namespaceDefaults:
archival:
history:
state: "disabled"
visibility:
state: "disabled"

dynamicConfigClient:
filepath: "/etc/temporal/config/dynamicconfig/production.yaml"
pollInterval: "60s"
EOF
cat <<EOF >/etc/temporal/config/dynamicconfig/production.yaml
limit.maxIDLength:
- value: 255
constraints: {}
EOF
cat <<EOF >/etc/temporal/ui/production.yaml
temporalGrpcAddress: 127.0.0.1:7233
port: 8080
enableUi: true
defaultNamespace: default
cors:
cookieInsecure: true
allowOrigins:
- http://${LOCAL_IP}:8080
EOF
msg_ok "Configured Temporal"

msg_info "Initializing Temporal Database"
set -a && source /etc/temporal/temporal.env && set +a
$STD /opt/temporal/temporal-sql-tool --db temporal_visibility create-database
$STD /opt/temporal/temporal-sql-tool --db temporal setup-schema -v 0.0
$STD /opt/temporal/temporal-sql-tool --db temporal update-schema --schema-name postgresql/v12/temporal
$STD /opt/temporal/temporal-sql-tool --db temporal_visibility setup-schema -v 0.0
$STD /opt/temporal/temporal-sql-tool --db temporal_visibility update-schema --schema-name postgresql/v12/visibility
msg_ok "Initialized Temporal Database"

msg_info "Creating Services"
cat <<EOF >/etc/systemd/system/temporal.service
[Unit]
Description=Temporal Server
After=network.target postgresql.service
Requires=postgresql.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/temporal
EnvironmentFile=/etc/temporal/temporal.env
ExecStart=/opt/temporal/temporal-server --root /etc/temporal --env production --allow-no-auth start
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

cat <<EOF >/etc/systemd/system/temporal-ui.service
[Unit]
Description=Temporal UI
After=network.target temporal.service
Wants=temporal.service

[Service]
Type=simple
User=root
WorkingDirectory=/opt/temporal-ui
ExecStart=/opt/temporal-ui/ui-server --root /etc/temporal --config ui --env production start
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF
systemctl enable -q --now temporal temporal-ui
msg_ok "Created Services"

msg_info "Creating Default Namespace"
for _ in {1..60}; do
temporal operator cluster health &>/dev/null && break
sleep 1
done
$STD temporal operator namespace create --namespace default
msg_ok "Created Default Namespace"

motd_ssh
customize
cleanup_lxc
49 changes: 49 additions & 0 deletions json/temporal.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "Temporal",
"slug": "temporal",
"categories": [
20
],
"date_created": "2026-11-09",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8080,
"documentation": "https://docs.temporal.io/",
"website": "https://temporal.io/",
"repository": "https://github.com/temporalio/temporal",
"logo": "https://cdn.jsdelivr.net/gh/temporalio/ui@main/src/lib/vendor/apple-touch-icon.png",
"description": "Temporal is an open-source durable execution platform. Workflows written in Go, Java, Python, TypeScript, .NET, PHP or Ruby keep their state across crashes, restarts and retries, and the server handles timers, retries, signals and schedules so application code does not have to.",
"install_methods": [
{
"type": "default",
"script": "ct/temporal.sh",
"config_path": "/etc/temporal/config/production.yaml",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 8,
"os": "Debian",
"version": "13"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "The gRPC endpoint on port 7233 and the UI on 8080 have no authentication. Keep the container on a trusted network or put it behind a firewall and a TLS proxy.",
"type": "warning"
},
{
"text": "Point workers and SDK clients at <IP>:7233. The temporal CLI is installed in the container and already talks to the local server; the default namespace is created with a 72h retention.",
"type": "info"
},
{
"text": "The database password lives in /etc/temporal/temporal.env; the server config in /etc/temporal/config/production.yaml reads it from there. Restart temporal after changing either file.",
"type": "info"
}
]
}
Loading