Virtualización

Publicado

Laboratorio multicloud local con Proxmox, Floci, AWS, Azure y Google Cloud

Manual para montar un laboratorio multicloud local con una VM en Proxmox, Docker, Floci AWS, Floci Azure, Floci GCP y Floci UI sin usar cuentas cloud reales.

1. Introducción

El objetivo de este laboratorio es disponer de un entorno local donde practicar conceptos y servicios de las principales plataformas cloud sin depender directamente de infraestructura real ni generar costes durante las pruebas.

El laboratorio utiliza:

  • Proxmox VE como plataforma de virtualización.
  • Ubuntu Server como sistema operativo de la máquina virtual.
  • Docker Engine y Docker Compose para ejecutar servicios.
  • Floci AWS para emular servicios de Amazon Web Services.
  • Floci Azure para emular servicios de Microsoft Azure.
  • Floci GCP para emular servicios de Google Cloud Platform.
  • Floci UI como interfaz web multicloud.
  • AWS CLI para interactuar con el entorno AWS emulado.

Arquitectura final:

Proxmox VE
└── VM cloud-lab
    ├── Ubuntu Server
    ├── Docker Engine
    ├── Docker Compose
    ├── Floci AWS
    │   ├── Interno TCP 4566
    │   └── Publicado TCP 14566
    ├── Floci Azure
    │   ├── Interno TCP 4577
    │   ├── Interno TCP 5672
    │   ├── Interno TCP 5673
    │   ├── Interno TCP 9093
    │   ├── Publicado TCP 14577
    │   ├── Publicado TCP 15672
    │   ├── Publicado TCP 15673
    │   └── Publicado TCP 19093
    ├── Floci GCP
    │   ├── Interno TCP 4588
    │   └── Publicado TCP 14588
    ├── Floci API
    │   ├── Interno TCP 4501
    │   └── Publicado TCP 14501
    └── Floci UI
        ├── Interno TCP 4500
        └── Publicado TCP 14500

Todos los componentes quedan accesibles desde otros dispositivos de la red local usando la IP reservada de la VM y los puertos publicados que defina cada instalación.

Antes de empezar: valores que debes cambiar

Por seguridad, los datos propios del entorno se han dejado anonimizados. Antes de ejecutar los comandos hay que sustituir estos valores por los reales de la instalación.

Valor en el manualQué debes poner
<VMID>ID libre de la VM en Proxmox, obtenido con pvesh get /cluster/nextid
<usuario>Usuario local creado durante la instalación de Ubuntu Server
<IP_VM>IP reservada para la VM en la LAN
local-lvmStorage de Proxmox donde se creará el disco de la VM
local:iso/ubuntu-server-amd64.isoRuta exacta de la ISO subida a Proxmox
vmbr0Bridge de red que usará la VM
enp6s18Nombre de la interfaz de red dentro de Ubuntu, si en tu caso aparece diferente

2. Recursos de la máquina virtual

Recursos utilizados en el laboratorio:

RecursoConfiguración
CPU4 vCPU
RAM10 GB
Disco100 GB
SistemaUbuntu Server LTS
BIOSOVMF / UEFI
Máquinaq35
ControladorVirtIO SCSI
RedVirtIO
QEMU Guest Agent

Para un laboratorio básico se podría usar menos memoria, pero 10 GB dan margen para varios runtimes, contenedores auxiliares, bases de datos, Functions/Lambda y una fase posterior con Kubernetes.

3. Comprobaciones previas en Proxmox

Comprobar almacenamientos:

pvesm status

Verificar que la ISO de Ubuntu esté disponible:

pvesm list local --content iso | grep ubuntu

Ejemplo anonimizado:

local:iso/ubuntu-server-amd64.iso

Comprobar el bridge de red:

ip link show vmbr0

Debe aparecer en estado:

UP

Obtener un VM ID disponible:

pvesh get /cluster/nextid

En el resto del manual se usa <VMID> como identificador genérico.

4. Crear la VM desde la consola de Proxmox

La VM se puede crear completamente por CLI:

qm create <VMID> \
  --name cloud-lab \
  --description "Laboratorio multicloud - Floci AWS Azure GCP" \
  --ostype l26 \
  --machine q35 \
  --bios ovmf \
  --cpu host \
  --sockets 1 \
  --cores 4 \
  --memory 10240 \
  --balloon 0 \
  --scsihw virtio-scsi-single \
  --scsi0 local-lvm:100,discard=on,iothread=1,ssd=1 \
  --efidisk0 local-lvm:1,efitype=4m,pre-enrolled-keys=1 \
  --ide2 local:iso/ubuntu-server-amd64.iso,media=cdrom \
  --net0 virtio,bridge=vmbr0,firewall=1 \
  --agent enabled=1 \
  --onboot 1 \
  --boot 'order=ide2;scsi0'

Comprobar la configuración:

qm config <VMID>

Arrancar la VM:

qm start <VMID>

Comprobar el estado:

qm status <VMID>

Resultado esperado:

status: running

5. Instalación de Ubuntu Server

Durante el instalador se usa Ubuntu Server.

Configuración recomendada:

  • Hostname: cloud-lab
  • Usuario: <usuario>
  • Disco: utilizar todo el disco
  • Red: DHCP inicialmente
  • OpenSSH Server: instalar

No es necesaria ninguna interfaz gráfica.

Cuando termine la instalación, apagar la VM y retirar la ISO desde Proxmox:

qm set <VMID> --delete ide2
qm set <VMID> --boot order=scsi0

Después se puede arrancar normalmente:

qm start <VMID>

6. Conexión mediante SSH

Consultar la IP asignada por DHCP dentro de la VM:

ip addr

La interfaz VirtIO puede aparecer como enp6s18 u otro nombre similar.

Desde otro equipo:

ssh <usuario>@<IP_VM>

<IP_VM> debe sustituirse por la IP reservada de la máquina virtual en la red local.

7. Actualizar Ubuntu

Actualizar repositorios:

sudo apt update

Actualizar paquetes:

sudo apt upgrade -y

8. Instalar QEMU Guest Agent

Instalar:

sudo apt install qemu-guest-agent -y

Comprobar:

systemctl status qemu-guest-agent --no-pager

Resultado esperado:

Active: active (running)

Esto mejora la integración entre Proxmox y la máquina virtual.

9. Configuración de red

Inicialmente Ubuntu utiliza DHCP.

Ejemplo de Netplan:

network:
  version: 2
  ethernets:
    enp6s18:
      dhcp4: true

En lugar de configurar una IP estática dentro de Ubuntu, se recomienda usar una reserva DHCP en el router:

MAC de la VM
└── Reserva DHCP
    └── IP estable para la VM

Ventajas:

  • Ubuntu sigue recibiendo gateway y DNS automáticamente.
  • Se evita mantener configuración manual de red dentro de la VM.
  • La dirección de la VM permanece estable.

Antes de modificar Netplan conviene crear una copia:

sudo cp /etc/netplan/50-cloud-init.yaml /etc/netplan/50-cloud-init.yaml.bak

En este laboratorio se mantiene:

dhcp4: true

10. Verificar hostname

Comprobar:

hostnamectl

El hostname utilizado es:

cloud-lab

Si hace falta modificarlo:

sudo hostnamectl set-hostname cloud-lab

También debe comprobarse:

cat /etc/hosts

La entrada correspondiente debe ser similar a:

127.0.1.1 cloud-lab

Si fuera necesario corregirla:

sudo sed -i 's/hostname-antiguo/cloud-lab/' /etc/hosts

11. Reinicio y validación

Reiniciar:

sudo reboot

Volver a acceder por SSH y comprobar:

hostnamectl
systemctl is-active qemu-guest-agent

Resultado esperado:

active

12. Instalación de Docker Engine

Se utiliza el repositorio oficial de Docker.

Instalar dependencias:

sudo apt update
sudo apt install ca-certificates curl -y

Crear el directorio de claves:

sudo install -m 0755 -d /etc/apt/keyrings

Descargar la clave:

sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc

Dar permisos de lectura:

sudo chmod a+r /etc/apt/keyrings/docker.asc

Crear el repositorio:

sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

Actualizar:

sudo apt update

Instalar Docker:

sudo apt install \
  docker-ce \
  docker-ce-cli \
  containerd.io \
  docker-buildx-plugin \
  docker-compose-plugin \
  -y

13. Comprobar Docker

Estado:

systemctl is-active docker

Resultado esperado:

active

Versión de Docker:

docker --version

Docker Compose:

docker compose version

14. Ejecutar Docker sin sudo

Añadir el usuario al grupo Docker:

sudo usermod -aG docker $USER

Actualizar la sesión:

newgrp docker

Comprobar:

groups

Debe aparecer el grupo:

docker

El grupo docker proporciona privilegios elevados sobre el sistema. Solo deben pertenecer a él usuarios de confianza.

15. Prueba de Docker

Ejecutar:

docker run --rm hello-world

Resultado esperado:

Hello from Docker!
This message shows that your installation appears to be working correctly.

16. Crear estructura del laboratorio

Crear directorios:

mkdir -p ~/floci/aws
mkdir -p ~/floci/azure
mkdir -p ~/floci/gcp

Crear una red Docker compartida:

docker network create floci_shared

Comprobar:

docker network ls | grep floci_shared

Esta red permitirá conectar:

Floci UI
└── Floci API
    └── floci_shared
        ├── AWS
        ├── Azure
        └── GCP

17. Floci AWS

Entrar en el directorio:

cd ~/floci/aws

Crear compose.yaml:

services:
  floci:
    image: floci/floci:latest
    container_name: floci-aws
    restart: unless-stopped
    ports:
      - "14566:4566"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./data:/app/data
    environment:
      FLOCI_STORAGE_MODE: hybrid
      FLOCI_STORAGE_PERSISTENT_PATH: /app/data
    networks:
      - default
      - floci_shared

networks:
  floci_shared:
    external: true

Validar:

docker compose config

Arrancar:

docker compose up -d

Comprobar:

docker ps --filter name=floci-aws

Debe aparecer en estado:

healthy

18. Comprobar Floci AWS

Endpoint de salud:

curl http://localhost:14566/_floci/health

La respuesta debe contener servicios en estado running.

Servicios habituales disponibles:

  • S3
  • EC2
  • Lambda
  • IAM
  • DynamoDB
  • SQS
  • SNS
  • RDS
  • ECS
  • EKS
  • CloudFormation
  • Route53
  • CloudFront
  • API Gateway
  • Secrets Manager
  • KMS

19. Instalar AWS CLI

Instalar unzip:

sudo apt install unzip -y

Descargar:

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" \
  -o awscliv2.zip

Descomprimir:

unzip awscliv2.zip

Instalar:

sudo ./aws/install

Comprobar:

aws --version

20. Perfil AWS exclusivo para Floci

Es importante no utilizar credenciales reales de AWS.

Crear un perfil exclusivo:

aws configure --profile floci

Usar valores de prueba:

AWS Access Key ID: test
AWS Secret Access Key: test
Default region: us-east-1
Output: json

Comprobar:

aws configure list --profile floci

21. Primera prueba AWS

Listar buckets:

aws \
  --endpoint-url=http://localhost:14566 \
  s3api list-buckets \
  --profile floci

Inicialmente debe devolver:

{
  "Buckets": []
}

Crear un bucket:

aws \
  --endpoint-url=http://localhost:14566 \
  s3 mb s3://laboratorio-floci-demo \
  --profile floci

Resultado esperado:

make_bucket: laboratorio-floci-demo

Esto confirma que AWS CLI está interactuando con Floci.

22. Floci Azure

Entrar:

cd ~/floci/azure

Crear compose.yaml:

services:
  floci-az:
    image: floci/floci-az:latest
    container_name: floci-azure
    restart: unless-stopped
    ports:
      - "14577:4577"
      - "15672:5672"
      - "15673:5673"
      - "19093:9093"
    volumes:
      - ./data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - default
      - floci_shared

networks:
  floci_shared:
    external: true

Validar:

docker compose config

Arrancar:

docker compose up -d

Comprobar:

docker ps --filter name=floci-azure

Debe aparecer en estado:

healthy

23. Validar Azure

Ejecutar:

curl http://localhost:14577/health

Respuesta esperada:

{
  "edition": "floci-az-always-free",
  "status": "UP"
}

24. Floci GCP

Entrar:

cd ~/floci/gcp

Crear compose.yaml:

services:
  floci-gcp:
    image: floci/floci-gcp:latest
    container_name: floci-gcp
    restart: unless-stopped
    ports:
      - "14588:4588"
    volumes:
      - ./data:/app/data
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - default
      - floci_shared

networks:
  floci_shared:
    external: true

Validar:

docker compose config

Arrancar:

docker compose up -d

25. Validar GCP

Comprobar el contenedor:

docker ps --filter name=floci-gcp

Debe mostrar:

healthy

Consultar salud:

curl http://localhost:14588/health

Servicios habituales disponibles:

  • BigQuery
  • Pub/Sub
  • GKE
  • IAM
  • Firestore
  • Cloud Functions
  • Cloud SQL
  • Cloud Storage
  • Cloud Run
  • Secret Manager
  • KMS
  • Cloud Tasks
  • Firebase Auth

26. Comprobar los tres runtimes

Ejecutar:

docker ps

Debe aparecer aproximadamente:

floci-aws      healthy
floci-azure    healthy
floci-gcp      healthy

Puertos publicados hacia la LAN:

ProveedorPuerto internoPuerto publicado
AWS456614566
Azure API457714577
Azure AMQP567215672
Azure AMQP TLS567315673
Azure Event Hub/Kafka909319093
GCP458814588

27. Acceso desde otros equipos de la LAN

Docker publica los puertos sobre 0.0.0.0, por lo que los runtimes pueden consultarse desde otros dispositivos de la misma red.

Ejemplos desde otro equipo de la LAN:

http://<IP_VM>:14566
http://<IP_VM>:14577
http://<IP_VM>:14588

Desde Windows:

curl.exe http://<IP_VM>:14566/_floci/health

Una respuesta HTTP 200 confirma el acceso desde la LAN.

No se recomienda publicar estos puertos directamente a Internet.

28. Instalar Floci UI

Clonar la interfaz oficial:

cd ~/floci
git clone https://github.com/floci-io/floci-ui.git ui

Entrar:

cd ui

Comprobar:

git status

29. Por qué no usar directamente el Compose oficial

El docker-compose.yml oficial puede levantar también runtimes propios para AWS, Azure y GCP.

En este laboratorio esos runtimes ya existen y sus puertos publicados están personalizados, así que se crea un Compose específico solo para:

  • Floci UI
  • Floci API

Ambos se conectan a los runtimes existentes mediante la red floci_shared.

30. Compose personalizado para Floci UI

Crear compose.external.yaml:

services:
  floci-ui:
    build:
      context: ./packages/frontend
      dockerfile: Dockerfile.dev
    container_name: floci-ui
    volumes:
      - ./packages/frontend/src:/app/src
      - ./packages/frontend/index.html:/app/index.html
      - ./packages/frontend/vite.config.ts:/app/vite.config.ts
      - ./packages/frontend/tsconfig.json:/app/tsconfig.json
      - ./packages/frontend/tsconfig.node.json:/app/tsconfig.node.json
    ports:
      - "14500:4500"
    environment:
      API_TARGET: http://floci-api:4501
      VITE_USE_POLLING: "true"
    depends_on:
      - floci-api
    networks:
      - floci_shared

  floci-api:
    build:
      context: ./packages/api
      dockerfile: Dockerfile.dev
    container_name: floci-api
    volumes:
      - ./packages/api/src:/app/src
    ports:
      - "14501:4501"
    environment:
      FLOCI_ENDPOINT: http://floci-aws:4566
      FLOCI_AZURE_ENDPOINT: http://floci-azure:4577
      FLOCI_GCP_ENDPOINT: http://floci-gcp:4588
      FLOCI_GCP_PROJECT: floci-local
      AWS_REGION: us-east-1
      AWS_ACCESS_KEY_ID: test
      AWS_SECRET_ACCESS_KEY: test
      PORT: "4501"
    networks:
      - floci_shared

networks:
  floci_shared:
    external: true

31. Validar Floci UI

Antes de ejecutar:

docker compose -f compose.external.yaml config

Esto ayuda a detectar:

  • errores YAML;
  • indentación incorrecta;
  • variables mal declaradas;
  • rutas inválidas.

32. Construir la interfaz

Ejecutar:

docker compose -f compose.external.yaml build

Resultado esperado:

Image ui-floci-api Built
Image ui-floci-ui Built

33. Arrancar Floci UI

Ejecutar:

docker compose -f compose.external.yaml up -d

Comprobar:

docker ps --filter name=floci-

La arquitectura queda:

floci-ui     LAN 14500 -> interno 4500
floci-api    LAN 14501 -> interno 4501
floci-aws    LAN 14566 -> interno 4566
floci-azure  LAN 14577 -> interno 4577
floci-gcp    LAN 14588 -> interno 4588

34. Acceder a Floci UI

Desde otro equipo:

http://<IP_VM>:14500

La interfaz permite cambiar entre:

  • AWS
  • Microsoft Azure
  • Google Cloud

y consultar diferentes servicios y recursos.

Panel de Floci UI mostrando el entorno local de AWS y servicios disponibles
Vista esperada de Floci UI al finalizar el laboratorio. En algunas ejecuciones la barra superior puede no reflejar correctamente el estado de conexión; si las pruebas por API responden como `reachable`, no afecta al funcionamiento del laboratorio.

35. Comprobar el proxy multicloud

La API de la interfaz permite validar cada proveedor.

AWS:

curl -s http://localhost:14500/api/clouds/aws/status

Azure:

curl -s http://localhost:14500/api/clouds/azure/status

GCP:

curl -s http://localhost:14500/api/clouds/gcp/status

Respuesta correcta:

{
  "adapterRegistered": true,
  "runtime": "reachable",
  "error": null
}

En el laboratorio se confirmó este estado en los tres proveedores.

36. Incidencia conocida de Floci UI

Durante las pruebas puede aparecer una discrepancia visual en la barra superior de Floci UI.

La interfaz puede mostrar:

No conectado

mientras que la API devuelve:

{
  "runtime": "reachable",
  "error": null
}

Si además se cumple lo siguiente:

  • los recursos pueden consultarse;
  • AWS CLI funciona;
  • cada endpoint runtime responde;
  • los tres contenedores están healthy;
  • el proxy de Floci UI accede correctamente a ellos;

entonces se considera una incidencia visual de la interfaz, no un problema de red ni de los runtimes.

No se recomienda modificar el código fuente de Floci UI solo para corregir ese indicador mientras el backend siga devolviendo reachable.

37. Estado final del laboratorio

Al terminar esta fase:

  • Ubuntu Server OK
  • SSH OK
  • QEMU Guest Agent OK
  • Reserva DHCP OK
  • Docker Engine OK
  • Docker Compose OK
  • Floci AWS OK
  • Floci Azure OK
  • Floci GCP OK
  • AWS CLI OK
  • S3 de prueba OK
  • Red Docker multicloud OK
  • Floci API OK
  • Floci UI OK
  • Acceso desde LAN OK

38. Próximas fases del laboratorio

A partir de aquí la infraestructura base permite comenzar con ejercicios reales.

AWS:

  • S3
  • IAM
  • EC2
  • VPC
  • Subnets
  • Security Groups
  • Lambda
  • DynamoDB
  • RDS
  • SQS
  • SNS
  • ECS
  • EKS
  • CloudFormation

Azure:

  • Resource Groups
  • Virtual Networks
  • Virtual Machines
  • Blob Storage
  • Azure Functions
  • Cosmos DB
  • Azure SQL
  • Key Vault
  • AKS
  • Service Bus
  • Event Hubs

Google Cloud:

  • Cloud Storage
  • Compute
  • VPC
  • IAM
  • Cloud Functions
  • Cloud Run
  • Firestore
  • BigQuery
  • Pub/Sub
  • Cloud SQL
  • GKE

Herramientas para fases posteriores:

  • Azure CLI
  • Google Cloud CLI
  • Terraform
  • OpenTofu
  • kubectl
  • Ansible
  • CI/CD

39. Seguridad del laboratorio

Al ser un entorno de aprendizaje es importante mantener varias precauciones:

  • No utilizar credenciales reales de AWS dentro de Floci.
  • No reutilizar contraseñas personales.
  • No publicar los puertos del laboratorio directamente a Internet.
  • Mantenerlo accesible únicamente desde la LAN o mediante una VPN.
  • No publicar IP internas reales, MAC, usuarios o contraseñas.
  • No mostrar tokens ni archivos ~/.aws/credentials.
  • Recordar que pertenecer al grupo docker concede privilegios elevados.
  • Realizar snapshots antes de experimentos importantes.

40. Prompt para pedir ayuda a una IA

El siguiente prompt sirve para pedirle a una IA que acompañe el montaje del laboratorio desde cero. Antes de usarlo, rellena los valores entre corchetes con los datos de tu entorno.

Actúa como un administrador de sistemas senior. Quiero que me guíes paso a paso para montar un laboratorio multicloud local en una VM de Proxmox VE usando Ubuntu Server, Docker, Docker Compose, Floci AWS, Floci Azure, Floci GCP, Floci UI y AWS CLI.

Objetivo:
- Crear una VM llamada cloud-lab.
- Instalar Ubuntu Server sin entorno gráfico.
- Instalar QEMU Guest Agent.
- Dejar la VM con DHCP y una reserva en el router.
- Instalar Docker Engine y Docker Compose.
- Crear una red Docker compartida llamada floci_shared.
- Levantar Floci AWS, Floci Azure y Floci GCP como runtimes locales.
- Levantar Floci UI y Floci API conectados a esos runtimes.
- Configurar AWS CLI con un perfil exclusivo llamado floci usando credenciales ficticias.
- Validar cada fase con comandos concretos.

Datos de mi entorno:
- ID de VM en Proxmox: [ESCRIBE_AQUI_EL_VMID]
- Nombre de la VM: cloud-lab
- Usuario Linux: [ESCRIBE_AQUI_EL_USUARIO]
- IP reservada de la VM: [ESCRIBE_AQUI_LA_IP_VM]
- Bridge de red Proxmox: [ESCRIBE_AQUI_EL_BRIDGE, por ejemplo vmbr0]
- Storage para disco: [ESCRIBE_AQUI_EL_STORAGE, por ejemplo local-lvm]
- Storage de ISO: [ESCRIBE_AQUI_EL_STORAGE_ISO, por ejemplo local]
- Nombre exacto de la ISO: [ESCRIBE_AQUI_EL_NOMBRE_DE_LA_ISO]
- Interfaz de red dentro de Ubuntu, si ya la conozco: [ESCRIBE_AQUI_LA_INTERFAZ, por ejemplo enp6s18]

Usa estos puertos de ejemplo para publicar los servicios en la LAN:
- Floci AWS: 14566 hacia el puerto interno 4566.
- Floci Azure API: 14577 hacia el puerto interno 4577.
- Floci Azure AMQP: 15672 hacia el puerto interno 5672.
- Floci Azure AMQP TLS: 15673 hacia el puerto interno 5673.
- Floci Azure Event Hub/Kafka: 19093 hacia el puerto interno 9093.
- Floci GCP: 14588 hacia el puerto interno 4588.
- Floci API: 14501 hacia el puerto interno 4501.
- Floci UI: 14500 hacia el puerto interno 4500.
- Si alguno está ocupado, proponme otro puerto libre y actualiza todos los comandos relacionados.

Condiciones de seguridad:
- No debo usar credenciales reales de AWS, Azure ni Google Cloud.
- No debo exponer puertos directamente a Internet.
- Los servicios solo deben quedar accesibles desde la LAN o por VPN.
- No debo publicar IPs reales, MAC, UUID, Machine ID, Boot ID, usuarios reales, contraseñas ni tokens.
- Si preparo documentación pública, ayúdame a sustituir los datos sensibles por valores ficticios o placeholders.

Forma de respuesta que necesito:
- Divide el trabajo por fases.
- En cada fase dame comandos listos para copiar y pegar.
- Después de cada bloque de comandos añade cómo comprobar si salió bien.
- Si un comando usa un placeholder, explícame qué valor debo poner ahí.
- Incluye los docker compose completos para AWS, Azure, GCP, Floci UI y Floci API.
- Incluye pruebas con curl, docker ps y AWS CLI.
- Añade una sección de problemas conocidos. En concreto, explica que Floci UI puede mostrar un estado visual incorrecto en la barra superior, pero que si la API devuelve runtime reachable, los contenedores están healthy y los recursos se consultan, el laboratorio funciona correctamente.