Cómo Desplegar un Proyecto MERN en Railway

En este artículo veremos las formas más comunes de desplegar un proyecto del Stack MERN (MongoDB, Express, React y Node) en Railway, el cual es un servicio de la nube que se cataloga como un Platform as a Service (PaaS). Esto significa que basta con seleccionar el repositorio de código de tu proyecto y la plataforma desplegará todo de forma automática.

Requerimientos

Antes de empezar con el tutorial, es recomendable conocer los siguientes temas para poder entender este artículo:

  • Bases del Stack MERN: Es recomendable que sepas las bases de cómo crear una aplicación en el Stack MERN. Este artículo se enfoca en el despliegue y no en explicar el código. Es decir, para este tutorial es necesario que sepas:
    • Qué es una REST API y cómo crear una en Node.js con Express.
    • Qué es una base de datos MongoDB.
    • Qué es React y cómo crear aplicaciones básicas.

Además, necesitas contar con cuentas en las siguientes plataformas:

Precios

Al momento de escribir este tutorial, Railway ofrece un plan de $5 al mes para desplegar proyectos de backend, frontend y bases de datos. Este plan es suficiente para desplegar el ejemplo de este artículo. Ten en cuenta que Railway ya no ofrece un plan gratuito.

Despliegue Separado

Comencemos aprendiendo cómo desplegar una aplicación fullstack (backend y frontend) de forma separada. Este es, en mi opinión, el enfoque más fácil.

En resumen, el despliegue será el siguiente:

  1. Creación del proyecto de backend.
  2. Creación del proyecto de frontend.
  3. Configuración de CORS.
  4. Creación de repositorio para el backend.
  5. Despliegue del backend en Railway.
  6. Creación de la base de datos MongoDB en Railway.
  7. Creación de repositorio para el frontend.
  8. Despliegue del frontend en Railway.

Creación del Proyecto de Backend

Primero, crearemos el backend.

mkdir mern-stack-railway
cd mern-stack-railway
mkdir backend
cd backend

Inicializamos un proyecto de Node.js:

npm init -y

Instalamos las dependencias necesarias:

npm install express dotenv morgan mongoose
npm install nodemon -D

Creamos la estructura básica del proyecto:

mkdir models routes
touch index.js db.js models/user.js routes/user.routes.js .env .gitignore

Configura los siguientes archivos:

  • backend/.gitignore:

    node_modules
    .env
    
  • backend/.env: Contendrá las variables de entorno, por ejemplo:

    MONGO_URI=<tu_uri_de_mongodb>
    PORT=4000
    
  • backend/index.js:

    const express = require('express');
    const mongoose = require('mongoose');
    const morgan = require('morgan');
    const dotenv = require('dotenv');
    const userRoutes = require('./routes/user.routes');
    const connectDB = require('./db');
    
    dotenv.config();
    
    const app = express();
    const port = process.env.PORT || 4000;
    
    connectDB();
    
    app.use(morgan('dev'));
    app.use(express.json());
    app.use('/api/users', userRoutes);
    
    app.listen(port, () => {
      console.log(`Server running on port ${port}`);
    });
    
  • backend/db.js:

    const mongoose = require('mongoose');
    
    const connectDB = async () => {
      try {
        await mongoose.connect(process.env.MONGO_URI, {
          useNewUrlParser: true,
          useUnifiedTopology: true,
        });
        console.log('MongoDB connected');
      } catch (error) {
        console.error('Error connecting to MongoDB:', error.message);
        process.exit(1);
      }
    };
    
    module.exports = connectDB;
    
  • backend/models/user.js:

    const mongoose = require('mongoose');
    
    const userSchema = new mongoose.Schema({
      name: {
        type: String,
        required: true,
      },
      email: {
        type: String,
        required: true,
        unique: true,
      },
      password: {
        type: String,
        required: true,
      },
    });
    
    module.exports = mongoose.model('User', userSchema);
    
  • backend/routes/user.routes.js:

    const express = require('express');
    const router = express.Router();
    
    router.get('/', (req, res) => {
      res.send('User API');
    });
    
    module.exports = router;
    

Creación del Proyecto de Frontend

Ahora, crearemos el proyecto de React.

cd ..
npx create-react-app frontend

Realiza las configuraciones necesarias para que el frontend pueda comunicarse con el backend, como la configuración de CORS y las variables de entorno.

Creación de Repositorios en GitHub

Debido a que estamos trabajando con dos proyectos separados (frontend y backend), crea un repositorio para cada uno y súbelos a GitHub.

git init
git add .
git commit -m "Initial commit"
git remote add origin <tu_url_del_repositorio>
git push -u origin main

Despliegue del Backend en Railway

  1. Inicia sesión en Railway.
  2. Crea un nuevo proyecto.
  3. Conecta el repositorio del backend.
  4. Configura las variables de entorno desde el archivo .env.

Despliegue del Frontend en Railway

Sigue un procedimiento similar al del backend para desplegar el frontend.

Despliegue Conjunto

Aunque desplegar por separado es más sencillo, también puedes desplegar un proyecto MERN de forma conjunta, configurando un único repositorio con ambas partes. Para ello, necesitarás un Dockerfile o un archivo docker-compose.yml para administrar ambos servicios.

Subida de Imágenes

Si tu proyecto incluye subida de imágenes, considera usar servicios como AWS S3 o Cloudinary para almacenar los archivos. Configura las credenciales necesarias en tu archivo .env y asegura que el backend esté preparado para manejar dichas subidas.


¡Y eso es todo! Ahora tienes los pasos básicos para desplegar un proyecto MERN en Railway.