Preview frontends · fxnstudio.com
nxtsmarthomes.fxnstudio.com 3004
NXTSmart.Homes — smart-home blog (imported from WordPress, served from Strapi).
bestlookingskin.fxnstudio.com 3002
BestLooking.Skin — skincare blog preview.
nxtbargains.fxnstudio.com 3001
NXT.Bargains — product-comparison/affiliate blog.
originfacts.fxnstudio.com 3000
OriginFacts — long-form facts/explainer site (renamed from preview.fxnstudio.com).
Backend services · fxnstudio.com
cms.fxnstudio.com 8888
Strapi CMS — content backend for every preview frontend above.
pim.fxnstudio.com 8090
Akeneo PIM — product catalogue master (BigBuy + manual). Runs from local docker-compose; no GitHub mirror.
claw.fxnstudio.com 18789
OpenClaw gateway — scraping/orchestration service.
Production sites hosted on this server
nxt.deals 3010
FXN travel booking platform (Duffel-powered flight + stay search).
nxtsmart.homes apache
Live WordPress site (rehub theme) being migrated to Next.js + Strapi.
Currently running containers
| Name | Image | Port | Status |
|---|---|---|---|
| nxtsmart-homes | node:20-alpine | 127.0.0.1:3004 | up |
| bestlooking-skin-preview | node:20-alpine | 127.0.0.1:3002 | up |
| nxt-bargains-dev | node:20-alpine | 127.0.0.1:3001 | up |
| originfacts-com-dev | node:20-alpine | 127.0.0.1:3000 | up |
| fxn-chisfis-frontend | node:20-alpine | 127.0.0.1:3010 | up nxt.deals |
| fxn-strapi | fxnstudio-cms-strapi | 127.0.0.1:8888 | up |
| fxn-postgres | postgres:16-alpine | internal | healthy |
| akeneo-httpd-1 | httpd:2.4 | 127.0.0.1:8090 | up PIM |
| + 7 supporting Akeneo containers (fpm, consumer, mysql, elasticsearch, minio, selenium, pubsub-emulator, blackfire) | |||
| openclaw-openclaw-gateway-1 | openclaw:local | 127.0.0.1:18789-18790 | healthy |
Snapshot at page-render time — use docker ps for live state.
Useful commands
Inspect state
# Running containers docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}' # All containers (including stopped) docker ps -a # Logs (tail + follow) docker logs --tail 100 -f nxtsmart-homes # Shell into a container docker exec -it fxn-strapi sh # What ports are listening on the host ss -tlnp | grep -E ':(3000|3001|3002|3004|3010|8888|8090)'
Rebuild + restart a Next.js preview frontend
# Pattern: cd into source, do a one-shot build inside an ephemeral node container, # then restart the long-running container. # Replace PORT and NAME / SITE_URL as needed for the target frontend. cd /opt/fxn-cms-git/backend/nxtsmart-homes # or nxt-bargains, bestlooking-skin, originfacts-com docker run --rm --network fxnstudio-cms_fxn-net -v "$PWD":/app -w /app \ -e NEXT_PUBLIC_SITE_URL=https://nxtsmarthomes.fxnstudio.com \ -e NEXT_PUBLIC_STRAPI_URL=https://cms.fxnstudio.com \ node:20-alpine sh -c "corepack enable && yarn install --frozen-lockfile && yarn build" docker restart nxtsmart-homes # Verify curl -sI -o /dev/null -w "https=%{http_code}\n" https://nxtsmarthomes.fxnstudio.com/
Pull from git and rebuild (deploy)
# Example for nxtsmart-homes — same shape for the others cd /opt/fxn-cms-git/backend/nxtsmart-homes git pull --ff-only docker run --rm --network fxnstudio-cms_fxn-net -v "$PWD":/app -w /app \ -e NEXT_PUBLIC_SITE_URL=https://nxtsmarthomes.fxnstudio.com \ -e NEXT_PUBLIC_STRAPI_URL=https://cms.fxnstudio.com \ node:20-alpine sh -c "yarn install --frozen-lockfile && yarn build" docker restart nxtsmart-homes # For bestlooking.skin prod (when re-enabled) see the canonical script: # /opt/fxn-cms-git/backend/deploy-bestlooking-skin.sh
Strapi: rebuild the image after schema/code changes
# Required whenever you change /opt/fxn-cms-git/backend/strapi-deploy/strapi/src/** # (e.g. new content types, bootstrap, lifecycles) cd /opt/fxn-cms-git/backend/strapi-deploy docker compose build strapi docker compose up -d strapi # Wait for ready until curl -sf http://127.0.0.1:8888/_health; do sleep 2; done; echo ' OK'
Strapi: restart without rebuild (config/env-only changes)
cd /opt/fxn-cms-git/backend/strapi-deploy docker compose restart strapi docker logs --tail 50 fxn-strapi
Re-run the WP → Strapi importer (nxtsmart.homes)
# Idempotent (legacyWpId-keyed). Re-running updates existing posts and # backfills publishedAt from WP date_gmt via a single SQL UPDATE. STRAPI_API_TOKEN=<token> \ python3 /opt/fxn-cms-git/backend/scripts/import-wp-to-nxtsmart.py # Useful flags # --limit 5 # only the first N posts # --categories-only # skip posts # --posts-only # skip categories (after first run) # --dry-run # print actions, write nothing
nginx: reload after editing a vhost
# Edit a config under /etc/nginx/sites-available/ , then: nginx -t # validate systemctl reload nginx # Enable / disable a site ln -s /etc/nginx/sites-available/<name> /etc/nginx/sites-enabled/<name> rm /etc/nginx/sites-enabled/<name>
Let's Encrypt: issue a cert for a new subdomain
# DNS must point to this server first. certbot certonly --nginx -d <subdomain.fxnstudio.com> \ --non-interactive --agree-tos -m kritin@fxnholdings.com # List + manual renew check certbot certificates certbot renew --dry-run
Cleanup: stopped containers, dangling images, old build cache
# Safe — only removes stopped containers and dangling layers docker container prune -f docker image prune -f # Aggressive — also removes UNUSED images (anything not attached to a container) docker system prune -af