Deploy de un proyecto en Flask o FastAPI en Railway

Video thumbnail

Desplegar una aplicación Flask o FastAPI no tiene por qué ser complicado. En esta guía te explico cómo hacerlo utilizando Railway, una plataforma moderna que simplifica el proceso de deployment en la nube. Si ya trabajaste con Django, notarás que el flujo es muy similar, solo que con algunos ajustes específicos para Flask y FastAPI.

Railway permite conectar tu repositorio de GitHub, crear bases de datos y desplegar tu app en minutos. Yo he usado este servicio varias veces, incluso con el plan gratuito, y puedo decirte que es una de las opciones más sencillas para proyectos pequeños o pruebas en producción.

Qué es Railway y por qué usarlo para tus apps Flask o FastAPI

Railway es una plataforma de despliegue continuo que permite alojar aplicaciones web, APIs y bases de datos sin preocuparte por la infraestructura. Todo se gestiona desde un panel muy intuitivo o desde su CLI.

En este artículo hablamos más sobre que es Railway.

Preparación del proyecto en local

Antes de desplegar, asegúrate de tener tu entorno configurado correctamente.

Requisitos previos y entorno virtual

Crea un entorno virtual y verifica que tu aplicación Flask o FastAPI funciona localmente. Esto evitará errores durante el despliegue.

Configuración del archivo requirements.txt

Asegúrate de incluir todas las dependencias del proyecto. En mi caso, agregué Uvicorn, el servidor web que uso en producción. Railway instala automáticamente lo que encuentre en este archivo.

Ejemplo de requirements.txt:

flask
fastapi
uvicorn
gunicorn
sqlalchemy

Servidor de producción con Uvicorn para Flask

Para producción, define el comando que ejecutará la aplicación. Railway asigna automáticamente el puerto, así que no lo declares manualmente:

uvicorn app:app --host=0.0.0.0 --port=${PORT}

Hasta ahora, hemos empleando un servidor de desarrollo, lo cual queda perfectamente claro al momento de ejecutar una aplicación en Flask:

$ python run.py         
***
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
***

Debemos de instalar alguno para producción; para Python web, gunicorn es usualmente una excelente opción:

$ pip install gunicorn

Railway necesita un Procfile para saber cómo ejecutar tu app, este archivo indica a plataformas de despliegue como Tailway o Heroku por nombrar algunas, como desplegar la aplicación, es decir, como arrancar la app, en este caso, el comando del servidor web instalado:

web: gunicorn -b 0.0.0.0:$PORT run:app

Con el comando anterior, ejecutamos la aplicación llamada run.py (run:app) con gunicorn en el puerto expuesto de manera dinámica en la variable de entorno creada por Raywail $POST en cualquier IP asignada por Railway (0.0.0.0) -escucha en todas las interfaces de red disponibles dentro del contenedor y no solo en localhost-. el -b es solo para hacer un enlace a la IP y puerto anterior.

Servidor de producción con Uvicorn para FastAPI

Video thumbnail

 diferencia de Flask que es un framework WSGI y no ASGI y es por eso que en el caso de Flask basta con instalar solamente Gunicorn, en FastAPI es un framework ASGI y no WSGI, así que, necesitamos instalar también Uvicorn:

$ pip install uvicorn

Se usan Gunicorn y Uvicorn juntos porque cada uno cumple un rol distinto y complementario: Uvicorn es el servidor ASGI que ejecuta directamente la aplicación FastAPI, mientras que Gunicorn actúa como un gestor de procesos que lanza y supervisa múltiples instancias (workers) de Uvicorn para aprovechar varios núcleos del servidor. En producción, esta combinación permite manejar más tráfico simultáneamente, reiniciar workers fallidos y mantener la aplicación estable y eficiente.

Railway necesita un Procfile para saber cómo ejecutar tu app, este archivo indica a plataformas de despliegue como Tailway o Heroku por nombrar algunas, como desplegar la aplicación, es decir, como arrancar la app, en este caso, el comando del servidor web instalado:

web: gunicorn -k uvicorn.workers.UvicornWorker -b 0.0.0.0:$PORT api:app

Con el comando anterior, ejecutamos la aplicación llamada run.py (api:app) con gunicorn en el puerto expuesto de manera dinámica en la variable de entorno creada por Raywail $POST en cualquier IP asignada por Railway (0.0.0.0) -escucha en todas las interfaces de red disponibles dentro del contenedor y no solo en localhost-. el -b es solo para hacer un enlace a la IP y puerto anterior.

-k uvicorn.workers.UvicornWorker

  • Indica a Gunicorn que use Uvicorn como worker.
  • Necesario porque FastAPI es ASGI y Gunicorn por sí solo no entiende ASGI.
  • Uvicorn ejecuta tu app FastAPI y Gunicorn la gestiona como múltiples procesos.

El archivo Procfile debe estar ubicado dentro de la carpeta del proyecto (al mismo nivel que el run.py).

Configuración de base de datos

En este apartado, configuraremos la base de datos, esto lo tienes que hacer si el proyecto es en Flask o FastAPI, el único cambio que hay en el deploy es al momento de configurar gunicorn que fue lo mostrado anteriormente.

Por qué usar SQLite en el plan gratuito

En el plan gratuito, los servicios “duermen” cuando no se usan. Esto puede generar errores 500 si la base de datos también se suspende. Por eso recomiendo usar SQLite: evita esos errores y no depende de servicios externos.

Alternativas con PostgreSQL o MySQL

Si tu aplicación necesita bases de datos más robustas, Railway ofrece instancias gratuitas de PostgreSQL y MySQL. Solo asegúrate de incluir las migraciones y subirlas a GitHub para que Railway las ejecute correctamente.

Migraciones y sincronización del esquema

Railway no permite subir directamente archivos SQL para ejecutar migraciones, así que deberás hacerlo mediante comandos. Si usas SQLAlchemy o Alembic, bastará con correr los comandos desde la CLI de Railway.

Conexión del proyecto con Railway

En este artículo, explicamos como hacer el deploy de un proyecto en Django en Railway, específicamente de allí tienes que consultar el apartado de crear la base de datos (si así lo quieres) y de crear el contenedor para la app; son exactamente los mismos pasos, desde crear el contenedor, integrar GitHub…

Instalación y autenticación Railway CLI

Railway CLI es la herramienta de línea de comandos de Railway, que te permite gestionar los proyectos y servicios directamente desde la terminal, sin depender del panel web.

Instala la CLI de Railway con Node.js o Brew (en macOS):

$ npm i -g @railway/cli

Inicia sesión con:

$ railway login

Enlazar proyecto y ejecutar comandos

Para trabajar directamente desde tu máquina dentro del entorno remoto, enlaza tu proyecto:

$ railway link

Esto te permitirá ejecutar comandos en el contenedor de producción.

Aplicar migraciones en producción; para ello, primero, configura EN LOCAL, tus configuraciones de producción:

mysql+pymysql://root:twgYYhRdwy***lUUe@mysql.railway.internal:3306/railway

Con el proyecto enlazado, ejecuta los comandos habituales de tu framework. Por ejemplo, si usas Flask-Migrate o Alembic:

python -m app db init
python -m app db migrate
python -m app db upgrade

Si NO vas a usar SQLite, si vas a usar SQLite

Puedes usar la base de datos en SQLite pero con limitaciones importantes como que la misma será sobrescrita cada vez que hagas un nuevo deploy desde Railway; esto no es un problema si simplemente quieres usar la aplicación como una demo o para presentar a un cliente y con esto, puedes saltar la creación del contenedor de la base de datos y el uso de Railway CLI para ejecutar las migraciones; para ello, lo que debes de hacer es quitar 

.gitignore

# Ignorar base de datos SQLite
*.sqlite3
*.db

Y sincronizar en GitHub:

$ git add db.sqlite3
$ git commit -m "Agrego base de datos SQLite"
$ git push origin main

Es importante aclarar que usualmente NO se recomienda sincronizar la base de datos de SQLite en GitHub para evitar conflictos, por lo tanto, luego, puedes luego revertir estos cambios una vez sincronizado.

Una vez hecho esto, aplicas los siguientes cambios en el proyecto:

SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(basedir, "dev.db")

Si ya subiste el archivo db.sqlite3 antes

Git seguirá rastreándolo, aunque lo pongas en .gitignore,
porque ya está en el historial.
Para dejar de rastrearlo, haz esto:

git rm --cached db.sqlite3

Y luego haz commit:

$ git commit -m "Dejo de rastrear db.sqlite3 y lo agrego al .gitignore"
$ git push

Conclusión

El proceso de deployment de Flask y FastAPI en Railway es casi idéntico al de Django: basta con preparar el archivo requirements.txt, configurar las variables de entorno, conectar el repositorio de GitHub y lanzar la app con Uvicorn. La ventaja es que Railway simplifica los pasos y ofrece un plan gratuito con muy buena integración.

Personalmente, me ha resultado una herramienta ágil, especialmente para prototipos y proyectos personales. Con un poco de organización y las migraciones listas, puedes tener tu API o app web en línea en cuestión de minutos.

Preguntas frecuentes (FAQs)

¿Puedo desplegar Flask y FastAPI en el mismo entorno?
Sí, siempre que cada servicio se ejecute en un contenedor distinto o con rutas separadas.

¿Railway es mejor que Render o Heroku para apps pequeñas?
Para proyectos personales o educativos, Railway suele ser más rápido de configurar y ofrece un plan gratuito más estable.

¿Cómo escalar una app en el plan gratuito?
Puedes aumentar el plan o dividir la aplicación en microservicios, aunque el plan gratuito está pensado para uso ligero. 

Acepto recibir anuncios de interes sobre este Blog.

Mostramos los pasos para hacer el deploy de un proyecto en Flask y FastAPI en Railway.

| 👤 Andrés Cruz

🇺🇸 In english