Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 73d39b49ea |
@@ -1,8 +0,0 @@
|
|||||||
.env
|
|
||||||
*.key
|
|
||||||
|
|
||||||
data/
|
|
||||||
data/*.csv
|
|
||||||
data/*.log
|
|
||||||
data/*.json
|
|
||||||
data/*.txt
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
RewriteEngine On
|
|
||||||
|
|
||||||
# Redirigir a index si no existeix el fitxer
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-f
|
|
||||||
RewriteCond %{REQUEST_FILENAME} !-d
|
|
||||||
RewriteRule ^ index.html [L]
|
|
||||||
-21
@@ -1,21 +0,0 @@
|
|||||||
FROM php:8.2-apache-bookworm
|
|
||||||
|
|
||||||
ENV DEBIAN_FRONTEND=noninteractive
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
libcurl4-openssl-dev \
|
|
||||||
libonig-dev \
|
|
||||||
ca-certificates \
|
|
||||||
&& docker-php-ext-install curl mbstring mysqli pdo pdo_mysql \
|
|
||||||
&& a2enmod rewrite \
|
|
||||||
&& echo "ServerName localhost" > /etc/apache2/conf-available/servername.conf \
|
|
||||||
&& a2enconf servername \
|
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
COPY . /var/www/html/
|
|
||||||
|
|
||||||
RUN mkdir -p /var/www/html/api/cache \
|
|
||||||
&& chown -R www-data:www-data /var/www/html \
|
|
||||||
&& chmod -R 775 /var/www/html/api/cache
|
|
||||||
|
|
||||||
EXPOSE 80
|
|
||||||
+53
-36
@@ -1,60 +1,77 @@
|
|||||||
<?php
|
<?php
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
function kapvoe_env(string $key, ?string $default = null): string
|
|
||||||
{
|
|
||||||
$value = getenv($key);
|
|
||||||
if ($value === false || $value === '') {
|
|
||||||
return $default ?? '';
|
|
||||||
}
|
|
||||||
return (string)$value;
|
|
||||||
}
|
|
||||||
|
|
||||||
$baseUrl = rtrim(kapvoe_env('KAPVOE_PUBLIC_BASE_URL', 'https://kapvoe-portfoli.treblarella.org'), '/');
|
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'stripe_secret_key' => kapvoe_env('STRIPE_SECRET_KEY'),
|
// Clau secreta real de Stripe. NO la posis mai al HTML.
|
||||||
'stripe_webhook_secret' => kapvoe_env('STRIPE_WEBHOOK_SECRET'),
|
'stripe_secret_key' => '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',
|
||||||
|
|
||||||
|
// Secret del webhook de Stripe (Signing secret)
|
||||||
|
'stripe_webhook_secret' => 'whsec_8FTXIXPWBSzFjJNQWuzetQF6LoNKv9sg',
|
||||||
|
|
||||||
|
// Moneda
|
||||||
'currency' => 'eur',
|
'currency' => 'eur',
|
||||||
|
|
||||||
|
// On guardar les comandes i logs
|
||||||
'orders_storage_dir' => dirname(__DIR__) . '/data',
|
'orders_storage_dir' => dirname(__DIR__) . '/data',
|
||||||
|
|
||||||
'success_url' => $baseUrl . '/checkout/payment-success.php',
|
// URLs públiques
|
||||||
'cancel_url' => $baseUrl . '/checkout/payment-cancel.php',
|
'success_url' => 'https://kapvoe-portfoli.treblarella.org/checkout/payment-success.php',
|
||||||
|
'cancel_url' => 'https://kapvoe-portfoli.treblarella.org/checkout/payment-cancel.php',
|
||||||
|
|
||||||
|
'stock_sync_url' => 'https://script.google.com/macros/s/AKfycbyH6PuQPR342mwSiKCkYZ1lOnn1VccqzFO-ScbhwjvJoABU3LqVNJcS3gtPE5ZuT0JyvQ/exec',
|
||||||
|
'stock_sync_token' => 'kapvoe_stock_2026_x7F9mQpL2vN8rT4sZ1kW',
|
||||||
|
|
||||||
'stock_sync_url' => kapvoe_env('KAPVOE_STOCK_SYNC_URL'),
|
'catalog_api_url' => 'https://kapvoe-portfoli.treblarella.org/api/products.php',
|
||||||
'stock_sync_token' => kapvoe_env('KAPVOE_STOCK_SYNC_TOKEN'),
|
|
||||||
'catalog_api_url' => kapvoe_env('KAPVOE_CATALOG_API_URL', $baseUrl . '/api/products.php'),
|
|
||||||
|
|
||||||
|
// Tracking i analytics per Google Sheets / Looker Studio
|
||||||
'analytics_enabled' => true,
|
'analytics_enabled' => true,
|
||||||
'analytics_sync_url' => kapvoe_env('KAPVOE_ANALYTICS_SYNC_URL'),
|
'analytics_sync_url' => 'https://script.google.com/macros/s/AKfycbyyK8fAytZcPHuJKn-LVItMC8BAyTz0jzHml47vvfOHsTwhetCITND_-_yNd7HqickQ/exec',
|
||||||
'analytics_sync_token' => kapvoe_env('KAPVOE_ANALYTICS_SYNC_TOKEN'),
|
'analytics_sync_token' => 'kapvoe_analitycs_2026_x7F9mQpL2vN8rT4sZ1kW',
|
||||||
'analytics_timeout' => 10,
|
'analytics_timeout' => 10,
|
||||||
|
|
||||||
'mail_transport' => kapvoe_env('KAPVOE_MAIL_TRANSPORT', 'smtp'),
|
// Correu sortint
|
||||||
'mail_from_email' => kapvoe_env('KAPVOE_MAIL_FROM_EMAIL', 'pedidos@bloodbros.store'),
|
// Si vols dependre nomes de la Synology, fes servir 'smtp'.
|
||||||
'mail_from_name' => kapvoe_env('KAPVOE_MAIL_FROM_NAME', 'Blood Bros Sports'),
|
// Opcions: auto | mail | smtp | resend
|
||||||
'mail_reply_to' => kapvoe_env('KAPVOE_MAIL_REPLY_TO', 'pedidos@bloodbros.store'),
|
'mail_transport' => 'smtp',
|
||||||
|
'mail_from_email' => 'pedidos@bloodbros.store',
|
||||||
|
'mail_from_name' => 'Blood Bros Sports',
|
||||||
|
'mail_reply_to' => 'pedidos@bloodbros.store',
|
||||||
|
|
||||||
'resend_api_key' => kapvoe_env('KAPVOE_RESEND_API_KEY'),
|
// API HTTP de correu. Recomanat si el hosting falla amb mail() o SMTP.
|
||||||
'resend_api_url' => kapvoe_env('KAPVOE_RESEND_API_URL', 'https://api.resend.com/emails'),
|
// Amb Resend nomes cal una API key i el domini verificat.
|
||||||
|
'resend_api_key' => '',
|
||||||
|
'resend_api_url' => 'https://api.resend.com/emails',
|
||||||
|
|
||||||
|
// AvÃs intern de noves comandes
|
||||||
|
// SMTP sortint. Activa-ho si el servidor no envia be amb mail().
|
||||||
|
// SMTP sortint. Idealment apunta al servidor SMTP de la teva Synology.
|
||||||
|
// Exemples habituals:
|
||||||
|
// - NAS mateixa maquina: 127.0.0.1
|
||||||
|
// - NAS a la LAN: 192.168.x.x
|
||||||
'smtp_enabled' => true,
|
'smtp_enabled' => true,
|
||||||
'smtp_host' => kapvoe_env('KAPVOE_SMTP_HOST', 'mail.bloodbros.store'),
|
'smtp_host' => 'mail.bloodbros.store',
|
||||||
'smtp_port' => (int)kapvoe_env('KAPVOE_SMTP_PORT', '587'),
|
'smtp_port' => 587,
|
||||||
'smtp_encryption' => kapvoe_env('KAPVOE_SMTP_ENCRYPTION', 'tls'),
|
'smtp_encryption' => 'tls',
|
||||||
'smtp_username' => kapvoe_env('KAPVOE_SMTP_USERNAME', 'pedidos@bloodbros.store'),
|
'smtp_username' => 'pedidos@bloodbros.store',
|
||||||
'smtp_password' => kapvoe_env('KAPVOE_SMTP_PASSWORD'),
|
'smtp_password' => '2%0Jx5zv',
|
||||||
'smtp_timeout' => 15,
|
'smtp_timeout' => 15,
|
||||||
|
// Prova de compatibilitat TLS per hostings/PHPs restrictius.
|
||||||
|
// Activa-ho nomes per provar si el problema es la validacio del certificat.
|
||||||
'smtp_allow_invalid_certificates' => true,
|
'smtp_allow_invalid_certificates' => true,
|
||||||
|
|
||||||
'admin_notification_email' => kapvoe_env('KAPVOE_ADMIN_NOTIFICATION_EMAIL', 'pedidos@bloodbros.store'),
|
// Avis intern per correu
|
||||||
|
'admin_notification_email' => 'pedidos@bloodbros.store',
|
||||||
|
|
||||||
|
// Avis intern independent del correu.
|
||||||
|
// Si poses un webhook intern de la Synology, es cridara per cada compra pagada.
|
||||||
|
// Si ho deixes buit, es guardara a data/internal-notifications.log
|
||||||
'internal_notification_enabled' => true,
|
'internal_notification_enabled' => true,
|
||||||
'internal_notification_webhook_url' => kapvoe_env('KAPVOE_INTERNAL_NOTIFICATION_WEBHOOK_URL'),
|
'internal_notification_webhook_url' => '',
|
||||||
'internal_notification_webhook_token' => kapvoe_env('KAPVOE_INTERNAL_NOTIFICATION_WEBHOOK_TOKEN'),
|
'internal_notification_webhook_token' => '',
|
||||||
'internal_notification_timeout' => 10,
|
'internal_notification_timeout' => 10,
|
||||||
'internal_notification_log_path' => dirname(__DIR__) . '/data/internal-notifications.log',
|
'internal_notification_log_path' => dirname(__DIR__) . '/data/internal-notifications.log',
|
||||||
|
|
||||||
'admin_tools_token' => kapvoe_env('KAPVOE_ADMIN_TOOLS_TOKEN'),
|
// Token per eines internes com el test de correu.
|
||||||
];
|
// Posa-hi un valor llarg i privat abans d'usar test-mail.php
|
||||||
|
'admin_tools_token' => 'kapvoe-test-2026-9xF2mL7qP4sT8vN1',
|
||||||
|
];
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
order_id;created_at;product_code;product_name;unit_price;quantity;customer_name;address;postal_code;city;province;phone;email;payment_status;stripe_session_id;payment_intent_id;stock_updated;stock_updated_at;webhook_processed_at
|
||||||
|
ORD-20260403-114000-45c216;"2026-04-03 11:40:02";K383;K383;60;1;"Albert Gadea Llevot";"Carrer del Progrés 5";25244;Fondarella;Lleida;686255350;albert@bloodbros.store;paid;cs_test_a1OGoVroq2P9ljWEHeyNewPwku0zZ1aJG3d2uDyDwIzl1q70bCZPRbrWT8;pi_3TI4CsHRV8rA2Xws1vaNX2My;1;"2026-04-03 11:40:24";"2026-04-03 11:40:24"
|
||||||
|
@@ -1,296 +0,0 @@
|
|||||||
# Kapvoe Portfoli - Deployment i produccio
|
|
||||||
|
|
||||||
## Objectiu
|
|
||||||
|
|
||||||
Aquest projecte publica el portfolio d'ulleres Kapvoe al domini de produccio:
|
|
||||||
|
|
||||||
https://kapvoe-portfoli.treblarella.org
|
|
||||||
|
|
||||||
El flux correcte de treball es:
|
|
||||||
|
|
||||||
VS Code / PowerShell
|
|
||||||
-> git commit
|
|
||||||
-> git push
|
|
||||||
-> Gitea
|
|
||||||
-> Webhook
|
|
||||||
-> Coolify API
|
|
||||||
-> Docker build/deploy
|
|
||||||
-> Produccio
|
|
||||||
|
|
||||||
## Arquitectura
|
|
||||||
|
|
||||||
Internet
|
|
||||||
-> Cloudflare / DNS
|
|
||||||
-> Synology Reverse Proxy
|
|
||||||
-> Coolify a 192.168.1.80
|
|
||||||
-> Aplicacio Docker kapvoe-portfoli-web
|
|
||||||
-> PHP Apache
|
|
||||||
-> Apps Script / Google Sheets
|
|
||||||
-> Stripe Checkout
|
|
||||||
|
|
||||||
## Domini de produccio
|
|
||||||
|
|
||||||
Domini public:
|
|
||||||
|
|
||||||
https://kapvoe-portfoli.treblarella.org
|
|
||||||
|
|
||||||
Aquest domini apunta a Synology, i Synology fa reverse proxy cap a Coolify.
|
|
||||||
|
|
||||||
Configuracio recomanada del reverse proxy de Synology:
|
|
||||||
|
|
||||||
Origen:
|
|
||||||
- Protocol: HTTPS
|
|
||||||
- Host: kapvoe-portfoli.treblarella.org
|
|
||||||
- Port: 443
|
|
||||||
|
|
||||||
Desti:
|
|
||||||
- Protocol: HTTP
|
|
||||||
- Host: 192.168.1.80
|
|
||||||
- Port: 80
|
|
||||||
|
|
||||||
## Coolify
|
|
||||||
|
|
||||||
Aplicacio:
|
|
||||||
|
|
||||||
kapvoe-portfoli-web
|
|
||||||
|
|
||||||
Projecte:
|
|
||||||
|
|
||||||
Portfoli Ulleres / production
|
|
||||||
|
|
||||||
Build pack:
|
|
||||||
|
|
||||||
Dockerfile
|
|
||||||
|
|
||||||
Dockerfile location:
|
|
||||||
|
|
||||||
/Dockerfile
|
|
||||||
|
|
||||||
Domini configurat a Coolify:
|
|
||||||
|
|
||||||
https://kapvoe-portfoli.treblarella.org
|
|
||||||
|
|
||||||
## Git Source
|
|
||||||
|
|
||||||
Repositori Gitea:
|
|
||||||
|
|
||||||
Albert/portfoli-ulleres
|
|
||||||
|
|
||||||
URL SSH interna usada per Coolify:
|
|
||||||
|
|
||||||
ssh://git@10.0.0.1:22222/Albert/portfoli-ulleres.git
|
|
||||||
|
|
||||||
Branca de produccio:
|
|
||||||
|
|
||||||
main
|
|
||||||
|
|
||||||
## Deploy automatic
|
|
||||||
|
|
||||||
El deploy automatic funciona amb:
|
|
||||||
|
|
||||||
Gitea webhook -> Coolify API
|
|
||||||
|
|
||||||
Webhook a Gitea:
|
|
||||||
|
|
||||||
coolify-production-deploy
|
|
||||||
|
|
||||||
URL del webhook:
|
|
||||||
|
|
||||||
http://10.0.0.1:8000/api/v1/deploy?uuid=f11x5rza9srzo6pkgqcnl0ph&force=false
|
|
||||||
|
|
||||||
Metode:
|
|
||||||
|
|
||||||
POST
|
|
||||||
|
|
||||||
Content type:
|
|
||||||
|
|
||||||
application/json
|
|
||||||
|
|
||||||
Header d'autoritzacio:
|
|
||||||
|
|
||||||
Bearer <COOLIFY_API_TOKEN>
|
|
||||||
|
|
||||||
Important: el token no s'ha de guardar mai al repo.
|
|
||||||
|
|
||||||
## Configuracio Gitea necessaria
|
|
||||||
|
|
||||||
Gitea ha de permetre webhooks cap a la IP interna de Docker/Coolify.
|
|
||||||
|
|
||||||
Fitxer:
|
|
||||||
|
|
||||||
/data/gitea/conf/app.ini
|
|
||||||
|
|
||||||
Bloc necessari:
|
|
||||||
|
|
||||||
[webhook]
|
|
||||||
ALLOWED_HOST_LIST = external,private,loopback,10.0.0.1
|
|
||||||
|
|
||||||
Despres de modificar aquest fitxer cal reiniciar el contenidor de Gitea.
|
|
||||||
|
|
||||||
## Coolify API
|
|
||||||
|
|
||||||
A Coolify cal tenir API Access activat.
|
|
||||||
|
|
||||||
Allowed IPs recomanats:
|
|
||||||
|
|
||||||
10.0.0.0/8,127.0.0.1/32,192.168.1.0/24
|
|
||||||
|
|
||||||
Token recomanat:
|
|
||||||
|
|
||||||
gitea-production-deploy
|
|
||||||
|
|
||||||
Permisos minims:
|
|
||||||
|
|
||||||
- read
|
|
||||||
- deploy
|
|
||||||
|
|
||||||
## Persistent Storage
|
|
||||||
|
|
||||||
La carpeta de dades runtime es persistent:
|
|
||||||
|
|
||||||
/var/www/html/data
|
|
||||||
|
|
||||||
Aquesta carpeta conte:
|
|
||||||
|
|
||||||
- orders.csv
|
|
||||||
- analytics.log
|
|
||||||
- mail.log
|
|
||||||
- internal-notifications.log
|
|
||||||
|
|
||||||
Aquesta carpeta no ha d'anar al repositori Git.
|
|
||||||
|
|
||||||
.gitignore ha d'incloure:
|
|
||||||
|
|
||||||
data/
|
|
||||||
data/*.csv
|
|
||||||
data/*.log
|
|
||||||
data/*.json
|
|
||||||
data/*.txt
|
|
||||||
|
|
||||||
## Stripe
|
|
||||||
|
|
||||||
Checkout Stripe funciona amb:
|
|
||||||
|
|
||||||
/checkout/create-checkout-session.php
|
|
||||||
|
|
||||||
Webhook live de Stripe:
|
|
||||||
|
|
||||||
https://kapvoe-portfoli.treblarella.org/checkout/stripe-webhook.php
|
|
||||||
|
|
||||||
Event minim necessari:
|
|
||||||
|
|
||||||
checkout.session.completed
|
|
||||||
|
|
||||||
El webhook processa:
|
|
||||||
|
|
||||||
- payment_status = paid
|
|
||||||
- payment_intent_id
|
|
||||||
- stock update
|
|
||||||
- email client
|
|
||||||
- email admin
|
|
||||||
|
|
||||||
## Variables d'entorn critiques a Coolify
|
|
||||||
|
|
||||||
No guardar secrets al repo.
|
|
||||||
|
|
||||||
Variables importants:
|
|
||||||
|
|
||||||
STRIPE_SECRET_KEY
|
|
||||||
STRIPE_WEBHOOK_SECRET
|
|
||||||
KAPVOE_PUBLIC_BASE_URL
|
|
||||||
KAPVOE_CATALOG_API_URL
|
|
||||||
KAPVOE_STOCK_SYNC_URL
|
|
||||||
KAPVOE_STOCK_SYNC_TOKEN
|
|
||||||
KAPVOE_ANALYTICS_SYNC_URL
|
|
||||||
KAPVOE_ANALYTICS_SYNC_TOKEN
|
|
||||||
KAPVOE_SMTP_HOST
|
|
||||||
KAPVOE_SMTP_PORT
|
|
||||||
KAPVOE_SMTP_ENCRYPTION
|
|
||||||
KAPVOE_SMTP_USERNAME
|
|
||||||
KAPVOE_SMTP_PASSWORD
|
|
||||||
KAPVOE_ADMIN_NOTIFICATION_EMAIL
|
|
||||||
KAPVOE_ADMIN_TOOLS_TOKEN
|
|
||||||
|
|
||||||
Valor intern recomanat per evitar problemes SSL dins del contenidor:
|
|
||||||
|
|
||||||
KAPVOE_CATALOG_API_URL=http://127.0.0.1/api/products.php
|
|
||||||
|
|
||||||
## Com desplegar canvis
|
|
||||||
|
|
||||||
Des del PC:
|
|
||||||
|
|
||||||
git status
|
|
||||||
git add .
|
|
||||||
git commit -m "Missatge del canvi"
|
|
||||||
git push
|
|
||||||
|
|
||||||
Despres anar a Coolify -> kapvoe-portfoli-web -> Deployments.
|
|
||||||
|
|
||||||
El deploy ha d'apareixer amb etiqueta:
|
|
||||||
|
|
||||||
API
|
|
||||||
|
|
||||||
No hauria de ser necessari premer Redeploy manualment.
|
|
||||||
|
|
||||||
## Com validar produccio
|
|
||||||
|
|
||||||
Productes:
|
|
||||||
|
|
||||||
https://kapvoe-portfoli.treblarella.org/api/products.php?refresh=1
|
|
||||||
|
|
||||||
Ha de retornar JSON amb:
|
|
||||||
|
|
||||||
"ok": true
|
|
||||||
|
|
||||||
I count amb el nombre de productes visibles.
|
|
||||||
|
|
||||||
Web:
|
|
||||||
|
|
||||||
https://kapvoe-portfoli.treblarella.org
|
|
||||||
|
|
||||||
Checkout:
|
|
||||||
|
|
||||||
Fer una prova amb producte de prova i verificar:
|
|
||||||
|
|
||||||
- Stripe checkout obre correctament
|
|
||||||
- Stripe webhook retorna 200
|
|
||||||
- orders.csv passa a paid
|
|
||||||
- stock_updated = 1
|
|
||||||
- customer_email_sent = 1
|
|
||||||
- admin_email_sent = 1
|
|
||||||
|
|
||||||
## Comprovar dades persistents al servidor
|
|
||||||
|
|
||||||
Al servidor Coolify:
|
|
||||||
|
|
||||||
CONTAINER=$(docker ps --format "{{.Names}}" | grep f11x5 | head -n 1)
|
|
||||||
docker exec "$CONTAINER" ls -la /var/www/html/data
|
|
||||||
docker exec "$CONTAINER" sh -c 'tail -n 5 /var/www/html/data/orders.csv'
|
|
||||||
|
|
||||||
## Notes importants de seguretat
|
|
||||||
|
|
||||||
S'han de rotar tots els secrets que s'hagin enganxat accidentalment en converses, logs o terminals compartits.
|
|
||||||
|
|
||||||
Secrets a rotar:
|
|
||||||
|
|
||||||
- Stripe secret key
|
|
||||||
- Stripe webhook secret
|
|
||||||
- SMTP password
|
|
||||||
- KAPVOE_STOCK_SYNC_TOKEN
|
|
||||||
- KAPVOE_ANALYTICS_SYNC_TOKEN
|
|
||||||
- KAPVOE_ADMIN_TOOLS_TOKEN
|
|
||||||
- Tokens interns de Gitea si s'han exposat
|
|
||||||
- Coolify API token si s'ha exposat
|
|
||||||
|
|
||||||
## Estat final validat
|
|
||||||
|
|
||||||
Validat:
|
|
||||||
|
|
||||||
- Web en produccio funcional
|
|
||||||
- Productes carregant
|
|
||||||
- Imatges carregant
|
|
||||||
- Stripe Checkout funcional
|
|
||||||
- Stripe webhook funcional
|
|
||||||
- Emails client i admin funcionals
|
|
||||||
- Persistent storage funcional
|
|
||||||
- Deploy automatic Gitea -> Coolify funcional
|
|
||||||
Reference in New Issue
Block a user