Ir al contenido

Buscar en la documentación

Busca en la documentación de Skiffly

Migrar desde Railway

Los conceptos se corresponden uno a uno, la mayoría de los documentos de la API funcionan sin cambios y los comandos de la CLI tienen los mismos nombres. Qué cambiar, en orden.

Correspondencia de conceptos#

RailwaySkifflyNotas
Espacio de trabajo / equipoEspacio de trabajoroles owner, admin, member; sin grupos de acceso
Proyecto → Entorno → Servicioiguallos entornos de PR son pr-<n> y se activan por proyecto
Origen del servicio: repositorio, imagenigualregistries privados aún no soportados
Railpack / Nixpacks / DockerfileRailpack / Dockerfilelos proyectos con Nixpacks se compilan con Railpack o con un Dockerfile
${{Postgres.DATABASE_URL}}, ${{shared.VAR}}misma sintaxis
RAILWAY_PUBLIC_DOMAIN, RAILWAY_PRIVATE_DOMAIN, …SKIFFLY_PUBLIC_DOMAIN, SKIFFLY_PRIVATE_DOMAIN, …ver variables integradas
Red privada service.railway.internal<service-slug> (http://api:8080)IPv4, solo dentro del mismo entorno
Dominio generado *.up.railway.app*.skiffly.cloud
Dominio propio: CNAME + verificaciónCNAME a edge.skiffly.cloud + TXT _skiffly.<host>
Proxy TCPProxy TCP (edge.skiffly.cloud:2xxxx)skiffly proxy, skiffly connect
VolúmenesVolúmenesuna réplica por servicio con volumen; respaldos diarios
Programación cronProgramación cron
App SleepingApp Sleeping~10 min de inactividad
Ruta del health checkRuta del health checkhasta 5 min de arranque
Réplicas, regionesRéplicashoy solo UE
Cambios preparados → Desplegarno existenlos cambios se aplican de inmediato; vuelve a desplegar cuando haga falta
Facturación por uso, facturaFacturación por uso, saldo prepagoPayPal o cripto; 3 días de gracia y luego pausa
CLI railwayCLI skifflymismos nombres de comando cuando la función existe
Servidor MCP de RailwayServidor MCP de Skifflymismos nombres de herramienta cuando la función existe
railway/iac (defineRailway)@skiffly/config (defineSkiffly)buscar y reemplazar
PlantillasPlantillas136 en el catálogo, templateDeployV2
Observabilidad: logs, métricasLogs (búfer de 5 000 líneas), métricas (7 días)todavía sin log drains
Webhooks, funciones, buckets, sandboxesno disponibles

Importar con la CLI: skiffly import --from-railway#

La CLI (o la herramienta MCP import_from_railway) lee tu proyecto de Railway a través de la API pública de Railway y lo recrea en Skiffly de una sola vez, así que los pasos 2, 4, 5 y la mayor parte del 6 de abajo ocurren automáticamente. Necesitas un token de cuenta de Railway (un token de espacio de trabajo también sirve); solo se usa para leer y no se guarda.

skiffly login
skiffly import --from-railway --dry-run          # elige el proyecto de Railway, previsualiza el plan
skiffly import --from-railway                    # aplicar: crea un proyecto nuevo en Skiffly (o --project <id|name>)

Flags: --railway-token <t> (o RAILWAY_TOKEN), --railway-project <id> (el id de la URL del panel de Railway o de railway status), --project <id|name|new> y --workspace <w> para el destino en Skiffly, --environment <name> para importar un solo entorno, --dry-run, --yes, --json.

Qué se importa, por entorno (los entornos de PR se omiten):

RailwaySkiffly
EntornosEntornos con el mismo nombre (production se corresponde con el de producción del proyecto)
Servicios desde un repositorio de GitHub: rama, directorio raíz, ruta del Dockerfile, comando de buildserviceCreate con el mismo origen y builder (RAILPACK, o DOCKERFILE cuando hay una ruta de Dockerfile definida); los builds con Nixpacks/Heroku/Paketo pasan a Railpack
Servicios desde una imagen DockerServicio de imagen; el puerto se deduce de PORT o de la imagen (Postgres 5432, Redis 6379, …)
Comando de inicio, health check, programación cron, réplicas, app sleepingserviceInstanceUpdate por entorno
Variables (por servicio y compartidas), sin renderizarSe copian conservando las referencias ${{Service.VAR}} y ${{shared.VAR}}; RAILWAY_PUBLIC_DOMAIN, RAILWAY_PRIVATE_DOMAIN, RAILWAY_ENVIRONMENT, … dentro de las referencias pasan a SKIFFLY_*; las variables RAILWAY_* en sí no se copian
VolúmenesSe crean vacíos en la misma ruta de montaje (tamaño redondeado hacia arriba a GB enteros)
Dominios propiosSe adjuntan al servicio; se imprimen el CNAME y el registro TXT _skiffly
Proxies TCPSe recrean en edge.skiffly.cloud con un puerto nuevo

No se importa: el contenido de volúmenes y bases de datos, los dominios *.up.railway.app generados por Railway, los comandos pre-deploy, el historial de despliegues, las credenciales de registries privados, railway.json/railway.toml (se usan en su lugar los valores de la instancia del servicio). Los servicios que ya existen por nombre en el proyecto destino se dejan intactos. No se despliega nada: los servicios se crean con los despliegues desactivados para que puedas revisar las variables primero.

El comando termina con una tabla de lo creado y una lista Hazlo a mano, normalmente:

  • copiar los datos de bases de datos/volúmenes (pg_dump en Railway → skiffly connect <service> / skiffly ssh para restaurar; ver el paso 3);
  • crear los registros DNS de cada dominio propio (skiffly domain status <domain> los muestra) y luego quitar el dominio de Railway;
  • actualizar los clientes de los proxies TCP al nuevo host:puerto (skiffly proxy list) y las variables que referenciaban RAILWAY_TCP_PROXY_*;
  • definir cualquier variable que referenciara una variable integrada exclusiva de Railway; mover los comandos pre-deploy al comando de inicio;
  • skiffly link <projectId> y luego skiffly up / skiffly redeploy -s <service> por servicio, manteniendo Railway en marcha hasta que Skiffly esté saludable.

Desde un agente de IA: la herramienta import_from_railway del servidor MCP de Skiffly acepta los mismos parámetros (railwayToken, railwayProjectId, projectId o createProjectName, environment, dryRun) y devuelve el mismo informe.

Paso a paso#

  1. Inicia sesión en app.skiffly.dev con GitHub, instala la GitHub App para los repositorios privados y recarga el saldo.

  2. Exporta las variables de Railway: railway variables --kv > vars.env por servicio. Elimina las entradas RAILWAY_*; reemplaza las referencias a variables provistas por Railway con los equivalentes SKIFFLY_*.

  3. Primero las bases de datos. Despliega la plantilla (skiffly deploy --template postgres) y luego mueve los datos a través de un proxy TCP:

    # Lado de Railway
    pg_dump "$RAILWAY_DATABASE_URL" -Fc -f db.dump
    # Lado de Skiffly
    skiffly connect postgres --print          # imprime la URL; crea el proxy en el primer uso
    pg_restore -d "<url from --print>" --no-owner --clean --if-exists db.dump
    skiffly proxy delete <port>               # cierra el puerto público al terminar

    Redis y Mongo: redis-cli --rdb/mongodump y la restauración correspondiente a través de skiffly connect.

  4. Servicios. skiffly init en cada repositorio y luego skiffly up. Define las variables:

    skiffly variables set --skip-deploys $(grep -v '^RAILWAY_' vars.env | xargs)
    skiffly variables set 'DATABASE_URL=${{Postgres.DATABASE_URL}}'
    skiffly redeploy

    O describe todo una sola vez en .skiffly/skiffly.ts y ejecuta skiffly config apply; un railway.ts de Railway se porta con defineRailwaydefineSkiffly.

  5. La configuración que Railway guardaba en railway.json/railway.toml (comando de build, comando de inicio, health check, política de reinicio, cron, patrones de watch) va en el servicio: update-service en MCP, serviceInstanceUpdate en GraphQL o el archivo de configuración. Skiffly no lee railway.json.

  6. Dominios. Genera un dominio skiffly.cloud para probar, luego agrega el dominio propio y cambia el CNAME cuando se emita el certificado. Mantén el servicio de Railway en marcha hasta que el DNS se haya propagado.

  7. Clientes de la API. Cambia el endpoint a https://api.skiffly.dev/graphql y el token. Los documentos que usan projects, deployments(input:), variables, serviceInstanceUpdate, serviceInstanceDeployV2, customDomainCreate, templateDeployV2 y los demás campos compatibles funcionan tal cual; buildLogs pasa a ser deploymentLogs filtrado por stream.

  8. Automatización. Las GitHub Actions que ejecutaban railway up ejecutan npx skiffly up (o skiffly config apply --yes) con SKIFFLY_TOKEN.

Qué revisar antes de hacer el cambio#

  • La app escucha en $PORT (Skiffly lo define; 8080 por defecto si no configuras ninguno).
  • Nada depende de los hostnames *.railway.internal ni de la red privada IPv6.
  • El SMTP saliente por el puerto 25 está bloqueado; usa el 587 con autenticación o una API de correo.
  • Límites del plan: Hobby permite 8 GiB / 8 vCPU por servicio, Pro 32 GiB / 32 vCPU. Free es un solo servicio.
  • Entornos de vista previa: activa las vistas previas de PR por proyecto; los forks se ignoran.