Documentación
Guía de instalación
Instala Café del Tiempo en tu propio servidor, con Docker o de forma manual. Todo el código es abierto (MIT) y es el mismo que corre en la versión alojada.
Elige cómo instalar #
Hay dos caminos. Ambos instalan la misma aplicación; cambia cómo se ejecuta.
Recomendado para servidores
Docker
PostgreSQL, Nginx, cola y tareas programadas vienen listos en docker-compose.yml. En el servidor solo necesitas Docker y Git.
Desarrollo o servidor propio
Manual
Instalas PHP, Composer y Node.js tú mismo. Ideal para probar en tu máquina con SQLite o para servidores que ya tienen PHP.
Instalar manualmente →Requisitos #
Con Docker
- Docker Engine con el plugin Docker Compose (el comando es
docker compose, con espacio). - Git, para clonar y actualizar el repositorio.
- No necesitas PHP, Composer ni Node.js en el servidor: viven en las imágenes, y los assets compilados (
public/build) vienen en el repositorio.
Instalación manual
| Componente | Versión | Notas |
|---|---|---|
| PHP | 8.3 o superior | Extensiones: mbstring, bcmath, intl, gd, zip, exif, pcntl, pdo_sqlite o pdo_pgsql, más las que Laravel trae por defecto (ctype, fileinfo, openssl, tokenizer, xml, curl). |
| Composer | 2.x | Gestor de dependencias de PHP. |
| Node.js | 20.19+ o 22.12+ | Solo para compilar los assets con Vite. |
| Base de datos | SQLite 3 o PostgreSQL 16 | SQLite viene por defecto y basta para uso personal. PostgreSQL es la opción para producción. |
Servidor
Para uso personal o familiar basta un VPS pequeño: 1–2 vCPU, 2 GB de RAM y 10 GB de disco son una referencia orientativa. Si vas a abrir el registro a más personas, planea más memoria.
Instalación con Docker #
El stack levanta cinco servicios: app (PHP-FPM), nginx (expone el puerto 9000), postgres, queue (worker de colas) y scheduler (tareas programadas).
1. Clona el repositorio
git clone https://github.com/xenthrall/cafe-del-tiempo.git
cd cafe-del-tiempo
2. Crea el archivo de entorno
Usa la plantilla pensada para Docker, no .env.example:
cp .env.docker.example .env
Edita .env y ajusta al menos APP_URL, DB_PASSWORD y APP_INSTANCE. Tienes el detalle de cada variable en Configuración del entorno.
3. Genera la clave de la aplicación
Genera la clave desde el host y pégala en APP_KEY. Así evitas problemas de permisos al escribir el .env desde el contenedor.
echo "base64:$(openssl rand -base64 32)"
4. Construye y levanta los servicios
docker compose build
docker compose up -d
docker compose ps
Al arrancar, el contenedor app espera a PostgreSQL y optimiza Laravel. Revisa que no haya errores con docker compose logs -f app.
5. Ejecuta las migraciones
Las migraciones no corren solas al arrancar, a propósito. Ejecútalas la primera vez y en cada actualización:
docker compose exec app php artisan migrate --force
6. Crea tu usuario administrador y entra
docker compose exec app php artisan user:create --admin
Abre http://TU_IP:9000/app e inicia sesión. Más opciones del comando en Tu primer usuario.
Instalación manual #
En tu máquina (desarrollo o prueba)
Con SQLite no necesitas configurar ninguna base de datos:
git clone https://github.com/xenthrall/cafe-del-tiempo.git
cd cafe-del-tiempo
composer install && npm install
cp .env.example .env && php artisan key:generate
php artisan migrate
npm run build
php artisan serve
Abre http://localhost:8000/app. Para desarrollar con recarga automática, usa composer run dev en lugar de php artisan serve.
En un servidor sin Docker
- Apunta tu servidor web (Nginx, Apache o Caddy) a la carpeta
public/del proyecto. - Instala dependencias sin paquetes de desarrollo:
bash
composer install --no-dev --optimize-autoloader npm ci && npm run build - Configura el
.envconAPP_ENV=production,APP_DEBUG=falsey tu base de datos (ver configuración). - Migra y optimiza:
bash
php artisan migrate --force php artisan optimize - Da permisos de escritura al usuario del servidor web sobre
storage/ybootstrap/cache/. - Configura el worker de colas y las tareas programadas, como se explica en Colas y tareas programadas.
Configuración del entorno #
Estas son las variables del .env que conviene revisar. El resto de valores de las plantillas ya funcionan tal cual.
| Variable | Qué poner |
|---|---|
APP_URL | La URL pública real, con su esquema: https://tu-dominio o http://TU_IP:9000. |
APP_KEY | Clave con la que Laravel firma sesiones y cookies. Genérala una vez y no la cambies: al hacerlo se cierran todas las sesiones. |
APP_ENV / APP_DEBUG | production y false en cualquier servidor accesible desde internet. |
APP_INSTANCE | self-hosted (por defecto): registro cerrado, las cuentas las crea un administrador. hosted: cualquiera puede registrarse. |
APP_LOCALE | es para la interfaz en español. |
DB_CONNECTION y DB_* | sqlite o pgsql. Con Docker deja DB_HOST=postgres y define una DB_PASSWORD fuerte. |
SESSION_SECURE_COOKIE | true si sirves la app por HTTPS. |
QUEUE_CONNECTION | database, ya configurado. Requiere un worker activo. |
R2_PRIVATE_* | Credenciales del bucket privado de Cloudflare R2 (o compatible con S3) donde se guardan los respaldos. |
Tu primer usuario #
Crea usuarios desde la terminal con user:create (en Docker, antepone docker compose exec app). El comando pide nombre, correo y contraseña:
php artisan user:create --admin
- Con
--admin, el usuario entra al panel personal (/app) y al de administración de la instancia (/system). - Sin
--admin, solo entra a/app. - Puedes pasar
--namey--emailpara no escribirlos en el prompt. La contraseña siempre se pide de forma interactiva, para que no quede en el historial de la terminal.
Desde /system también puedes crear las cuentas del resto de personas sin abrir el registro público.
Colas y tareas programadas #
La aplicación necesita dos procesos en segundo plano: un worker de colas y el programador de tareas, que ejecuta los respaldos diarios. Con Docker ya corren en los servicios queue y scheduler.
En una instalación manual, mantén el worker activo con Supervisor o systemd:
php artisan queue:work --tries=3 --timeout=90
Y agrega el programador al cron del usuario del servidor web:
* * * * * cd /ruta/a/cafe-del-tiempo && php artisan schedule:run >> /dev/null 2>&1
Dominio y HTTPS #
Pon un proxy inverso con HTTPS delante del puerto de la aplicación: Caddy, Nginx, Traefik o un túnel como Cloudflare Tunnel. La aplicación ya confía en las cabeceras X-Forwarded-* del proxy, así que solo tienes que:
- Poner
APP_URL=https://tu-dominio. - Poner
SESSION_SECURE_COOKIE=true. - Reiniciar:
docker compose up -d.
Respaldos #
La aplicación respalda la base de datos todos los días a las 02:00 y limpia los respaldos antiguos a la 01:30. Los archivos se suben al disco r2_private, así que necesitas configurar las variables R2_PRIVATE_*.
- Solo se respalda la base de datos: el código ya está en Git, y respaldar archivos incluiría el
.envcon tus credenciales. - Guarda una copia del
.envfuera del servidor: el respaldo no la incluye. - Para probar la configuración, lanza un respaldo manual:
php artisan backup:run --only-db.
Actualizar #
Con Docker:
git pull origin main
docker compose up -d --build
docker compose exec app php artisan migrate --force
En una instalación manual:
git pull origin main
composer install --no-dev --optimize-autoloader
npm ci && npm run build
php artisan migrate --force
php artisan optimize
php artisan queue:restart
Problemas comunes #
| Síntoma | Solución |
|---|---|
Unable to locate file in Vite manifest | Faltan los assets compilados. Ejecuta npm run build (o haz git pull si usas los del repositorio). |
El contenedor postgres nunca queda "healthy" | Revisa que DB_PASSWORD no esté vacía en el .env. |
key:generate falla con permiso denegado en Docker | Genera la clave con openssl desde el host, como en el paso 3. |
Cambios en el .env que no se aplican | La configuración está en caché. Ejecuta php artisan optimize o reinicia los contenedores. |
| No aparece la opción de registrarse | Es lo esperado con APP_INSTANCE=self-hosted. Crea las cuentas desde /system. |
¿Algo más? Abre un issue en GitHub.