Nota
L'accés a aquesta pàgina requereix autorització. Pots provar d'iniciar sessió o canviar de directori.
L'accés a aquesta pàgina requereix autorització. Pots provar de canviar directoris.
En este artículo se muestra cómo migrar una aplicación Heroku a Azure Container Apps. Exporta la configuración de Heroku, implementa la aplicación, migra los servicios de datos, configura CI/CD y configura dominios personalizados.
Para obtener una visión general conceptual sobre el mapeo de conceptos de Heroku a Azure, los equivalentes de servicios y los problemas comunes, consulte visión general de la migración de Heroku a Azure Container Apps.
Objetivos de aprendizaje
En este artículo aprenderá a:
- Exportación de la configuración de la aplicación Heroku e implementación en Azure Container Apps
- Migración de datos de PostgreSQL y Redis a servicios administrados de Azure
- Configurar una canalización CI/CD con GitHub Actions
- Configuración de dominios personalizados con certificados TLS administrados
- Configuración de reglas de escalado automático para la aplicación migrada
Prerrequisitos
Cuenta de Azure con una suscripción activa. cree una de forma gratuita.
CLI de Azure (versión 2.53.0 o posterior) con la extensión Container Apps instalada.
az extension add --name containerapp --upgrade az provider register --namespace Microsoft.AppLa CLI de Heroku se instaló y autentica (se usa para exportar la configuración y los datos).
Docker (opcional: solo es necesario si crea imágenes localmente).
El código fuente de la aplicación en un repositorio de Git.
Familiaridad con: Administración de aplicaciones Heroku, comandos básicos de la CLI de Azure y conceptos de contenedor.
1 - Exportación de la configuración de Heroku
Empiece por exportar las variables de configuración de la aplicación Heroku. Use este archivo como referencia al establecer variables de entorno en Azure.
heroku config -a <HEROKU_APP_NAME> --json > heroku-config.json
Nota:
Reemplace por <HEROKU_APP_NAME> el nombre de la aplicación Heroku. En este artículo, reemplace los valores entre corchetes angulares (< >) por sus propios valores.
2- Creación de recursos de Azure
Defina las variables de shell usadas en este procedimiento. A continuación, cree un grupo de recursos y un entorno de Container Apps.
# 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>"
Registre los proveedores de recursos necesarios. Cree el grupo de recursos y el entorno.
# 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
Nota:
La creación del entorno aprovisiona automáticamente un área de trabajo de Log Analytics. Este paso puede tardar de uno a dos minutos.
Comprobar: confirme que el entorno se está ejecutando.
az containerapp env show \
--name $ENVIRONMENT \
--resource-group $RESOURCE_GROUP \
--query "properties.provisioningState" -o tsv
La salida debe mostrar Succeeded.
3- Implementación de la aplicación
Elija una de las siguientes opciones de implementación en función de la configuración de la aplicación.
Opción A: Implementar desde el origen (no se necesita dockerfile)
Este comando usa Cloud Native Buildpacks para detectar el lenguaje, la compilación y la implementación automáticamente, de forma similar a la experiencia de Heroku git push .
az containerapp up \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--environment $ENVIRONMENT \
--source . \
--ingress external \
--target-port 3000
Nota:
El --source indicador utiliza Container Apps Cloud Build, que podría no estar disponible en todas las regiones o para todos los conjuntos de tecnologías de idioma. Si se produce un error, use la opción B en su lugar.
Opción B: Implementar con un Dockerfile (recomendado)
Si la aplicación aún no tiene un Dockerfile, cree uno. En el ejemplo siguiente se muestra un Node.js Dockerfile mínimo que instala dependencias de producción, copia el código de la aplicación e inicia el servidor.
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Compile la imagen a través de Azure Container Registry (ACR) e implemente en Container Apps. Esta secuencia crea un registro, compila la imagen en la nube, registra el registro con Container Apps y actualiza la aplicación contenedora para usar la nueva imagen.
# 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
Sugerencia
az acr build compila la imagen de Docker en la nube; no necesita Docker instalado localmente. Este enfoque es el camino de implementación más confiable.
Comprobar: confirme que la aplicación contenedora se está ejecutando.
az containerapp show \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
--query "properties.runningStatus" -o tsv
4- Establecimiento de variables de entorno
Container Apps usa secretos para valores confidenciales, como cadenas de conexión y claves de API. Debe establecer secretos antes de hacer referencia a ellos en variables de entorno.
Importante
Establezca secretos antes de hacer referencia a ellos como variables de entorno. El orden es importante: hacer referencia a un secreto que aún no existe provoca un error.
Los siguientes comandos crean secretos en Container Apps y, a continuación, establecen variables de entorno que hacen referencia a esos secretos. La actualización de secretos por sí solo no reinicia la aplicación: el az containerapp update comando crea una nueva revisión que recoge los nuevos valores.
# 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"
Sugerencia
Use un script para convertir heroku-config.json en az containerapp update comandos para la migración masiva de variables de entorno.
5- Comprobación de la implementación
Recupere la dirección URL de la aplicación y, a continuación, pruebe la aplicación en un explorador o mediante curl. Use el flujo de registro para supervisar si hay errores de inicio.
# 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- Migración de servicios de datos
Migración de PostgreSQL
La secuencia siguiente exporta una copia de seguridad de Heroku Postgres, crea un servidor flexible de Azure Database for PostgreSQL, restaura los datos y actualiza la cadena de conexión en la aplicación contenedora.
# Export a backup from Heroku Postgres
heroku pg:backups:capture -a <HEROKU_APP_NAME>
heroku pg:backups:download -a <HEROKU_APP_NAME>
Cree el servidor flexible y la base de datos de Azure Database for PostgreSQL.
# 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>
Restaure la copia de seguridad de Heroku en la nueva base de datos de Azure y actualice la cadena de conexión.
# 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"
Compruebe: conéctese a la base de datos de Azure y confirme que las tablas y los recuentos de filas coinciden con el origen de Heroku.
Migración de Redis
Cree una instancia de Azure Cache for Redis y conéctela a la aplicación de contenedor. Los siguientes comandos aprovisionan la memoria caché, recuperan la clave de acceso y establecen la cadena de conexión como un secreto.
# 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"
Nota:
El aprovisionamiento de Azure Cache for Redis puede tardar entre 10 y 20 minutos. Redis se usa normalmente como caché, por lo que, a menos que la use como almacén de datos principal, no hay datos que migrar. Apunte la aplicación en la nueva instancia.
Comprobar: Confirme la conexión de Redis comprobando el punto de control de salud de la aplicación o los registros después de la actualización.
Otros complementos
Para otros complementos de Heroku, consulte la tabla Equivalentes de servicio en la información general sobre la migración.
Para cada complemento: aprovisione el servicio equivalente de Azure, actualice los detalles de conexión en las variables de entorno de Container App, valide la integración y, a continuación, quite el complemento Heroku.
7 - Configurar CI/CD
GitHub Actions
Cree un flujo de trabajo de GitHub Actions que compile su imagen de Docker, la suba a ACR y la implemente en Container Apps en cada inserción en la rama main. Guarde el siguiente archivo como .github/workflows/deploy.yml en el repositorio.
Este flujo de trabajo realiza los pasos siguientes:
- Echa un vistazo al código fuente.
- Se inicia sesión en Azure mediante un principal de servicio almacenado como un secreto de GitHub.
- Compila e inserta una imagen de Docker en ACR, etiquetada con la confirmación de Git SHA.
- Actualiza la aplicación contenedora para usar la nueva imagen, que desencadena una nueva revisión.
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 }}
Cree el principal de servicio: ejecute el siguiente comando para crear un principal de servicio con el acceso delimitado a su grupo de recursos. Almacene la salida JSON como secreto en la AZURE_CREDENTIALS configuración del repositorio de GitHub.
az ad sp create-for-rbac \
--name "github-deploy" \
--role contributor \
--scopes /subscriptions/<SUBSCRIPTION_ID>/resourceGroups/$RESOURCE_GROUP \
--json-auth
Azure DevOps
Utiliza la tarea de implementación de Azure Container Apps en la canalización de Azure DevOps. El flujo de trabajo es similar: compile la imagen, inserte en ACR y actualice la aplicación contenedora.
8: Configuración de dominios personalizados y TLS
Los siguientes comandos agregan un dominio personalizado a la aplicación contenedora, recuperan los registros de comprobación de DNS y enlazan un certificado TLS administrado gratuito. Debe agregar registros DNS en el proveedor de dominio entre los pasos 2 y 4.
# 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
En el proveedor DNS, agregue los siguientes registros:
- Registro TXT: para la comprobación del dominio (valor que se muestra en la salida del comando anterior).
-
Registro CNAME: apunte
<YOUR_DOMAIN>a<APP_NAME>.<REGION>.azurecontainerapps.io.
Después de la propagación de DNS, enlace el certificado administrado.
# 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
Comprobar: confirme que el certificado está vinculado.
az containerapp hostname list \
--name $APP_NAME \
--resource-group $RESOURCE_GROUP \
-o table
Los certificados administrados son gratuitos y se renuevan automáticamente, equivalentes a la gestión automatizada de certificados de Heroku.
9- Configurar el escalado
Configure reglas de escalado automático para reemplazar el escalado manual de Heroku. El siguiente comando configura el escalado automático basado en HTTP que se escala entre 0 y 10 réplicas en función de la carga de solicitudes simultáneas, con una nueva réplica agregada siempre que cualquier instancia única supere 50 solicitudes simultáneas.
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
En el caso de los procesos de trabajo, implemente una aplicación de contenedor separada con escalado basado en cola. El comando siguiente crea una aplicación de contenedor de trabajo que escala de 0 a 5 réplicas en función del número de mensajes de una cola de Azure Storage.
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"
Sugerencia
En el caso de las aplicaciones de producción que necesitan responder inmediatamente, establezca --min-replicas 1. Para entornos de desarrollo y pruebas, use --min-replicas 0 para aprovechar la escalabilidad a cero y eliminar los costos de inactividad.
Solución de problemas
| Problema | Causa | Resolución |
|---|---|---|
| La aplicación no responde a solicitudes HTTP después de la implementación | Container Apps espera que la aplicación escuche en el puerto especificado por la PORT variable de entorno (valor predeterminado 80). Es posible que la aplicación escuche en un puerto diferente. |
Establece --target-port en el puerto en el que tu aplicación escucha al crear o actualizar la aplicación de contenedor. |
az containerapp up --source falla debido a errores del generador |
Cloud Build no está disponible en todas las regiones ni para todas las pilas de lenguajes. | Use el enfoque basado en Dockerfile: compile con az acr build e implemente la imagen. Consulte opción B: Implementación con un Dockerfile. |
| Las variables de entorno que hacen referencia a secretos están vacías | Los secretos deben existir antes de hacer referencia a ellos en variables de entorno. | Ejecute az containerapp secret set primero, luego az containerapp update para establecer las variables de entorno. Consulte el paso 4. |
| El aprovisionamiento de servicios de Azure tarda más de lo esperado | Los servicios administrados de Azure tienen tiempos de aprovisionamiento más largos que los complementos de Heroku. | Azure Cache for Redis: de 10 a 20 minutos. Servidor flexible de PostgreSQL: de 5 a 10 minutos. Aprovisione servicios en paralelo durante la implementación de la aplicación. |
| Los archivos escritos en tiempo de ejecución desaparecen después del reinicio | Container Apps usa un sistema de archivos efímero, similar a Heroku. | Monte un recurso compartido de Azure Files para el almacenamiento persistente. |
Limpieza de recursos
Si ha creado recursos específicamente para este tutorial de migración, elimine el grupo de recursos para quitar todos los recursos asociados y dejar de incurrir en cargos.
az group delete --name $RESOURCE_GROUP --yes --no-wait
Precaución
Este comando elimina el grupo de recursos y todos los recursos que contiene, incluidas las bases de datos, los registros de contenedor y las aplicaciones de contenedor. Esta acción no se puede deshacer.
Contenido relacionado
- Introducción a la migración de Heroku a Azure Container Apps
- Configuración de Azure Application Insights para la supervisión y las alertas
- Incorporación de Azure Front Door para CDN, WAF y equilibrio de carga global
- Uso de Dapr con Azure Container Apps para la comunicación de microservicios
- Documentación de Azure Container Apps