Anmerkung
Der Zugriff auf diese Seite erfordert eine Genehmigung. Du kannst versuchen, dich anzumelden oder die Verzeichnisse zu wechseln.
Der Zugriff auf diese Seite erfordert eine Genehmigung. Du kannst versuchen , die Verzeichnisse zu wechseln.
In diesem Artikel erfahren Sie, wie Sie eine Heroku-Anwendung zu Azure-Container-Apps migrieren. Sie exportieren Ihre Heroku-Konfiguration, stellen Ihre App bereit, migrieren Datendienste, richten CI/CD ein und konfigurieren benutzerdefinierte Domänen.
Eine konzeptionelle Übersicht über die Zuordnung von Heroku-zu-Azure-Konzepten, Dienstäquivalenten und häufig auftretenden Fallstricke finden Sie unter Heroku zu Azure Container Apps-Migrationsübersicht.
Lernziele
In diesem Artikel erfahren Sie, wie Sie:
- Exportieren der Heroku-App-Konfiguration und Bereitstellen in Azure-Container-Apps
- Migrieren von PostgreSQL- und Redis-Daten zu verwalteten Azure-Diensten
- Konfigurieren einer CI/CD-Pipeline mit GitHub-Aktionen
- Einrichten von benutzerdefinierten Domänen mit verwalteten TLS-Zertifikaten
- Konfigurieren von automatischen Skalierungsregeln für Ihre migrierte App
Voraussetzungen
Azure-Konto mit einem aktiven Abonnement. Erstellen Sie ein kostenloses Konto.
Azure CLI (Version 2.53.0 oder höher) mit der installierten Container-Apps-Erweiterung.
az extension add --name containerapp --upgrade az provider register --namespace Microsoft.AppHeroku CLI installiert und authentifiziert (zum Exportieren von Konfiguration und Daten).
Docker (optional – nur erforderlich, wenn Sie Images lokal erstellen).
Der Quellcode Ihrer App in einem Git-Repository.
Vertrautheit mit: Heroku-App-Verwaltung, grundlegende Azure CLI-Befehle und Containerkonzepte.
1 - Exportieren Ihrer Heroku-Konfiguration
Exportieren Sie zunächst die Konfigurationsvariablen Ihrer Heroku-App. Verwenden Sie diese Datei als Referenz, wenn Sie Umgebungsvariablen in Azure festlegen.
heroku config -a <HEROKU_APP_NAME> --json > heroku-config.json
Hinweis
Ersetzen Sie <HEROKU_APP_NAME> durch den Namen Ihrer Heroku-App. Ersetzen Sie in diesem Artikel Werte in spitzen Klammern (< >) durch Ihre eigenen Werte.
2 – Erstellen von Azure-Ressourcen
Definieren Sie die shellvariablen, die in diesem Verfahren verwendet werden. Erstellen Sie dann eine Ressourcengruppe und container-Apps-Umgebung.
# Define variables used throughout this migration.
# Replace the placeholder values with your own.
RESOURCE_GROUP="<RESOURCE_GROUP>"
LOCATION="eastus"
ENVIRONMENT="<ENVIRONMENT_NAME>"
APP_NAME="<APP_NAME>"
Registrieren Sie die erforderlichen Ressourcenanbieter. Erstellen Sie die Ressourcengruppe und -umgebung.
# Register resource providers (required once per subscription)
az provider register --namespace Microsoft.App
az provider register --namespace Microsoft.OperationalInsights
# Create a resource group to hold all migration resources
az group create \
--name $RESOURCE_GROUP \
--location $LOCATION
# Create a Container Apps environment, which automatically
# provisions a Log Analytics workspace for logging
az containerapp env create \
--name $ENVIRONMENT \
--resource-group $RESOURCE_GROUP \
--location $LOCATION
Hinweis
Durch die Erstellung der Umgebung wird automatisch ein Log Analytics-Arbeitsbereich erstellt. Dieser Schritt kann ein bis zwei Minuten dauern.
Überprüfen: Bestätigen Sie, dass die Umgebung läuft.
az containerapp env show \
--name $ENVIRONMENT \
--resource-group $RESOURCE_GROUP \
--query "properties.provisioningState" -o tsv
Die Ausgabe sollte Succeeded angezeigt werden.
3 – Bereitstellen Ihrer App
Wählen Sie eine der folgenden Bereitstellungsoptionen basierend auf dem Setup Ihrer App aus.
Option A: Bereitstellen aus der Quelle (keine Dockerfile erforderlich)
Dieser Befehl verwendet Cloud Native Buildpacks, um Ihre Sprache zu erkennen, zu erstellen und automatisch bereitzustellen – ähnlich wie die Heroku-Erfahrung git push .
az containerapp up \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--environment $ENVIRONMENT \
--source . \
--ingress external \
--target-port 3000
Hinweis
Das --source Flag verwendet Container Apps Cloud Build, die möglicherweise nicht in allen Regionen oder für alle Sprachstapel verfügbar sind. Wenn der Fehler auftritt, verwenden Sie stattdessen Option B.
Option B: Bereitstellen mit einer Dockerfile (empfohlen)
Wenn Ihre App noch nicht über eine Dockerfile-Datei verfügt, erstellen Sie eine. Das folgende Beispiel zeigt eine minimale Node.js Dockerfile, die Produktionsabhängigkeiten installiert, den Anwendungscode kopiert und den Server startet.
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Erstellen Sie das Image über die Azure Container Registry (ACR) und stellen Sie es für Container-Apps bereit. Diese Sequenz erstellt eine Registrierung, erstellt das Image in der Cloud, registriert die Registrierung bei Container-Apps und aktualisiert die Container-App, um das neue Image zu verwenden.
# Create an Azure Container Registry
az acr create \
--name <REGISTRY_NAME> \
--resource-group $RESOURCE_GROUP \
--sku Basic \
--admin-enabled true
# Build the image in ACR (no local Docker required)
az acr build \
--registry <REGISTRY_NAME> \
--image $APP_NAME:v1 .
# Retrieve the ACR password for registry authentication
ACR_PASSWORD=$(az acr credential show \
--name <REGISTRY_NAME> \
--query "passwords[0].value" -o tsv)
# Register ACR with the container app
az containerapp registry set \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--server <REGISTRY_NAME>.azurecr.io \
--username <REGISTRY_NAME> \
--password $ACR_PASSWORD
# Deploy the image to the container app
az containerapp update \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--image <REGISTRY_NAME>.azurecr.io/$APP_NAME:v1
Tipp
az acr build erstellt das Docker-Image in der Cloud – Sie benötigen Docker nicht lokal installiert. Dieser Ansatz ist der zuverlässigste Bereitstellungspfad.
Überprüfen: Vergewissern Sie sich, dass die Container-App ausgeführt wird.
az containerapp show \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--query "properties.runningStatus" -o tsv
4 – Festlegen von Umgebungsvariablen
Container-Apps verwenden geheime Schlüssel für vertrauliche Werte wie Verbindungszeichenfolgen und API-Schlüssel. Sie müssen geheime Schlüssel festlegen, bevor Sie sie in Umgebungsvariablen referenzieren.
Von Bedeutung
Legen Sie geheime Schlüssel fest, bevor Sie sie als Umgebungsvariablen referenzieren. Die Reihenfolge ist wichtig – das Verweisen auf ein Geheimnis, das noch nicht vorhanden ist, verursacht einen Fehler.
Die folgenden Befehle erstellen geheime Schlüssel in Container-Apps und legen dann Umgebungsvariablen fest, die auf diese geheimen Schlüssel verweisen. Durch das Aktualisieren von geheimen Schlüsseln allein wird die App nicht neu gestartet – der az containerapp update Befehl erstellt eine neue Revision, die die neuen Werte einnimmt.
# Set secrets (connection strings, API keys)
az containerapp secret set \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--secrets "redis-url=<AZURE_REDIS_CONNECTION_STRING>" \
"api-key=<YOUR_API_KEY>"
# Set environment variables that reference the secrets
az containerapp update \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--set-env-vars "REDIS_URL=secretref:redis-url" \
"API_KEY=secretref:api-key"
Tipp
Verwenden Sie ein Skript als Werkzeug zum Konvertieren von heroku-config.json in az containerapp update Befehle für die Massenmigration von Umgebungsvariablen.
5 – Überprüfen der Bereitstellung
Rufen Sie die Anwendungs-URL ab, und testen Sie dann Ihre App in einem Browser oder mithilfe von curl. Verwenden Sie den Protokolldatenstrom, um auf Startfehler zu überwachen.
# Get the app URL
az containerapp show \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--query "properties.configuration.ingress.fqdn" -o tsv
# Stream live console logs to check for errors
az containerapp logs show \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--type console \
--follow
6 – Migrieren von Datendiensten
Migrieren von PostgreSQL
Die folgende Sequenz exportiert eine Sicherung von Heroku Postgres, erstellt eine Azure-Datenbank für PostgreSQL Flexible Server, stellt die Daten wieder her und aktualisiert die Verbindungszeichenfolge in Ihrer Container-App.
# Export a backup from Heroku Postgres
heroku pg:backups:capture -a <HEROKU_APP_NAME>
heroku pg:backups:download -a <HEROKU_APP_NAME>
Erstellen Sie die Azure-Datenbank für PostgreSQL Flexible Server und Datenbank.
# Create the PostgreSQL Flexible Server instance
az postgres flexible-server create \
--resource-group $RESOURCE_GROUP \
--name <PG_SERVER_NAME> \
--location $LOCATION \
--admin-user <ADMIN_USER> \
--admin-password '<STRONG_PASSWORD>' \
--sku-name Standard_B1ms \
--tier Burstable
# Create the application database
az postgres flexible-server db create \
--resource-group $RESOURCE_GROUP \
--server-name <PG_SERVER_NAME> \
--database-name <DATABASE_NAME>
Stellen Sie die Heroku-Sicherung in der neuen Azure-Datenbank wieder her, und aktualisieren Sie die Verbindungszeichenfolge.
# Restore the Heroku backup to Azure PostgreSQL
pg_restore \
--host=<PG_SERVER_NAME>.postgres.database.azure.com \
--port=5432 \
--username=<ADMIN_USER> \
--dbname=<DATABASE_NAME> \
--no-owner --no-acl \
latest.dump
# Update the Container App with the new connection string
az containerapp secret set \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--secrets "database-url=postgresql://<ADMIN_USER>:<PASSWORD>@<PG_SERVER_NAME>.postgres.database.azure.com:5432/<DATABASE_NAME>?sslmode=require"
Überprüfen: Stellen Sie eine Verbindung zur Azure-Datenbank her und bestätigen Sie, dass Ihre Tabellen und Zeilenanzahlen mit der Heroku-Quelle übereinstimmen.
Migrieren von Redis
Erstellen Sie einen Azure-Cache für Redis-Instanz, und verbinden Sie ihn mit Ihrer Container-App. Mit den folgenden Befehlen wird der Cache bereitgestellt, der Zugriffsschlüssel abgerufen und die Verbindungszeichenfolge als Geheimnis festgelegt.
# Create Azure Cache for Redis (provisioning takes 10–20 minutes)
az redis create \
--resource-group $RESOURCE_GROUP \
--name <REDIS_NAME> \
--location $LOCATION \
--sku Basic \
--vm-size c0
# Retrieve the primary access key
az redis list-keys \
--resource-group $RESOURCE_GROUP \
--name <REDIS_NAME> \
--query "primaryKey" -o tsv
# Store the connection string as a Container App secret
az containerapp secret set \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--secrets "redis-url=rediss://:<ACCESS_KEY>@<REDIS_NAME>.redis.cache.windows.net:6380"
# Set the environment variable referencing the secret
az containerapp update \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--set-env-vars "REDIS_URL=secretref:redis-url"
Hinweis
Die Bereitstellung von Azure Cache für Redis kann 10 bis 20 Minuten dauern. Redis wird normalerweise als Cache genutzt. Es gibt keine Daten zu migrieren, es sei denn, Sie verwenden es als primären Datenspeicher. Zeigen Sie Ihre App auf die neue Instanz.
Überprüfen Sie die Redis-Verbindung, indem Sie den Health-Endpoint Ihrer App aufrufen oder die Protokolle nach dem Update überprüfen.
Weitere Add-Ons
Weitere Heroku-Add-Ons finden Sie in der Migrationsübersicht in der Tabelle " Dienstäquivalente ".
Aktualisieren Sie für jedes Add-On: Stellen Sie den azure-äquivalenten Dienst bereit, aktualisieren Sie die Verbindungsdetails in Ihren Container-App-Umgebungsvariablen, überprüfen Sie die Integration, und entfernen Sie dann das Heroku-Add-On.
7 – Einrichten von CI/CD
GitHub-Aktionen
Erstellen Sie einen GitHub-Aktionsworkflow, der Ihr Docker-Image erstellt, es an ACR überträgt und bei jedem Push auf die main-Verzweigung in Containeranwendungen deployt. Speichern Sie die folgende Datei wie .github/workflows/deploy.yml in Ihrem Repository.
Dieser Workflow führt die folgenden Schritte aus:
- Checkt Ihren Quellcode aus.
- Meldet sich bei Azure mit einem Dienstprinzipal an, der als GitHub-Geheimnis gespeichert ist.
- Erstellt und pusht ein Docker-Image an ACR, markiert mit dem Git Commit SHA.
- Aktualisiert die Container-App so, dass das neue Image verwendet wird, das eine neue Überarbeitung auslöst.
name: Deploy to Azure Container Apps
on:
push:
branches: [main]
# Environment variables shared across all jobs.
# Update these values to match your Azure resource names.
env:
AZURE_CONTAINER_REGISTRY: <REGISTRY_NAME>.azurecr.io
IMAGE_NAME: <APP_NAME>
RESOURCE_GROUP: <RESOURCE_GROUP>
CONTAINER_APP_NAME: <APP_NAME>
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
# Check out the repository source code
- uses: actions/checkout@v4
# Authenticate to Azure using the service principal credentials
- uses: azure/login@v2
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
# Build the Docker image and push it to ACR
- name: Build and push image
run: |
az acr login --name <REGISTRY_NAME>
docker build -t ${{ env.AZURE_CONTAINER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} .
docker push ${{ env.AZURE_CONTAINER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
# Deploy the new image to the container app
- name: Deploy to Container Apps
run: |
az containerapp update \
--name ${{ env.CONTAINER_APP_NAME }} \
--resource-group ${{ env.RESOURCE_GROUP }} \
--image ${{ env.AZURE_CONTAINER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
Erstellen Sie den Dienstprinzipal: Führen Sie den folgenden Befehl aus, um einen Dienstprincipal mit Contributor Zugriff auf Ihre Ressourcengruppe zu erstellen. Speichern Sie die JSON-Ausgabe als geheimen AZURE_CREDENTIALS Schlüssel in Ihren GitHub-Repositoryeinstellungen.
az ad sp create-for-rbac \
--name "github-deploy" \
--role contributor \
--scopes /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/$RESOURCE_GROUP \
--json-auth
Azure DevOps
Verwenden Sie die Aufgabe "Bereitstellen von Azure-Container-Apps" in Ihrer Azure DevOps-Pipeline. Der Workflow ist ähnlich: Erstellen Sie das Image, pushen Sie an ACR, und aktualisieren Sie die Container-App.
8 – Konfigurieren von benutzerdefinierten Domänen und TLS
Die folgenden Befehle fügen Ihrer Container-App eine benutzerdefinierte Domäne hinzu, rufen die DNS-Überprüfungseinträge ab und binden ein kostenloses verwaltetes TLS-Zertifikat. Sie müssen DNS-Einträge bei Ihrem Domänenanbieter zwischen den Schritten 2 und 4 hinzufügen.
# Add your custom domain to the container app
az containerapp hostname add \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--hostname <YOUR_DOMAIN>
# List hostnames to get the required DNS verification records
az containerapp hostname list \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
-o table
Fügen Sie bei Ihrem DNS-Anbieter die folgenden Einträge hinzu:
- TXT-Eintrag: Für die Domänenüberprüfung (Wert, der in der vorherigen Befehlsausgabe angezeigt wird).
-
CNAME-Eintrag: Verweisen
<YOUR_DOMAIN>auf<APP_NAME>.<REGION>.azurecontainerapps.io.
Binden Sie nach der DNS-Ausbreitung das verwaltete Zertifikat.
# Bind a free managed TLS certificate (auto-renews)
az containerapp hostname bind \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--hostname <YOUR_DOMAIN> \
--environment $ENVIRONMENT \
--validation-method CNAME
Überprüfen: Bestätigen Sie, dass das Zertifikat gebunden ist.
az containerapp hostname list \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
-o table
Verwaltete Zertifikate sind kostenlos und werden automatisch erneuert, was dem automatisierten Zertifikatsmanagement von Heroku entspricht.
9 – Konfigurieren der Skalierung
Richten Sie automatische Skalierungsregeln ein, um die manuelle Dyno-Skalierung von Heroku zu ersetzen. Mit dem folgenden Befehl wird die HTTP-basierte automatische Skalierung konfiguriert, die basierend auf gleichzeitiger Anforderungslast zwischen 0 und 10 Replikaten skaliert wird, wobei ein neues Replikat hinzugefügt wird, wenn eine einzelne Instanz 50 gleichzeitige Anforderungen überschreitet.
az containerapp update \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--min-replicas 0 \
--max-replicas 10 \
--scale-rule-name http-rule \
--scale-rule-type http \
--scale-rule-http-concurrency 50
Stellen Sie für Arbeitsprozesse eine separate Container-App mit warteschlangenbasierter Skalierung bereit. Mit dem folgenden Befehl wird eine Arbeitscontainer-App erstellt, die basierend auf der Anzahl der Nachrichten in einer Azure Storage-Warteschlange von 0 bis 5 Replikaten skaliert wird.
az containerapp create \
--name <APP_NAME>-worker \
--resource-group $RESOURCE_GROUP \
--environment $ENVIRONMENT \
--image <REGISTRY_NAME>.azurecr.io/<APP_NAME>-worker:latest \
--min-replicas 0 \
--max-replicas 5 \
--scale-rule-name queue-rule \
--scale-rule-type azure-queue \
--scale-rule-metadata "queueName=jobs" "queueLength=10" \
--scale-rule-auth "connection=queue-connection-string"
Tipp
Legen Sie für Produktions-Apps, die sofort reagieren müssen, folgendes fest --min-replicas 1. Verwenden Sie --min-replicas 0 in Entwicklungs- und Stagingumgebungen, um von Scale-to-Zero zu profitieren und Leerlaufkosten zu vermeiden.
Problembehandlung
| Das Problem | Ursache | Beschluss |
|---|---|---|
| Die App antwortet nach der Bereitstellung nicht auf HTTP-Anforderungen. | Container-Apps erwarten, dass Ihre App auf den durch die PORT Umgebungsvariable angegebenen Port lauscht (Standard 80). Ihre App lauscht möglicherweise auf einem anderen Port. |
Setzen Sie --target-port auf den Port, den Ihre App beim Erstellen oder Aktualisieren der Container-App überwacht. |
az containerapp up --source schlägt mit Build-Fehlern fehl |
Cloud Build ist in allen Regionen oder für alle Sprachstapel nicht verfügbar. | Verwenden Sie den Dockerfile-basierten Ansatz: erstellen mit az acr build und das Image bereitstellen. Siehe Option B: Bereitstellen mit einem Dockerfile. |
| Umgebungsvariablen, die auf Secrets verweisen, sind leer. | Geheime Schlüssel müssen vorhanden sein, bevor Sie in Umgebungsvariablen darauf verweisen. | Führen Sie zuerst az containerapp secret set aus, dann az containerapp update, um die Umgebungsvariablen festzulegen. Weitere Informationen finden Sie unter Schritt 4. |
| Die Azure-Dienstbereitstellung dauert länger als erwartet | Azure Managed Services haben längere Bereitstellungszeiten als Heroku-Add-Ons. | Azure Cache für Redis: 10–20 Minuten. PostgreSQL Flexible Server: 5-10 Minuten. Stellen Sie Dienste parallel bereit, während Sie Ihre App bereitstellen. |
| Dateien, die zur Laufzeit geschrieben wurden, werden nach dem Neustart nicht mehr angezeigt | Container-Apps verwenden ein kurzlebiges Dateisystem, ähnlich wie Heroku. | Bereitstellen einer Azure Files-Freigabe für beständigen Speicher. |
Bereinigen von Ressourcen
Wenn Sie Ressourcen speziell für diese Migrationsanleitung erstellt haben, löschen Sie die Ressourcengruppe, um alle zugehörigen Ressourcen zu entfernen und um weitere Kosten zu vermeiden.
az group delete --name $RESOURCE_GROUP --yes --no-wait
Vorsicht
Dieser Befehl löscht die Ressourcengruppe und alle darin enthaltenen Ressourcen, einschließlich Datenbanken, Containerregistrierungen und Container-Apps. Diese Aktion kann nicht rückgängig gemacht werden.
Verwandte Inhalte
- Übersicht über die Migration von Heroku zu Azure Container Apps
- Einrichten von Azure Application Insights zur Überwachung und Warnung
- Hinzufügen von Azure Front Door für CDN, WAF und globalen Lastenausgleich
- Verwenden von Dapr mit Azure-Container-Apps für die Microservice-Kommunikation
- Dokumentation zu Azure-Container-Apps