Environments and releases
Local, staging, pre-production and production — what each holds, who deploys and when — and how deployments, migrations, mobile release trains, versions, changelogs, rollbacks, feature flags and maintenance mode work.
The cahier asks for three environments — development, pre-production / recette client, production (cahier §13.1, OPS-01). The team adds staging for continuous integration. Servers, Dokploy projects, backups and monitoring are described in the architecture and deployment and operations; this page holds the rules the team follows.
The four environments
| Environment | Purpose | Deployed from | When | Data | Used by |
|---|---|---|---|---|---|
| Local | Development | Your working tree | Any time | Demo seed (OPS-01) | The developer |
| Staging | Integration, team testing, internal demos | dev | Automatically, on every merge | Demo seed, one test account per role; reset when needed (announced in the team group) | The team only |
| Pre-production (recette) | HOCO's hands-on tests, acceptance, rehearsal of the production import | Release candidates: tag vX.Y.Z-rc.N on release/x.y.z | When Anis tags a candidate, announced to HOCO's testers | HOCO's real catalogue, test resellers and delegates; never real customers' personal data without HOCO's written agreement | HOCO's testers and the team |
| Production | The business | Tag vX.Y.Z on master | In a deploy window, triggered by Anis | Real data | HOCO, delegates, resellers |
| Local | Staging | Pre-production | Production | |
|---|---|---|---|---|
| API | http://localhost:3100/v1 | https://api-staging.hoco.dz/v1 | https://api-preprod.hoco.dz/v1 | https://api.hoco.dz/v1 |
| Back-office | http://localhost:3101 | https://admin-staging.hoco.dz | https://admin-preprod.hoco.dz | https://admin.hoco.dz |
| Reseller web | http://localhost:3102 | https://app-staging.hoco.dz | https://app-preprod.hoco.dz | https://app.hoco.dz |
| Mobile flavor | dev (mock or local API) | staging | staging flavor built against pre-production | prod |
/reference (Scalar) | Yes | Yes | Yes | Disabled |
| Server | Laptop, docker compose | VPS 2, Dokploy project staging | VPS 2, Dokploy project preprod | VPS 1, Dokploy project production |
Assumption — hoco.dz and the host names are placeholders until HOCO confirms the domains (decision register). The docs site is deployed on the VPS with restricted access, from dev, so it always shows the latest plan and contract. How each environment is set up in GitHub and Dokploy is in the deployment runbook.
Local services (pnpm db:start): PostgreSQL 17 on 5442, Redis 7 on 6390, MinIO on 9100 (console 9101), Mailpit SMTP on 1125 and UI on 8125.
Rules per environment
- Staging may break, but not for long. A failed deploy or a broken main flow on staging is fixed or reverted within 2 working hours — it blocks Imad's integration and Akram's design QA.
- Pre-production is frozen during HOCO's test sessions. No candidate is deployed while a session runs; candidates go out before 09:00 or after the session, with French notes listing the fixes.
- Production deploy windows: Sunday to Wednesday, 09:00–14:00. Never on Thursday (the weekend follows), never on the eve of a public holiday, never during the first two days of the pilot. Exception: a hotfix for a Blocker, at any time, with HOCO informed.
- Data never flows down unmasked. After go-live, a copy of production for pre-production has phone numbers, names, e-mails and positions of resellers and delegates replaced. Staging never receives production data.
- Every environment is isolated: its own database, Redis, buckets, secrets, cookie prefix and Firebase project.
Deployment flow
- The image recipe is
docker/app.Dockerfilewith theAPPbuild argument (server,dashboard,web). Theworkerruns from the server image (ADR-004). - The server image is built once per commit and promoted: production runs the exact server image that passed pre-production.
- The Next apps are rebuilt per environment from the same commit, because
NEXT_PUBLIC_*values are inlined at build time. Nothing else differs between those builds. - Images are tagged with the commit SHA and the version. CI triggers the staging and pre-production deploys; the production deploy is triggered by Anis, never by a merge.
Order of a deployment
The server goes first, the mobile apps last.
- Backup. Production: a fresh dump before every deploy that contains a migration, on top of the nightly backups.
- Migrations. The new
apicontainer runsprisma migrate deployat start-up, before it accepts traffic; theworkernever migrates. Migrations are additive (expand then contract), so the previous version keeps working while they run. apiandworker. The newapimust answer/ready(database, Redis, migrations) before the old one stops.- Smoke test.
/healthreturns the new version; a back-office sign-in; one read per app; one job processed by the worker. - Back-office and reseller web.
- Mobile apps. A store release goes out only when the server version it needs is in production. The server stays compatible with every app version at or above the minimum version.
- Version policy. If the new app version must be forced, raise the minimum in BO-66.
Mobile release trains
| Train | Flavor | Built from | Distributed through | Audience | Cadence |
|---|---|---|---|---|---|
| Development | dev | The working tree | flutter run | Imad | — |
| Team | staging | Every merge into dev in hoco-mobile | Firebase App Distribution, group team | Anis, Imad, Akram | Continuous |
| Acceptance | staging, pointed at pre-production | vX.Y.Z-rc.N tags on release/x.y.z | Firebase App Distribution, group hoco-recette | HOCO's testers | Per candidate |
| Internal | prod | Release tag | Play internal testing | The team (smoke test against production) | Per release |
| Pilot | prod | Release tag | Play closed testing | Pilot delegates and resellers | From go-live (LCH-01) |
| Public | prod | Release tag | Play production, staged rollout 20 % → 50 % → 100 % over three working days | Everyone | From generalisation (LCH-05) |
| iOS | prod | Release tag | TestFlight, then the App Store | — | Only if iOS is confirmed (D-10, MOB-16) |
- A staged rollout is halted as soon as the crash-free rate of the new version drops under 99 % or a Blocker is reported.
- Closed testing means a testers list. Every pilot reseller and delegate must be on the list (by e-mail or through a Google Group) before the invitation link can open the store page. The pilot list is prepared with HOCO before training (LCH-02); unplanned sign-ups during the pilot are added to the group the same day.
- The first submission of each app, the data-safety form and the location declaration are reviewed by Google and can take several days: they are done in MOB-14, well before go-live.
versionNamecomes from the tag;versionCodeis the CI run number. Both apps share the version line; an app that did not change is not uploaded.
Versions and changelogs
| Line | Format | Tag | Shown in |
|---|---|---|---|
| Platform (server, back-office, reseller web) | X.Y.Z | vX.Y.Z in hoco | /health, the back-office and web footers |
| Mobile apps | X.Y.Z + build number | vX.Y.Z in hoco-mobile | The app's settings screen, the X-App-Version header |
| API contract | X.Y.Z | contracts-vX.Y.Z in hoco | Contract changelog |
| Release candidates | X.Y.Z-rc.N | vX.Y.Z-rc.N | Pre-production |
| Version | Meaning |
|---|---|
0.x.y | Candidates before go-live, on pre-production for HOCO |
1.0.0 | The release accepted in the PV and put live (LCH-01) |
1.0.z | Pilot fixes |
1.y.0 | Pilot improvements, the reseller web, generalisation |
2.0.0 | V2 delivered — the API stays /v1, because V2 is additive |
CHANGELOG.mdat the root of each repository, written in the release PR from the squash commits since the previous tag (git log --oneline v0.3.0..HEAD), grouped Added, Changed, Fixed, with task ids.- Release notes for HOCO, in French, short and per app (back-office, reseller app, delegate app, reseller web). Sent with each candidate and each production release, and summarised on the Progress page.
- Play "What's new": French, at most 500 characters per app.
Release checklist
Before cutting:
- Every task planned for the release is done per the definition of done on staging; what is not ready is behind a flag.
- No Blocker or Critical issue open on the release's GitHub milestone.
Cut and candidate:
-
release/x.y.zcreated fromdev; versions bumped;CHANGELOG.mdwritten; release PR intomasteropened as a draft. -
vX.Y.Z-rc.1tagged; pre-production deployed; migrations ran; smoke test passed. - HOCO's testers notified: French notes, what to test, known issues.
Acceptance:
- The release's acceptance scenarios pass on pre-production — for
1.0.0, the priority scenarios of cahier §12 (acceptance scenarios, QA-02). - Every fix landed on the release branch and was merged back into
dev.
Go:
- The last nightly backup succeeded; a restore has been tested at least once (SRV-28).
- No contracted operation of the release answers
501 NOT_IMPLEMENTED. - Monitoring and alerts green; the Sentry release created.
- HOCO informed of the production window at least 24 hours ahead, with the notes.
- Merge into
master, tag, production deploy in the window, smoke test. -
mastermerged back intodev; milestone closed; GitHub Release published with the notes. - Mobile: store release after the server; minimum and latest versions updated in BO-66.
Rollback
| Component | How | Time |
|---|---|---|
| Server, back-office, reseller web | Redeploy the previous image tag in Dokploy | 10 minutes at most |
| Database | Fix forward with a new migration — migrations are additive, so the previous code still runs on the new schema. A restore from backup is only for data corruption: Anis decides it, HOCO is informed, and the data written since the backup is lost | — |
| Mobile apps | No rollback of installed apps: halt the staged rollout, switch the feature off by flag, ship a hotfix with a higher version, force the update through BO-66, and as a last resort turn on maintenance mode | Hours, plus store review |
| Contract | Additive changes are never rolled back; a broken new operation is fixed forward | — |
If the smoke test of a production deploy fails, roll back first, investigate after.
Feature flags
- Business settings are product features, not flags: order minimums, payment methods, GPS tolerance and the other parameters of ADM-03, edited in BO-64 through
admin.settings.update. - Release flags hide unfinished or V2 features: boolean settings named
feature.<name>, delivered to the apps with the public settings ofappConfig.get. The back-office hides V2 items until their release flag is on. - Rules: off by default in production; each flag has an owner and a removal task; a flag is removed at most two releases after it is on everywhere; flags never replace permissions (those are RBAC).
- Assumption — the
feature.*naming and its delivery through app-config are confirmed in SRV-07 (settings service).
Maintenance mode
- Switch: BO-66, through
admin.appVersions.crud(ADM-07). The API answers503 MAINTENANCEwithdetails.until; the apps show their system state (RA-36, DA-28); the delegate app keeps working offline and syncs afterwards. - When: a migration that cannot run online, infrastructure work, a security incident.
- Planned maintenance is announced to HOCO 48 hours ahead, outside field hours (after 20:00, Sunday to Wednesday), never during the pilot's first week and never during Ramadan.
- Forced update: raising the minimum version of an app and platform makes the API answer
426 UPGRADE_REQUIREDwithdetails.storeUrl.
Design workflow
How Akram's designs flow into development: Claude Design organisation and statuses, the 21-day checkpoints, the daily feasibility check, the handoff package, design QA, changes after handoff and HOCO's validation of the designs.
Deployment runbook
How CI, the image workflow and Dokploy fit together for staging, pre-production and production: GitHub environments, variables and secrets, Dokploy projects and apps, env groups, domains and TLS, migrations and rollback, backups, the docs site, branch protection, and the one-time setup checklist.