170 lines
5.6 KiB
Bash
Executable File
170 lines
5.6 KiB
Bash
Executable File
#!/bin/bash
|
|
set -e
|
|
|
|
|
|
RG_NAME="smartbuilding-rg"
|
|
LOCATION="germanywestcentral"
|
|
ACR_NAME="sbacr$RANDOM"
|
|
ACI_NAME="smartbuilding-app"
|
|
DNS_LABEL="smartbuilding"
|
|
STORAGE_NAME="sbstorage${RANDOM}"
|
|
DB_PASS="${DB_PASS:-SmartBuilding2026!}"
|
|
|
|
|
|
APP_FQDN="${DNS_LABEL}.${LOCATION}.azurecontainer.io"
|
|
|
|
echo "=== SmartBuilding — Azure Deployment ==="
|
|
echo "Requires: az login && docker running"
|
|
echo "Web App: https://${APP_FQDN}"
|
|
echo "phpMyAdmin: http://${APP_FQDN}:8080"
|
|
echo ""
|
|
|
|
|
|
echo "[1/6] Registering Azure providers..."
|
|
az provider register --namespace Microsoft.ContainerRegistry --wait
|
|
az provider register --namespace Microsoft.ContainerInstance --wait
|
|
az provider register --namespace Microsoft.Storage --wait
|
|
|
|
|
|
echo "[2/6] Creating resource group and container registry..."
|
|
az group create --name $RG_NAME --location $LOCATION -o none
|
|
|
|
|
|
STORAGE_NAME=$(echo "$STORAGE_NAME" | tr -cd 'a-z0-9' | cut -c1-24)
|
|
az acr create --resource-group $RG_NAME --name $ACR_NAME \
|
|
--sku Basic --admin-enabled true -o none
|
|
|
|
|
|
until [ "$(az acr show --name $ACR_NAME --resource-group $RG_NAME \
|
|
--query provisioningState -o tsv 2>/dev/null)" = "Succeeded" ]; do
|
|
echo " Waiting for ACR..."; sleep 10
|
|
done
|
|
|
|
ACR_SERVER=$(az acr show --name $ACR_NAME --resource-group $RG_NAME --query loginServer -o tsv)
|
|
ACR_USER=$(az acr credential show --name $ACR_NAME --query username -o tsv)
|
|
ACR_PASS=$(az acr credential show --name $ACR_NAME --query "passwords[0].value" -o tsv)
|
|
|
|
|
|
echo "[3/6] Building and pushing smartbuilding webapp image..."
|
|
docker build -t "$ACR_SERVER/smartbuilding-webapp:latest" ./webapp
|
|
|
|
# Push without relying on local Docker credential store
|
|
TOKEN=$(az acr login --name $ACR_NAME --expose-token --output tsv --query accessToken)
|
|
TMPCFG=$(mktemp -d)
|
|
printf '{"auths":{"%s":{"auth":"%s"}}}\n' \
|
|
"$ACR_SERVER" "$(echo -n "00000000-0000-0000-0000-000000000000:$TOKEN" | base64 -w 0)" \
|
|
> "$TMPCFG/config.json"
|
|
DOCKER_CONFIG="$TMPCFG" docker push "$ACR_SERVER/smartbuilding-webapp:latest"
|
|
rm -rf "$TMPCFG"
|
|
|
|
echo "[4/6] Creating storage for database initialisation..."
|
|
az storage account create --name "$STORAGE_NAME" --resource-group $RG_NAME \
|
|
--location $LOCATION --sku Standard_LRS --allow-blob-public-access false -o none
|
|
|
|
STORAGE_KEY=$(az storage account keys list --resource-group $RG_NAME \
|
|
--account-name "$STORAGE_NAME" --query "[0].value" -o tsv)
|
|
|
|
az storage share create --name db-init \
|
|
--account-name "$STORAGE_NAME" --account-key "$STORAGE_KEY" -o none
|
|
|
|
# Upload the SQL schema + seed data
|
|
az storage file upload --account-name "$STORAGE_NAME" --account-key "$STORAGE_KEY" \
|
|
--share-name db-init --source webapp/user.sql --path user.sql -o none
|
|
|
|
|
|
echo "[5/6] Deploying container group (mysql + webapp + phpmyadmin + caddy)..."
|
|
|
|
YAML=$(mktemp /tmp/smartbuilding-aci-XXXX.yaml)
|
|
cat > "$YAML" << ACIYAML
|
|
apiVersion: '2021-10-01'
|
|
name: ${ACI_NAME}
|
|
location: ${LOCATION}
|
|
properties:
|
|
osType: Linux
|
|
restartPolicy: Always
|
|
imageRegistryCredentials:
|
|
- server: ${ACR_SERVER}
|
|
username: ${ACR_USER}
|
|
password: '${ACR_PASS}'
|
|
ipAddress:
|
|
type: Public
|
|
dnsNameLabel: ${DNS_LABEL}
|
|
ports:
|
|
- { port: 80, protocol: TCP }
|
|
- { port: 443, protocol: TCP }
|
|
- { port: 8080, protocol: TCP }
|
|
volumes:
|
|
- name: db-init
|
|
azureFile:
|
|
shareName: db-init
|
|
storageAccountName: ${STORAGE_NAME}
|
|
storageAccountKey: '${STORAGE_KEY}'
|
|
containers:
|
|
- name: mysql
|
|
properties:
|
|
image: mysql:8.0
|
|
environmentVariables:
|
|
- { name: MYSQL_ROOT_PASSWORD, secureValue: '${DB_PASS}' }
|
|
- { name: MYSQL_DATABASE, value: user }
|
|
resources:
|
|
requests: { cpu: 0.5, memoryInGB: 0.8 }
|
|
volumeMounts:
|
|
- { name: db-init, mountPath: /docker-entrypoint-initdb.d }
|
|
|
|
- name: webapp
|
|
properties:
|
|
image: ${ACR_SERVER}/smartbuilding-webapp:latest
|
|
environmentVariables:
|
|
- { name: DB_HOST, value: '127.0.0.1' }
|
|
- { name: DB_USER, value: root }
|
|
- { name: DB_NAME, value: user }
|
|
- { name: DB_PASSWORD, secureValue: '${DB_PASS}' }
|
|
resources:
|
|
requests: { cpu: 0.5, memoryInGB: 0.5 }
|
|
|
|
- name: phpmyadmin
|
|
properties:
|
|
image: phpmyadmin:latest
|
|
environmentVariables:
|
|
- { name: PMA_HOST, value: '127.0.0.1' }
|
|
- { name: PMA_USER, value: root }
|
|
- { name: PMA_PASSWORD, secureValue: '${DB_PASS}' }
|
|
- { name: APACHE_PORT, value: '8080' }
|
|
resources:
|
|
requests: { cpu: 0.3, memoryInGB: 0.3 }
|
|
ports:
|
|
- { port: 8080, protocol: TCP }
|
|
|
|
- name: caddy
|
|
properties:
|
|
image: caddy:2
|
|
command:
|
|
- caddy
|
|
- reverse-proxy
|
|
- --from
|
|
- ${APP_FQDN}
|
|
- --to
|
|
- localhost:3000
|
|
- --access-log
|
|
resources:
|
|
requests: { cpu: 0.2, memoryInGB: 0.3 }
|
|
ports:
|
|
- { port: 80, protocol: TCP }
|
|
- { port: 443, protocol: TCP }
|
|
ACIYAML
|
|
|
|
az container delete --resource-group $RG_NAME --name $ACI_NAME --yes 2>/dev/null || true
|
|
az container create --resource-group $RG_NAME --file "$YAML" -o none
|
|
rm -f "$YAML"
|
|
|
|
|
|
echo "[6/6] Deployment complete!"
|
|
echo ""
|
|
echo "=== SmartBuilding Application URLs ==="
|
|
echo " Web App: https://${APP_FQDN}"
|
|
echo " phpMyAdmin: http://${APP_FQDN}:8080"
|
|
echo ""
|
|
echo " DB Password: $DB_PASS"
|
|
echo " View logs: az container logs -g $RG_NAME -n $ACI_NAME --container-name <mysql|webapp|phpmyadmin|caddy>"
|
|
echo " Check status: az container show -g $RG_NAME -n $ACI_NAME --query 'containers[].{Name:name,State:instanceView.currentState.state}' -o table"
|