Hardcoded localhost:5000 broke shop.zea.lt; wire env fileReplacements and proxy /api + /uploads to the API container.
iLED — Sklep z lampami
Polish lamp e-commerce platform with .NET modular monolith API, Angular shop, and Angular admin panel.
Structure
Shop/
design/ Figma exports
src/
backend/ .NET 10 API (Clean Architecture + CQRS)
shop/ Angular customer webshop (port 4200)
admin/ Angular admin panel (port 4201)
docker/ PostgreSQL, Redis, OpenObserve, optional API
.drone.yml Drone CI (build) + SSH deploy
Drone CI / deploy
Pipeline file: .drone.yml.
CI (every push / PR): build API, shop, admin.
Deploy (master/main push, after CI): SSH to the host, git checkout the commit, docker compose --profile full up -d --build.
Drone secrets to configure:
| Secret | Purpose |
|---|---|
ssh_host |
Deploy server hostname/IP |
ssh_user |
SSH user |
ssh_key |
Private key (PEM) |
ssh_port |
SSH port (use 22 if unused) |
deploy_path |
Absolute clone path, e.g. /opt/iled-shop |
On the host once:
git clone ssh://git@git.zea.lt:2222/miczek/iled-shop.git /opt/iled-shop
cd /opt/iled-shop/docker
cp .env.example .env # edit passwords / CORS origins
Shop/admin Angular apps are built in CI; production static hosting (nginx) can be wired next.
Quick start
1. Infrastructure
cd docker
docker compose up -d postgres redis openobserve
- PostgreSQL:
localhost:5433(db/user/passiled/iled123) - Redis:
localhost:6379 - OpenObserve UI: http://localhost:5080 —
root@iled.local/Complexpass#123
2. Backend API
cd src/backend
dotnet run --project src/iLED.Api
API: http://localhost:5000
Swagger: http://localhost:5000/swagger
Health: http://localhost:5000/health
Sitemap: http://localhost:5000/api/v1/seo/sitemap.xml
Leave OpenTelemetry:OtlpEndpoint empty to disable exporters (default).
With OpenObserve running, set endpoint/headers via env or User Secrets
(see Observability below).
Optional full stack (API in Docker):
cd docker
docker compose --profile full up -d --build
3. Shop (customer)
cd src/shop
npm start
4. Admin
cd src/admin
npm start
Admin login: admin@iled.pl / Admin123!
Shop routes
| Path | Purpose |
|---|---|
/ |
Home |
/products, /products/:slug |
Catalog / product detail |
/cart, /checkout |
Cart & checkout |
/login, /account |
Auth & orders |
/privacy, /terms |
Legal (draft copy) |
/** |
Custom 404 |
Footer links to privacy/terms. Cookie banner gates OpenPanel analytics only (OpenObserve is server-side and does not use browser cookies).
Payments (PayU)
- Default:
PayU:UseSandbox: true— local redirect simulation. - Live: set
UseSandboxtofalseand configure via User Secrets / env:PayU:PosId,ClientId,ClientSecret,SecondKeyOAuthUrl/OrdersUrl(sandbox hosts are inappsettings.json; production:https://secure.payu.com/...)NotifyUrl,ContinueUrl
- Webhook:
POST /api/v1/payments/webhook(signature headerOpenPayu-Signature). Failures appear in OpenObserve traces/logs. - Status sync (no admin button): thank-you page pulls PayU on return;
PayUPaymentSyncBackgroundServicepolls pending payments (PayU:StatusPollEnabled,PayU:StatusPollIntervalSeconds— 30s in Development). Needed locally when PayU cannot reachNotifyUrl.
Do not commit secrets. Use dotnet user-secrets or environment variables.
Shipping (InPost / DHL / DPD)
- Default:
Shipping:UseSandbox: true— mock labels; InPost map can still use the real Geowidget (sandbox SDK). - InPost map (localhost): token from
sandbox Parcel Manager → API →
Geowidget → Generate without a domain, then set
Shipping:InPost:GeowidgetSandboxToken. SDK:https://sandbox-easy-geowidget-sdk.easypack24.net. - InPost map (prod):
GeowidgetPublicTokenbound to your domain. - DHL/DPD: widget URLs in config; fallback = demo Leaflet map.
- Live labels (
UseSandbox: false) need carrier API credentials.
Pickup checkout shows a billing/invoice address hint (locker is not the invoice address).
Observability
OpenObserve (API)
Compose service openobserve on port 5080.
OTLP/HTTP base endpoint (SDK appends /v1/traces|metrics|logs):
OpenTelemetry__OtlpEndpoint=http://localhost:5080/api/default
OpenTelemetry__OtlpHeaders=Authorization=Basic <base64(email:password)>
OpenTelemetry__ServiceName=iled-api
For the default compose user, Basic value is:
cm9vdEBpbGVkLmxvY2FsOkNvbXBsZXhwYXNzIzEyMw==
OpenPanel (shop product analytics)
OpenPanel’s official stack is multi-service (API, dashboard, ClickHouse, etc.). Deploy with their self-hosting guide:
https://openpanel.dev/docs/self-hosting/deploy-docker-compose
Then set shop env:
// src/shop/src/environments/environment.ts
openPanelApiUrl: 'https://your-openpanel-host/api',
openPanelClientId: '<client-id-from-openpanel-ui>',
The tracker loads only after cookie consent is accepted.
SEO & legal
- Per-route meta title/description/Open Graph via
SeoService - Favicon / apple-touch /
og-defaultinsrc/shop/public - Static
robots.txt+ API sitemap - Privacy & Terms mention self-hosted OpenPanel + OpenObserve (draft for lawyer review)
Features
Shop
- Homepage, product list with filters, product detail
- Cart, checkout, PayU (sandbox by default)
- Login/register, favorites, account/orders
- InPost / DHL / DPD pickup widgets + sandbox map
- Product reviews, newsletter signup
- Cookie consent, 404, legal pages
Admin
- Dashboard KPIs
- Product CRUD (incl. image alt text), stock management
- Orders & shipping labels
- Discount rules & promo codes
- Newsletter subscribers & campaigns
- Review moderation
API modules
- Catalog, Identity, Cart, Orders, Payments, Shipping, Marketing, Reviews, SEO
Design
Brand colors: #FFBC39, #000000, #8C8C8C, #D9D9D9