Cómo hacer Setup de E-commerce Full-Stack Profesional
Si alguna vez armaste un CRUD o seguiste tutorials básicos pero cuando te sentaste a hacer una app real se te desmoronó todo, este artículo es para vos. Te voy a guiar por los pasos concretos para montar un e-commerce full-stack profesional desde cero: backend, frontend, base de datos, Docker, todo junto. No es mágica, es arquitectura. Y funciona.
En 30 segundos
- Full-stack e-commerce significa construir backend (APIs), frontend (interfaz), y base de datos todo junto en un mismo proyecto, sin depender de plataformas como Shopify.
- Necesitás instalar Java 21, Node.js 20, Docker Desktop, y un IDE moderno (VSCode o IntelliJ) para empezar.
- La arquitectura típica tiene tres capas: frontend (React/Vue), backend (Express o Spring Boot), y datos (PostgreSQL + Redis + Elasticsearch).
- El setup debe incluir estructura de carpetas clara, variables de entorno, Docker Compose para orquestar servicios, y tests para verificar que todo habla entre sí.
- Un proyecto real como ShopFlow agrega complejidad: autenticación JWT, búsqueda con Elasticsearch, caché con Redis, pagos con Stripe, y event-driven processing con Kafka.
Qué es un setup full-stack de e-commerce y por qué no alcanza con Shopify
Un e-commerce full-stack es una aplicación donde vos construís el backend, el frontend y la integración de bases de datos desde cero, sin depender de plataformas cerradas como Shopify o WooCommerce. Significa que tenés control total sobre cada línea de código, cada endpoint, cada query. Es el camino que eligen las startups serias y las empresas que necesitan diferenciarse.
La diferencia con un constructor visual es obvia: con Shopify levantás una tienda en 20 minutos pero pagás comisión de transacción, estás atrapado en su ecosystem, y si necesitás algo custom, rezá. Con full-stack escribís código, tenés flexibilidad infinita, pero tenés que saber qué estás haciendo.
Si el 80% de las startups tech en algún punto necesita un e-commerce integrado en su stack, vos tenés que saber armarlo. No como expert, pero al menos el flujo básico: qué archivo va dónde, cómo el frontend habla con el backend, cómo Docker lo orquesta todo. Eso es lo que vamos a cubrir acá.
Step 1: Instalar las herramientas que necesitás
Antes de tocar código, tu máquina necesita cuatro cosas en versiones específicas. Versión importa. No es lo mismo Java 17 que Java 21, ni Node.js 18 que Node.js 20. Compatibility es frágil, así que pegá a lo que voy a decir.
Java 21: bajalo con SDKMAN (la forma inteligente de manejar versiones de Java). Abrís terminal y metés: Te puede servir nuestra cobertura de consideraciones de seguridad y privacidad.
curl -s "https://get.sdkman.io" | bash
sdk install java 21.0.1-oracle
java -versionEl último comando te muestra que instaló bien. Si ves “21.0” estás listo.
Node.js 20: Bajá de nodejs.org la versión LTS (Long Term Support). Una vez instalado, verificá con:
node -v
npm -vDocker Desktop: Es lo que va a orquestar tu aplicación. Bajalo de docker.com, instalá, y reiniciá. Verificá con:
docker -v
docker run hello-worldIDE: VSCode si preferís lightweight. IntelliJ IDEA si necesitás autocompletar inteligente (especialmente para Java). Ambos funcionan. El que uses va a ser tu home los próximos meses.
La arquitectura: tres capas que hablan entre sí
Cualquier e-commerce full-stack tiene tres capas separadas. No está todo mezclado en un monolito. Cada capa tiene su responsabilidad clara.
| Capa | Tecnología típica | Qué hace | Escucha en |
|---|---|---|---|
| Frontend | React, Vue, Svelte | Interfaz donde los usuarios ven productos, carrito, checkout. Llama APIs del backend | localhost:3000 |
| Backend | Express (Node), Spring Boot (Java), FastAPI (Python) | Procesa lógica: autenticación, validación de órdenes, pagos, búsqueda. Retorna JSON | localhost:8000 o 8080 |
| Base de datos | PostgreSQL (relacional), MongoDB (documento), Elasticsearch (búsqueda) | Guarda productos, usuarios, órdenes, inventario | localhost:5432 (Postgres) |

Un request típico: el usuario hace click en “comprar” en el frontend. El frontend envía un POST a `backend.com/api/orders` con los datos. El backend valida, guarda en la DB, retorna un JSON con el estado. El frontend renderiza “orden confirmada”. Así funciona.
En un proyecto de verdad como ShopFlow, se agrega complejidad: el backend habla con Elasticsearch para búsqueda rápida, con Redis para cachear datos calientes, con Stripe para pagos, con Kafka para procesar eventos asincronos (ej: “ordenaron → genera factura → envía mail”). Pero la idea base es la misma.
Estructura de carpetas: dónde va cada cosa
Si empezás sin una estructura clara, después te cuesta mover cosas. Así que definamos carpetas desde el día uno.
shopflow/
├── frontend/ # React o Vue app
│ ├── src/
│ │ ├── components/
│ │ ├── pages/
│ │ ├── services/ # Fetch calls al backend
│ │ └── App.jsx
│ ├── package.json
│ └── .env.local
├── backend/ # Node.js o Spring Boot
│ ├── src/
│ │ ├── routes/
│ │ ├── controllers/
│ │ ├── models/
│ │ └── index.js
│ ├── package.json
│ └── .env
├── docker-compose.yml # Orquesa servicios
├── .gitignore
└── README.mdConvenciones: backend usa camelCase en nombres de variables (`totalPrice`), frontend usa kebab-case en nombres de archivos (`product-card.jsx`). Las APIs siguen RESTful: GET `/api/products`, POST `/api/orders`, PUT `/api/users/:id`. Es lo que todo el mundo espera. Sobre eso hablamos en herramientas de inteligencia artificial.
En `.gitignore` mete siempre: `node_modules/`, `.env`, `*.log`, `dist/`, `build/`, `.DS_Store`. No subas credenciales a GitHub. La lección más cara se aprende solo una vez.
Configurar el backend: APIs que hablen
Voy a mostrar Node.js (es lo más rápido para empezar), pero lo mismo aplica con Spring Boot.
Crear un proyecto Express:
cd backend
npm init -y
npm install express cors dotenv
npm install --save-dev nodemonEl archivo `index.js` mínimo:
const express = require('express');
const cors = require('cors');
require('dotenv').config();
const app = express();
app.use(cors());
app.use(express.json());
// Endpoints básicos
app.get('/api/products', (req, res) => {
res.json([{ id: 1, name: 'Laptop', price: 999 }]);
});
app.post('/api/orders', (req, res) => {
const order = req.body;
console.log('Orden recibida:', order);
res.json({ id: 123, status: 'pending' });
});
app.listen(8000, () => console.log('Backend en puerto 8000'));
En `.env` del backend pones las credenciales (nunca hardcodeadas):
DB_HOST=localhost
DB_USER=root
DB_PASS=secret123
STRIPE_KEY=sk_test_xxxCuando crezcas, el backend hablará con PostgreSQL, tendrá autenticación JWT, validación de schemas con Joi o Zod. Pero esto es el esqueleto.
Configurar el frontend: React o Vue llamando al backend
Si usás Vite (más rápido que Create React App):
cd frontend
npm create vite@latest . -- --template react
npm install
npm install axiosUn componente que fetchea productos del backend:
import { useEffect, useState } from 'react';
import axios from 'axios';
export default function ProductList() {
const [products, setProducts] = useState([]);
useEffect(() => {
axios.get('http://localhost:8000/api/products')
.then(res => setProducts(res.data))
.catch(err => console.error(err));
}, []);
return (
<div>
{products.map(p => (
<div key={p.id}>
<h3>{p.name}</h3>
<p>${p.price}</p>
</div>
))}
</div>
);
}
Ojo: el backend necesita CORS habilitado (que ya pusimos con `app.use(cors())`) sino el frontend se queja de cross-origin. En producción configurás CORS más estricto, claro.
Docker: orquestar todo con un comando
Este es el punto donde muchos tutorials fallan. Porque en local funciona, pero cuando lo packeteás con Docker, las cosas se rompen. Ya lo cubrimos antes en elegir tu plataforma Git.
Dockerfile para el backend:
FROM node:20-alpine
WORKDIR /app
COPY package*.json .
RUN npm install
COPY . .
EXPOSE 8000
CMD ["npm", "start"]
Dockerfile para el frontend (con Nginx para servir estático):
FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json .
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Y el `docker-compose.yml` que lo une todo:
version: '3.8'
services:
frontend:
build: ./frontend
ports:
- "3000:80"
depends_on:
- backend
backend:
build: ./backend
ports:
- "8000:8000"
environment:
- NODE_ENV=development
- DB_HOST=postgres
depends_on:
- postgres
postgres:
image: postgres:15-alpine
environment:
POSTGRES_PASSWORD: secret123
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
postgres_data:
Con esto, levantás todo con un comando:
docker-compose up --buildFrontend en `localhost:3000`, backend en `localhost:8000`, PostgreSQL en `localhost:5432`. Todo conectado, todo con versiones fijas. Transportable a cualquier máquina o servidor que tenga Docker instalado.
Verificar que todo funciona antes de seguir
Una vez que levantaste con Docker Compose, hacé estas verificaciones:
- ¿El frontend carga en `localhost:3000`? Si ves la página, bien.
- ¿El backend responde? Abrís otra terminal: `curl http://localhost:8000/api/products`. Si ves JSON, bien.
- ¿El frontend puede llamar al backend? En la consola del navegador (F12 → Console) no debería haber errores CORS.
- ¿La base de datos persiste? Parás los containers con Ctrl+C, los levantás de nuevo, y si los datos siguen ahí, ganaste.
Si algo se rompe, debuggear es directo: `docker logs nombre_del_container` te muestra qué gritó. La mayoría de las veces es un typo en `.env` o un puerto que ya estaba ocupado.
Errores comunes en el setup
Credentials hardcodeadas en el código
Si metes la API key de Stripe directo en `index.js`, cuando subís a GitHub todo el mundo te ve la key. Game over. Siempre `.env` con `dotenv`. Punto.
CORS bloqueando el frontend
El backend dice “no, vos no podes hacer requests desde localhost:3000”. Solución: agregar `app.use(cors())` en Express, o configurar los headers en Spring Boot. Si omitís esto, pasás 4 horas en StackOverflow.
Services en docker-compose con nombres mal
En Docker, el backend no se llama `localhost` desde otro container (postgres o frontend). Se llama por el nombre del servicio en `docker-compose.yml`. Si tu DB_HOST es `postgres` en el yml pero en `.env` escribís `localhost`, no va a encontrar nada. Usa `postgres` en la config de Docker. Tema relacionado: extracción de datos con Python.
Ports ya ocupados
Si levantás Docker y te dice “puerto 8000 en uso”, algo más lo está usando (otro container, otra app). O cambias el puerto en docker-compose (`8001:8000`), o matás lo que esté usando 8000. En Windows, `netstat -ano | findstr :8000` te dice qué proceso lo tiene.
Preguntas Frecuentes
¿Node.js o Java para el backend?
Depende. Node.js (Express, Fastify, NestJS) es más rápido para empezar, sincronio-asincronismo integrado, ideal para startups. Java (Spring Boot) es más verbose pero más robusto a escala, mejor para empresas grandes. Para un first full-stack, Node.js es más gentle.
¿PostgreSQL o MongoDB?
PostgreSQL si tus datos son relacionales y previsibles (productos, usuarios, órdenes). MongoDB si son semi-estructurados y flexibles. Para e-commerce, PostgreSQL es lo estándar. Comenzá con eso.
¿Qué pasa si mi máquina no tiene 16GB de RAM?
Docker usa lo que necesita, pero si estás en una máquina vieja, Vite + Node + Postgres corriendo simultáneamente puede ser lento. Lo que hacen muchos: desarrollo local sin Docker (Node directo), Docker solo cuando testeas antes de producción.
¿Cómo agregó Elasticsearch o Redis después?
Igual que PostgreSQL: un servicio más en docker-compose.yml. El backend se conecta como lo hace con cualquier base de datos. Es modular, así que escalás sin refactorizar todo.
¿Dónde pongo los tests?
Backend: carpeta `tests/` o `__tests__/`, frameworks como Jest o Mocha. Frontend: test con Vitest o Jest. En docker-compose podés tener un servicio extra que solo corra tests. Pero eso es Step 2. Primero armá que funcione, después mejorá.
Conclusión
Setup full-stack de e-commerce no es mágico, es metodología. Instalás las herramientas correctas, estructurás las carpetas, separás las tres capas (frontend, backend, datos), las hacés hablar entre sí, y las empaquetás con Docker. De ahí en adelante, escalás: agregar autenticación JWT, Stripe para pagos, Elasticsearch para búsqueda, caché con Redis. Pero todo construido sobre esta base.
Lo importante ahora es que cuando termines este artículo, levantes el project en tu máquina, hagas click en el frontend, y veas que el backend responde. Eso es el aha moment. De ahí es solo construcción.
Si en tu equipo necesitan una tienda online profesional y personalizada (no Shopify), vos ya sabés el camino. Empezá por acá, construí con consistencia, y delegá a donweb.com si precisás infraestructura de hosting escalable para cuando estés listo para producción.






