Compare commits
162 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7bc84cea75 | |||
| 27093bcd54 | |||
| 0ea1b98a1f | |||
| 107ef43a0e | |||
| 623b237826 | |||
| 84ab6bef2d | |||
| 6705293e50 | |||
| 01c908e919 | |||
| 6865d2d437 | |||
| e95ec68931 | |||
| 1861e10d6d | |||
| f2fa8e3c17 | |||
| c22b668bc5 | |||
| 0576677523 | |||
| c6d5a0265f | |||
| 6fea1f2be1 | |||
| c130f9bcdf | |||
| e2d9ae7541 | |||
| f4b1f7722e | |||
| 215a8f2e3f | |||
| 50680a323f | |||
| 9f9f326af9 | |||
| 668ee46ba6 | |||
| c984c14085 | |||
| f58ae2c5f7 | |||
| 21ebb9667b | |||
| 746868d720 | |||
| 4d1daa3910 | |||
| 248d73a619 | |||
| 5cefb4d161 | |||
| 8b0793c42f | |||
| b585d851dd | |||
| 7c42800245 | |||
| a3b8593133 | |||
| 3a679eb03c | |||
| cf575afc3f | |||
| a94d938131 | |||
| d230e88bd1 | |||
| 467fcbffb7 | |||
| 5c391f3dee | |||
| 7e06f7f63a | |||
| 35956d2849 | |||
| 7b3cfb5178 | |||
| 9ca29e13de | |||
| a58b0f7cdb | |||
| c340cd2eaf | |||
| b2a3e5d605 | |||
| 962201975b | |||
| 5053cbcf44 | |||
| e4240d3f02 | |||
| cdd8ccb0e5 | |||
| 72e9de96e4 | |||
| 91885d5ff5 | |||
| b8c8a1a45f | |||
| 74aa30636c | |||
| 07b83c7ae8 | |||
| 721bf65ed3 | |||
| 0505f0a641 | |||
| 5c936b2b53 | |||
| 29b1e92ea9 | |||
| a0a184236c | |||
| c02e7fb4b6 | |||
| 1da82489c6 | |||
| ce6f48f5a4 | |||
| ae529862e6 | |||
| 5011812385 | |||
| 33a665294c | |||
| be017ded2b | |||
| 9951904e6d | |||
| b4da98f40d | |||
| 5cbc7c1190 | |||
| c2476135ff | |||
| f7dab87c76 | |||
| d444bbb49a | |||
| 8253b53b6f | |||
| eaf3bd55f0 | |||
| ad6effd470 | |||
| 507d085093 | |||
| 9aa20b0da0 | |||
| 2a07aca10a | |||
| 3b52b90e5c | |||
| 861d281db4 | |||
| 278d152fc1 | |||
| 2532f69e74 | |||
| 17388229b4 | |||
| e53040d55f | |||
| f2f6397deb | |||
| 0560db4318 | |||
| f21e29dd2a | |||
| 4c81c904b1 | |||
| 6769af994f | |||
| f433386f6a | |||
| e6b2014783 | |||
| 0f8383f0a3 | |||
| 126f7b05f1 | |||
| ac2e0b75b2 | |||
| 637242021f | |||
| ae77418596 | |||
| 07c57999b3 | |||
| 6462d153e4 | |||
| 40c422c9e4 | |||
| f15aac5f17 | |||
| c83490d4c9 | |||
| dee52d9b0c | |||
| 160370eb93 | |||
| fa6a499de8 | |||
| 3e895307d9 | |||
| 0ce88f7961 | |||
| d77d46d358 | |||
| 7245e97034 | |||
| fa1e2ba5ff | |||
| 6304066cd6 | |||
| cf995f2e80 | |||
| 6e09f0a32c | |||
| ec1897f247 | |||
| 50aed702fa | |||
| 81039f5bcf | |||
| f6141b0047 | |||
| a2549ff7db | |||
| 664c95820f | |||
| 58a3275a49 | |||
| 797acae974 | |||
| 0fb4e0af5c | |||
| 537487924b | |||
| e47e495911 | |||
| b60e1044e1 | |||
| 169d1977b4 | |||
| d656f79bf2 | |||
| d019a24c3d | |||
| 681569e5b3 | |||
| 3208b58067 | |||
| c0634c0971 | |||
| a880d6bc8a | |||
| 8da66e71a9 | |||
| e74a75e3a4 | |||
| 70560553cc | |||
| aa627267cf | |||
| 75d827d912 | |||
| a8db026382 | |||
| eb203fe365 | |||
| 9302d65dcf | |||
| 2723aea2a3 | |||
| d44eb04a5a | |||
| 97d68cc5ba | |||
| 4db9d12743 | |||
| b940a47c0d | |||
| 72b5d0da7a | |||
| 95d2cbfccb | |||
| f2e1d0ea12 | |||
| 69b83e0e87 | |||
| 7148dcbe0b | |||
| 53e717fedc | |||
| 37d7563b69 | |||
| a0734d27c9 | |||
| 9400e3607e | |||
| 9faf973d03 | |||
| b3f940074f | |||
| 033addb7d8 | |||
| 759c4efeed | |||
| 34ec1f04a9 | |||
| 80126d1b36 | |||
| 82b0c8b0b0 |
65
.env.example
@ -1,49 +1,16 @@
|
|||||||
# ─── Square API ────────────────────────────────────────────────────────────────
|
# ── Root .env (fallback for Docker Compose < v2.24) ───────────────────────────
|
||||||
# Get these from https://developer.squareup.com/apps
|
#
|
||||||
SQUARE_ACCESS_TOKEN=your_square_access_token_here
|
# Docker Compose v2.24+ reads build env_file directly from estore/.env — you
|
||||||
SQUARE_LOCATION_ID=your_square_location_id_here
|
# should not need this file at all on a modern install.
|
||||||
# "sandbox" or "production"
|
#
|
||||||
SQUARE_ENVIRONMENT=sandbox
|
# If your Compose is older and the shop shows "Online payment is not
|
||||||
|
# configured", copy the four NEXT_PUBLIC_* lines from estore/.env into this
|
||||||
# These are exposed to the browser — use your Square Application ID (not access token)
|
# file so Compose can bake them into the Next.js build:
|
||||||
# and the same location ID as above.
|
#
|
||||||
NEXT_PUBLIC_SQUARE_APP_ID=sandbox-sq0idb-your_app_id_here
|
# NEXT_PUBLIC_SQUARE_APP_ID=
|
||||||
NEXT_PUBLIC_SQUARE_LOCATION_ID=your_square_location_id_here
|
# NEXT_PUBLIC_SQUARE_LOCATION_ID=
|
||||||
# "sandbox" or "production" — controls which Square JS SDK URL is loaded
|
# NEXT_PUBLIC_SQUARE_ENVIRONMENT=production
|
||||||
NEXT_PUBLIC_SQUARE_ENVIRONMENT=sandbox
|
# NEXT_PUBLIC_SITE_URL=https://shop.beachpartyballoons.com
|
||||||
# Optional: ID of a Square category (Items > Categories) whose items appear in the shop.
|
#
|
||||||
# If set, only items in this category are shown. Otherwise falls back to src/config/shop-items.json.
|
# All other secrets (access tokens, passwords, etc.) belong only in estore/.env
|
||||||
SQUARE_SHOP_CATEGORY_ID=
|
# — never put them here.
|
||||||
|
|
||||||
# ─── CalDAV (Nextcloud) ────────────────────────────────────────────────────────
|
|
||||||
# Your Nextcloud CalDAV base URL — include trailing slash
|
|
||||||
CALDAV_URL=https://your-nextcloud.example.com/remote.php/dav/calendars/username/
|
|
||||||
CALDAV_USERNAME=your_nextcloud_username
|
|
||||||
# Use an app password (Settings > Security > Devices & sessions > App passwords)
|
|
||||||
CALDAV_PASSWORD=your_nextcloud_app_password
|
|
||||||
# Display name of the calendar to check for Busy blocks
|
|
||||||
CALDAV_CALENDAR_NAME=Deliveries
|
|
||||||
|
|
||||||
# ─── Email (SMTP — your mail server) ──────────────────────────────────────────
|
|
||||||
SMTP_HOST=mail.beachpartyballoons.com
|
|
||||||
SMTP_PORT=587
|
|
||||||
SMTP_USER=shop@beachpartyballoons.com
|
|
||||||
SMTP_PASS=your_email_password_here
|
|
||||||
# Address that receives new-order & slot-conflict alerts (you/staff)
|
|
||||||
ALERT_EMAIL_TO=you@beachpartyballoons.com
|
|
||||||
# Sender shown on outgoing emails
|
|
||||||
ALERT_EMAIL_FROM=shop@beachpartyballoons.com
|
|
||||||
|
|
||||||
# ─── Admin panel ───────────────────────────────────────────────────────────────
|
|
||||||
# Password to access /admin — keep this secret
|
|
||||||
ADMIN_PASSWORD=change_me_to_something_strong
|
|
||||||
# Secret token for the cron cache-refresh endpoint (POST /api/cache/refresh)
|
|
||||||
CACHE_REFRESH_SECRET=change_me_to_something_random
|
|
||||||
|
|
||||||
# ─── OSRM (self-hosted routing) ────────────────────────────────────────────────
|
|
||||||
# Leave blank to use the public demo server (unreliable). Self-host for production:
|
|
||||||
# https://hub.docker.com/r/osrm/osrm-backend
|
|
||||||
OSRM_URL=http://localhost:5000
|
|
||||||
|
|
||||||
# ─── Site ──────────────────────────────────────────────────────────────────────
|
|
||||||
NEXT_PUBLIC_SITE_URL=http://localhost:3000
|
|
||||||
|
|||||||
29
.gitignore
vendored
@ -1,18 +1,28 @@
|
|||||||
# dependencies
|
# Dependencies
|
||||||
node_modules/
|
node_modules/
|
||||||
|
.pnp
|
||||||
|
.pnp.js
|
||||||
|
|
||||||
# Next.js build output
|
# Next.js
|
||||||
.next/
|
estore/.next/
|
||||||
out/
|
estore/out/
|
||||||
|
|
||||||
# Runtime data — cache and item overrides change at runtime, don't track them
|
# Runtime data
|
||||||
data/catalog-cache.json
|
estore/data/catalog-cache.json
|
||||||
data/item-overrides.json
|
estore/data/item-overrides.json
|
||||||
|
estore/data/hours.json
|
||||||
|
estore/data/delivery-rates.json
|
||||||
|
main-site/photo-gallery-app/backend/uploads/
|
||||||
|
mongodb_data/
|
||||||
|
osrm/data/*
|
||||||
|
!osrm/data/.gitkeep
|
||||||
|
|
||||||
# Environment variables — never commit these
|
# Environment variables — never commit
|
||||||
.env
|
.env
|
||||||
.env.local
|
.env.local
|
||||||
.env*.local
|
.env*.local
|
||||||
|
*/.env
|
||||||
|
*/.env.local
|
||||||
|
|
||||||
# OS / editor
|
# OS / editor
|
||||||
.DS_Store
|
.DS_Store
|
||||||
@ -26,7 +36,4 @@ npm-debug.log*
|
|||||||
|
|
||||||
# Misc
|
# Misc
|
||||||
.eslintcache
|
.eslintcache
|
||||||
|
|
||||||
# Raw/duplicate image files — use public/images/ directly
|
|
||||||
public/images/pics/
|
|
||||||
*.heic
|
*.heic
|
||||||
|
|||||||
@ -1,26 +1,116 @@
|
|||||||
services:
|
services:
|
||||||
osrm:
|
|
||||||
image: osrm/osrm-backend
|
# ── Nginx reverse proxy ───────────────────────────────────────────────────────
|
||||||
container_name: osrm
|
nginx:
|
||||||
restart: unless-stopped
|
image: nginx:alpine
|
||||||
|
container_name: bpb-nginx
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
volumes:
|
||||||
|
- ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||||
|
depends_on:
|
||||||
|
- main-site
|
||||||
|
- estore
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
# ── Main website ─────────────────────────────────────────────────────────────
|
||||||
|
main-site:
|
||||||
|
build: ./main-site
|
||||||
|
container_name: bpb-main
|
||||||
|
expose:
|
||||||
|
- "3050"
|
||||||
|
environment:
|
||||||
|
NODE_ENV: production
|
||||||
|
ADMIN_PASSWORD: ${MAIN_ADMIN_PASSWORD}
|
||||||
|
volumes:
|
||||||
|
- ./main-site/update.json:/usr/src/app/update.json
|
||||||
|
restart: always
|
||||||
|
depends_on:
|
||||||
|
- gallery-backend
|
||||||
|
|
||||||
|
# ── Photo gallery backend ─────────────────────────────────────────────────────
|
||||||
|
gallery-backend:
|
||||||
|
build: ./main-site/photo-gallery-app/backend
|
||||||
|
container_name: bpb-gallery
|
||||||
ports:
|
ports:
|
||||||
- "5002:5000"
|
- "5002:5000"
|
||||||
|
environment:
|
||||||
|
MONGO_URI: mongodb://mongodb:27017/photogallery
|
||||||
|
WATERMARK_URL: http://watermarker:8000/watermark
|
||||||
volumes:
|
volumes:
|
||||||
- ./docker/osrm/data:/data
|
- ./main-site/photo-gallery-app/backend/uploads:/usr/src/app/uploads
|
||||||
command: osrm-routed --algorithm mld /data/connecticut-latest.osrm
|
depends_on:
|
||||||
|
- mongodb
|
||||||
|
- watermarker
|
||||||
|
restart: always
|
||||||
|
|
||||||
balloons-shop:
|
# ── Watermarker ───────────────────────────────────────────────────────────────
|
||||||
build: .
|
watermarker:
|
||||||
container_name: balloons-shop
|
build: ./main-site/photo-gallery-app/watermarker
|
||||||
|
container_name: bpb-watermarker
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
# ── MongoDB ───────────────────────────────────────────────────────────────────
|
||||||
|
mongodb:
|
||||||
|
image: mongo:latest
|
||||||
|
container_name: bpb-mongodb
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "27017:27017"
|
||||||
env_file:
|
volumes:
|
||||||
- .env
|
- ./mongodb_data:/data/db
|
||||||
|
restart: always
|
||||||
|
|
||||||
|
# ── eStore (Next.js / Square) ─────────────────────────────────────────────────
|
||||||
|
# NEXT_PUBLIC_* vars are baked into the JS bundle at build time.
|
||||||
|
# They are resolved from the root .env file (same dir as this compose file).
|
||||||
|
estore:
|
||||||
|
build:
|
||||||
|
context: ./estore
|
||||||
|
args:
|
||||||
|
NEXT_PUBLIC_SQUARE_APP_ID: ${NEXT_PUBLIC_SQUARE_APP_ID}
|
||||||
|
NEXT_PUBLIC_SQUARE_LOCATION_ID: ${NEXT_PUBLIC_SQUARE_LOCATION_ID}
|
||||||
|
NEXT_PUBLIC_SQUARE_ENVIRONMENT: ${NEXT_PUBLIC_SQUARE_ENVIRONMENT}
|
||||||
|
NEXT_PUBLIC_SITE_URL: ${NEXT_PUBLIC_SITE_URL}
|
||||||
|
container_name: bpb-estore
|
||||||
|
expose:
|
||||||
|
- "3000"
|
||||||
|
env_file: ./estore/.env
|
||||||
|
volumes:
|
||||||
|
- ./estore/data:/app/data
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on:
|
depends_on:
|
||||||
- osrm
|
- osrm
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/catalog"]
|
test: ["CMD", "node", "-e", "fetch('http://localhost:3000/shop/api/catalog').then(r=>{if(!r.ok)process.exit(1)}).catch(()=>process.exit(1))"]
|
||||||
interval: 30s
|
interval: 30s
|
||||||
timeout: 10s
|
timeout: 10s
|
||||||
retries: 3
|
retries: 3
|
||||||
|
|
||||||
|
# ── OSRM download (runs once, exits) ─────────────────────────────────────────
|
||||||
|
# Downloads the PBF map file into the shared volume if not already present.
|
||||||
|
osrm-download:
|
||||||
|
build:
|
||||||
|
context: ./osrm
|
||||||
|
dockerfile: Dockerfile.download
|
||||||
|
container_name: bpb-osrm-download
|
||||||
|
volumes:
|
||||||
|
- ./osrm/data:/data
|
||||||
|
environment:
|
||||||
|
OSRM_REGION: connecticut-latest
|
||||||
|
restart: "no"
|
||||||
|
|
||||||
|
# ── OSRM (routing engine) ─────────────────────────────────────────────────────
|
||||||
|
osrm:
|
||||||
|
build: ./osrm
|
||||||
|
container_name: bpb-osrm
|
||||||
|
expose:
|
||||||
|
- "5000"
|
||||||
|
volumes:
|
||||||
|
- ./osrm/data:/data
|
||||||
|
environment:
|
||||||
|
OSRM_REGION: connecticut-latest
|
||||||
|
OSRM_PROFILE: /opt/car.lua
|
||||||
|
depends_on:
|
||||||
|
osrm-download:
|
||||||
|
condition: service_completed_successfully
|
||||||
|
restart: unless-stopped
|
||||||
|
|||||||
49
estore/.env.example
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# ─── Square API ────────────────────────────────────────────────────────────────
|
||||||
|
# Get these from https://developer.squareup.com/apps
|
||||||
|
SQUARE_ACCESS_TOKEN=your_square_access_token_here
|
||||||
|
SQUARE_LOCATION_ID=your_square_location_id_here
|
||||||
|
# "sandbox" or "production"
|
||||||
|
SQUARE_ENVIRONMENT=sandbox
|
||||||
|
|
||||||
|
# These are exposed to the browser — use your Square Application ID (not access token)
|
||||||
|
# and the same location ID as above.
|
||||||
|
NEXT_PUBLIC_SQUARE_APP_ID=sandbox-sq0idb-your_app_id_here
|
||||||
|
NEXT_PUBLIC_SQUARE_LOCATION_ID=your_square_location_id_here
|
||||||
|
# "sandbox" or "production" — controls which Square JS SDK URL is loaded
|
||||||
|
NEXT_PUBLIC_SQUARE_ENVIRONMENT=sandbox
|
||||||
|
# Optional: ID of a Square category (Items > Categories) whose items appear in the shop.
|
||||||
|
# If set, only items in this category are shown. Otherwise falls back to src/config/shop-items.json.
|
||||||
|
SQUARE_SHOP_CATEGORY_ID=
|
||||||
|
|
||||||
|
# ─── CalDAV (Nextcloud) ────────────────────────────────────────────────────────
|
||||||
|
# Your Nextcloud CalDAV base URL — include trailing slash
|
||||||
|
CALDAV_URL=https://your-nextcloud.example.com/remote.php/dav/calendars/username/
|
||||||
|
CALDAV_USERNAME=your_nextcloud_username
|
||||||
|
# Use an app password (Settings > Security > Devices & sessions > App passwords)
|
||||||
|
CALDAV_PASSWORD=your_nextcloud_app_password
|
||||||
|
# Display name of the calendar to check for Busy blocks
|
||||||
|
CALDAV_CALENDAR_NAME=Deliveries
|
||||||
|
|
||||||
|
# ─── Email (SMTP — your mail server) ──────────────────────────────────────────
|
||||||
|
SMTP_HOST=mail.beachpartyballoons.com
|
||||||
|
SMTP_PORT=587
|
||||||
|
SMTP_USER=shop@beachpartyballoons.com
|
||||||
|
SMTP_PASS=your_email_password_here
|
||||||
|
# Address that receives new-order & slot-conflict alerts (you/staff)
|
||||||
|
ALERT_EMAIL_TO=you@beachpartyballoons.com
|
||||||
|
# Sender shown on outgoing emails
|
||||||
|
ALERT_EMAIL_FROM=shop@beachpartyballoons.com
|
||||||
|
|
||||||
|
# ─── Admin panel ───────────────────────────────────────────────────────────────
|
||||||
|
# Password to access /admin — keep this secret
|
||||||
|
ADMIN_PASSWORD=change_me_to_something_strong
|
||||||
|
# Secret token for the cron cache-refresh endpoint (POST /api/cache/refresh)
|
||||||
|
CACHE_REFRESH_SECRET=change_me_to_something_random
|
||||||
|
|
||||||
|
# ─── OSRM (self-hosted routing) ────────────────────────────────────────────────
|
||||||
|
# Leave blank to use the public demo server (unreliable). Self-host for production:
|
||||||
|
# https://hub.docker.com/r/osrm/osrm-backend
|
||||||
|
OSRM_URL=http://localhost:5000
|
||||||
|
|
||||||
|
# ─── Site ──────────────────────────────────────────────────────────────────────
|
||||||
|
NEXT_PUBLIC_SITE_URL=http://localhost:3000
|
||||||
32
estore/.gitignore
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# dependencies
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next/
|
||||||
|
out/
|
||||||
|
|
||||||
|
# Runtime data — cache and item overrides change at runtime, don't track them
|
||||||
|
data/catalog-cache.json
|
||||||
|
data/item-overrides.json
|
||||||
|
|
||||||
|
# Environment variables — never commit these
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env*.local
|
||||||
|
|
||||||
|
# OS / editor
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Raw/duplicate image files — use public/images/ directly
|
||||||
|
public/images/pics/
|
||||||
|
*.heic
|
||||||
@ -10,6 +10,18 @@ WORKDIR /app
|
|||||||
COPY --from=deps /app/node_modules ./node_modules
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY . .
|
COPY . .
|
||||||
ENV NEXT_TELEMETRY_DISABLED=1
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
|
||||||
|
# NEXT_PUBLIC_* vars are baked into the JS bundle at build time.
|
||||||
|
# Pass them as build args from your .env so they're available here.
|
||||||
|
ARG NEXT_PUBLIC_SQUARE_APP_ID
|
||||||
|
ARG NEXT_PUBLIC_SQUARE_LOCATION_ID
|
||||||
|
ARG NEXT_PUBLIC_SQUARE_ENVIRONMENT
|
||||||
|
ARG NEXT_PUBLIC_SITE_URL
|
||||||
|
ENV NEXT_PUBLIC_SQUARE_APP_ID=$NEXT_PUBLIC_SQUARE_APP_ID
|
||||||
|
ENV NEXT_PUBLIC_SQUARE_LOCATION_ID=$NEXT_PUBLIC_SQUARE_LOCATION_ID
|
||||||
|
ENV NEXT_PUBLIC_SQUARE_ENVIRONMENT=$NEXT_PUBLIC_SQUARE_ENVIRONMENT
|
||||||
|
ENV NEXT_PUBLIC_SITE_URL=$NEXT_PUBLIC_SITE_URL
|
||||||
|
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# ── Stage 3: Production runner ────────────────────────────────────────────────
|
# ── Stage 3: Production runner ────────────────────────────────────────────────
|
||||||
@ -26,6 +38,11 @@ COPY --from=builder /app/public ./public
|
|||||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
|
# Ensure the data directory exists and is writable by the nextjs user.
|
||||||
|
# For bind-mount deployments, the host directory must also be owned by uid 1001:
|
||||||
|
# sudo chown -R 1001:1001 estore/data
|
||||||
|
RUN mkdir -p /app/data && chown nextjs:nodejs /app/data
|
||||||
|
|
||||||
USER nextjs
|
USER nextjs
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
ENV PORT=3000
|
ENV PORT=3000
|
||||||
11
estore/data/categories-display.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"order": [
|
||||||
|
"latex",
|
||||||
|
"birthday",
|
||||||
|
"mylar-bouquets",
|
||||||
|
"graduation",
|
||||||
|
"letters-and-numbers",
|
||||||
|
"other"
|
||||||
|
],
|
||||||
|
"hidden": []
|
||||||
|
}
|
||||||
8
estore/data/occasions.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"mothers-day": {
|
||||||
|
"windowStart": "04-10"
|
||||||
|
},
|
||||||
|
"graduation": {
|
||||||
|
"windowStart": "04-01"
|
||||||
|
}
|
||||||
|
}
|
||||||
26
estore/docker-compose.yml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
services:
|
||||||
|
osrm:
|
||||||
|
image: osrm/osrm-backend
|
||||||
|
container_name: osrm
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "5002:5000"
|
||||||
|
volumes:
|
||||||
|
- ./docker/osrm/data:/data
|
||||||
|
command: osrm-routed --algorithm mld /data/connecticut-latest.osrm
|
||||||
|
|
||||||
|
balloons-shop:
|
||||||
|
build: .
|
||||||
|
container_name: balloons-shop
|
||||||
|
ports:
|
||||||
|
- "3000:3000"
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- osrm
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "-qO-", "http://localhost:3000/api/catalog"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
0
next-env.d.ts → estore/next-env.d.ts
vendored
@ -3,6 +3,10 @@ const isDev = process.env.NODE_ENV === 'development'
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
output: 'standalone',
|
output: 'standalone',
|
||||||
|
basePath: '/shop',
|
||||||
|
env: {
|
||||||
|
NEXT_PUBLIC_BASE_PATH: '/shop',
|
||||||
|
},
|
||||||
images: {
|
images: {
|
||||||
remotePatterns: [
|
remotePatterns: [
|
||||||
{ protocol: 'https', hostname: 'items-images-production.s3.us-west-2.amazonaws.com' },
|
{ protocol: 'https', hostname: 'items-images-production.s3.us-west-2.amazonaws.com' },
|
||||||
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 228 KiB After Width: | Height: | Size: 228 KiB |
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 160 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 136 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 2.4 MiB After Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 164 KiB |
|
Before Width: | Height: | Size: 130 KiB After Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 180 KiB After Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
|
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 85 KiB |
|
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 123 KiB |
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 225 KiB After Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 521 KiB After Width: | Height: | Size: 521 KiB |
|
Before Width: | Height: | Size: 213 KiB After Width: | Height: | Size: 213 KiB |
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 126 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 137 KiB |
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 109 KiB |
|
Before Width: | Height: | Size: 515 B After Width: | Height: | Size: 515 B |
|
Before Width: | Height: | Size: 515 B After Width: | Height: | Size: 515 B |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 738 B After Width: | Height: | Size: 738 B |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 932 KiB After Width: | Height: | Size: 932 KiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 877 KiB After Width: | Height: | Size: 877 KiB |
|
Before Width: | Height: | Size: 2.2 MiB After Width: | Height: | Size: 2.2 MiB |
|
Before Width: | Height: | Size: 827 KiB After Width: | Height: | Size: 827 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 738 B After Width: | Height: | Size: 738 B |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 689 KiB After Width: | Height: | Size: 689 KiB |
|
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 2.8 MiB |
|
Before Width: | Height: | Size: 3.2 MiB After Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 1.3 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.7 MiB After Width: | Height: | Size: 1.7 MiB |
|
Before Width: | Height: | Size: 890 KiB After Width: | Height: | Size: 890 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 890 KiB After Width: | Height: | Size: 890 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 519 KiB After Width: | Height: | Size: 519 KiB |
|
Before Width: | Height: | Size: 739 KiB After Width: | Height: | Size: 739 KiB |
|
Before Width: | Height: | Size: 2.0 MiB After Width: | Height: | Size: 2.0 MiB |
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.8 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |