{"_id":"@42wp/dev-env","_rev":"7-444878f627eca27071aaeb90657fbae0","name":"@42wp/dev-env","dist-tags":{"latest":"1.0.7"},"versions":{"1.0.0":{"name":"@42wp/dev-env","version":"1.0.0","keywords":["wordpress","docker","cli","dev-environment","traefik","wp-cli","42wp"],"author":{"name":"João Carvalho","email":"joao@carvalho.cc"},"license":"MIT","_id":"@42wp/dev-env@1.0.0","maintainers":[{"name":"jv.carvalho","email":"joao@carvalho.cc"}],"homepage":"https://github.com/42wp/dev-env#readme","bugs":{"url":"https://github.com/42wp/dev-env/issues"},"bin":{"42wp":"bin/42wp.js"},"dist":{"shasum":"b44f3ad174a2a2394db5d8b08431da28ded0b270","tarball":"https://registry.npmjs.org/@42wp/dev-env/-/dev-env-1.0.0.tgz","fileCount":33,"integrity":"sha512-ChrxAZYoEHbyth5sFXRIAT1orfOXTdQWu28Elt3RAWpxrZA87mIuSrJCblk3b8FmcppcaCInkXpGkM9rh3tY9Q==","signatures":[{"sig":"MEYCIQDrDRCYIYAm9GdXjTFxG3Yh9PBIHTnjjoCSI3vAEJ98hwIhAL2d84bBTGl5tCl2yW3n4QXA4jBbHrMEHVRhOknU0kUR","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":72852},"type":"module","engines":{"node":">=18.17"},"gitHead":"67f3eb50eb065a695c35b5728429207bb82c37e6","scripts":{"test":"node --test","prepublishOnly":"node --test"},"_npmUser":{"name":"jv.carvalho","email":"joao@carvalho.cc"},"repository":{"url":"git+https://github.com/42wp/dev-env.git","type":"git"},"_npmVersion":"11.6.2","description":"42WP — a CLI to spin up disposable WordPress dev environments with Docker (Traefik + MySQL + per-project containers).","directories":{},"_nodeVersion":"24.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/dev-env_1.0.0_1782492590674_0.4189530814442435","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@42wp/dev-env","version":"1.0.1","keywords":["wordpress","docker","cli","dev-environment","traefik","wp-cli","42wp"],"author":{"name":"João Carvalho","email":"joao@carvalho.cc"},"license":"MIT","_id":"@42wp/dev-env@1.0.1","maintainers":[{"name":"jv.carvalho","email":"joao@carvalho.cc"}],"homepage":"https://github.com/42wp/dev-env#readme","bugs":{"url":"https://github.com/42wp/dev-env/issues"},"bin":{"42wp":"bin/42wp.js"},"dist":{"shasum":"b55721bffe8fa5e504f12d790e3ef52733d00d83","tarball":"https://registry.npmjs.org/@42wp/dev-env/-/dev-env-1.0.1.tgz","fileCount":33,"integrity":"sha512-yn461+fiY1tOXefOj7ht6oYJvoNs6trsNwQJcwx3R/oZWU2zXEjFwnYUjE0bsVo36+bM/o0fXytwFUUdqZbB0g==","signatures":[{"sig":"MEQCIAl1ieBW1TbE6iWS/m2WXk4qIugSw4b8rFNHafwZW69HAiBwR+PRLjwue49BlY7ldj4BCNerdNtY4N8B7i7gB+T4cQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":73416},"type":"module","engines":{"node":">=18.17"},"gitHead":"700429336a61355c0406671836e641749a799b48","scripts":{"test":"node --test","prepublishOnly":"node --test"},"_npmUser":{"name":"jv.carvalho","email":"joao@carvalho.cc"},"repository":{"url":"git+https://github.com/42wp/dev-env.git","type":"git"},"_npmVersion":"11.6.2","description":"42WP — a CLI to spin up disposable WordPress dev environments with Docker (Traefik + MySQL + per-project containers).","directories":{},"_nodeVersion":"24.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/dev-env_1.0.1_1782847250688_0.315583240315243","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@42wp/dev-env","version":"1.0.3","keywords":["wordpress","docker","cli","dev-environment","traefik","wp-cli","42wp"],"author":{"name":"João Carvalho","email":"joao@carvalho.cc"},"license":"MIT","_id":"@42wp/dev-env@1.0.3","maintainers":[{"name":"jv.carvalho","email":"joao@carvalho.cc"}],"homepage":"https://github.com/42wp/dev-env#readme","bugs":{"url":"https://github.com/42wp/dev-env/issues"},"bin":{"42wp":"bin/42wp.js"},"dist":{"shasum":"2016b491f8f318cf9fc49557fcdd3a296b0bbfae","tarball":"https://registry.npmjs.org/@42wp/dev-env/-/dev-env-1.0.3.tgz","fileCount":36,"integrity":"sha512-d7kimcgFfO82gQ5ytYCBlvhGdfjFq2bqqb2nbaGo0aJQyZuH/X8BzTNDI8oeC46PO2shsbPdTKIQXUZLd6u4IQ==","signatures":[{"sig":"MEYCIQDto7jEye9FbER+82XnuYnc8tGa2DV0XsqDM0F/HlsWggIhANAeA09UlI9MrHomh0feuCkFkSDQiHI2De3RHL985lie","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":99692},"type":"module","engines":{"node":">=18.17"},"gitHead":"3112cf2b22a2ea182148da62b548df20215a3165","scripts":{"test":"node --test","prepublishOnly":"node --test"},"_npmUser":{"name":"jv.carvalho","email":"joao@carvalho.cc"},"repository":{"url":"git+https://github.com/42wp/dev-env.git","type":"git"},"_npmVersion":"11.6.2","description":"42WP — a CLI to spin up disposable WordPress dev environments with Docker (Traefik + MySQL + per-project containers).","directories":{},"_nodeVersion":"24.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/dev-env_1.0.3_1783538007543_0.004402092689862691","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@42wp/dev-env","version":"1.0.4","keywords":["wordpress","docker","cli","dev-environment","traefik","wp-cli","42wp"],"author":{"name":"João Carvalho","email":"joao@carvalho.cc"},"license":"MIT","_id":"@42wp/dev-env@1.0.4","maintainers":[{"name":"jv.carvalho","email":"joao@carvalho.cc"}],"homepage":"https://github.com/42wp/dev-env#readme","bugs":{"url":"https://github.com/42wp/dev-env/issues"},"bin":{"42wp":"bin/42wp.js"},"dist":{"shasum":"9c283992a4fe11bb32344ba589fd1d36e4b36cec","tarball":"https://registry.npmjs.org/@42wp/dev-env/-/dev-env-1.0.4.tgz","fileCount":36,"integrity":"sha512-rg8RI7GGUwZVDcr3WkWy/IH/xhXMAZDw3qTIi+DCWECaxU9YHFHvRJ4hF6k6CRU8L26PTkfTgec0CVE8RB348A==","signatures":[{"sig":"MEQCIFK9zKQ/rgqp7lKYogNnGycu2N5yEgYfdckkyYJvIWATAiANM0KfYLGZjdRNeem95Lh706CWYWD6gT2DmmMc/T3NAw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":99648},"type":"module","engines":{"node":">=18.17"},"gitHead":"5bd05b3aa65bf43a9ba4424d989f09535babe38d","scripts":{"test":"node --test","prepublishOnly":"node --test"},"_npmUser":{"name":"jv.carvalho","email":"joao@carvalho.cc"},"repository":{"url":"git+https://github.com/42wp/dev-env.git","type":"git"},"_npmVersion":"11.6.2","description":"42WP — a CLI to spin up disposable WordPress dev environments with Docker (Traefik + MySQL + per-project containers).","directories":{},"_nodeVersion":"24.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/dev-env_1.0.4_1783542037226_0.05845304244157923","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@42wp/dev-env","version":"1.0.5","keywords":["wordpress","docker","cli","dev-environment","traefik","wp-cli","42wp"],"author":{"name":"João Carvalho","email":"joao@carvalho.cc"},"license":"MIT","_id":"@42wp/dev-env@1.0.5","maintainers":[{"name":"jv.carvalho","email":"joao@carvalho.cc"}],"homepage":"https://github.com/42wp/dev-env#readme","bugs":{"url":"https://github.com/42wp/dev-env/issues"},"bin":{"42wp":"bin/42wp.js"},"dist":{"shasum":"6fcbd46955ec8fa1bcb28100709d44137bd618ce","tarball":"https://registry.npmjs.org/@42wp/dev-env/-/dev-env-1.0.5.tgz","fileCount":36,"integrity":"sha512-k+ONcDRdczHD4eLAi9th6KITFH2A/RNpoQn4FKOK5iJVv8GanI0x2uqIb76xf0CjsrYO/ys1g5qPS+Z87WIdCA==","signatures":[{"sig":"MEQCIAPBjr8xtsrTdPnHb12GbfVe5kIkMWz5L630gSpfZY1vAiBI5KSbzueYWkGHRuTDUFKRomqBikedaesQKWmbDmQAIA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":100290},"type":"module","engines":{"node":">=18.17"},"gitHead":"79bc7cb466b30248ffa60b90e8aeabf791cfa83d","scripts":{"test":"node --test","prepublishOnly":"node --test"},"_npmUser":{"name":"jv.carvalho","email":"joao@carvalho.cc"},"repository":{"url":"git+https://github.com/42wp/dev-env.git","type":"git"},"_npmVersion":"11.6.2","description":"42WP — a CLI to spin up disposable WordPress dev environments with Docker (Traefik + MySQL + per-project containers).","directories":{},"_nodeVersion":"24.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/dev-env_1.0.5_1783975183809_0.14332412564331154","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@42wp/dev-env","version":"1.0.6","keywords":["wordpress","docker","cli","dev-environment","traefik","wp-cli","42wp"],"author":{"name":"João Carvalho","email":"joao@carvalho.cc"},"license":"MIT","_id":"@42wp/dev-env@1.0.6","maintainers":[{"name":"jv.carvalho","email":"joao@carvalho.cc"}],"homepage":"https://github.com/42wp/dev-env#readme","bugs":{"url":"https://github.com/42wp/dev-env/issues"},"bin":{"42wp":"bin/42wp.js"},"dist":{"shasum":"d2f0a481de18ce2308010e186b5d10ba5f197414","tarball":"https://registry.npmjs.org/@42wp/dev-env/-/dev-env-1.0.6.tgz","fileCount":37,"integrity":"sha512-kubjiwYpqCBWnWK5vBnZgF9WVIdS1BhfRPc/a6JA8VlqVm8p4PEMkgdI9MIsy3AZwVyrPy1lwM6G95KilggXpw==","signatures":[{"sig":"MEUCIQD4lKKnLkspqZD3WJ/3YNvOqU/XkJe8EgR1HbDJ1uuIhwIgMgzwYyMSFktAAbji/I0Cl1OjvWtlIF1WDtZCZhwjh64=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":105995},"type":"module","engines":{"node":">=18.17"},"gitHead":"23fe87576e36543948deea2bb53d5f6291a4bf9c","scripts":{"test":"node --test","prepublishOnly":"node --test"},"_npmUser":{"name":"jv.carvalho","email":"joao@carvalho.cc"},"repository":{"url":"git+https://github.com/42wp/dev-env.git","type":"git"},"_npmVersion":"11.6.2","description":"42WP — a CLI to spin up disposable WordPress dev environments with Docker (Traefik + MySQL + per-project containers).","directories":{},"_nodeVersion":"24.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/dev-env_1.0.6_1783997351284_0.07326427737284513","host":"s3://npm-registry-packages-npm-production"}},"1.0.7":{"name":"@42wp/dev-env","version":"1.0.7","description":"42WP — a CLI to spin up disposable WordPress dev environments with Docker (Traefik + MySQL + per-project containers).","type":"module","bin":{"42wp":"bin/42wp.js"},"engines":{"node":">=18.17"},"repository":{"type":"git","url":"git+https://github.com/42wp/dev-env.git"},"bugs":{"url":"https://github.com/42wp/dev-env/issues"},"homepage":"https://github.com/42wp/dev-env#readme","keywords":["wordpress","docker","cli","dev-environment","traefik","wp-cli","42wp"],"author":{"name":"João Carvalho","email":"joao@carvalho.cc"},"license":"MIT","publishConfig":{"access":"public"},"scripts":{"test":"node --test"},"_id":"@42wp/dev-env@1.0.7","_integrity":"sha512-E2X35VL/egpYTkvOaK7G+OI8m0malHiqhvxQa7E5OOILDdo7AUM56M6uZPO43SaNqzICp0aw+Az0NjFG6fAWuw==","_resolved":"/private/var/folders/p0/fjf2nqg56gl47_3667lbsv5c0000gn/T/e97ffa439259c6b2d10101ba5888cafc/42wp-dev-env-1.0.7.tgz","_from":"file:42wp-dev-env-1.0.7.tgz","_nodeVersion":"24.12.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-E2X35VL/egpYTkvOaK7G+OI8m0malHiqhvxQa7E5OOILDdo7AUM56M6uZPO43SaNqzICp0aw+Az0NjFG6fAWuw==","shasum":"a1b82372e51eeaaaa2367e3a74e5a662a221c991","tarball":"https://registry.npmjs.org/@42wp/dev-env/-/dev-env-1.0.7.tgz","fileCount":37,"unpackedSize":107182,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBggdKtBPaxVZ+b9gAKHh/8fQbtPs5zMrEYgz99Ia7ZJAiEAmm72vHMcX2ytP/Od0UHgzHU6WSHiM4WdTCGRTLDed5s="}]},"_npmUser":{"name":"jv.carvalho","email":"joao@carvalho.cc"},"directories":{},"maintainers":[{"name":"jv.carvalho","email":"joao@carvalho.cc"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dev-env_1.0.7_1784314017323_0.767376381205878"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-26T16:49:50.481Z","modified":"2026-07-17T18:46:57.657Z","1.0.0":"2026-06-26T16:49:50.830Z","1.0.1":"2026-06-30T19:20:50.823Z","1.0.3":"2026-07-08T19:13:27.672Z","1.0.4":"2026-07-08T20:20:37.356Z","1.0.5":"2026-07-13T20:39:43.981Z","1.0.6":"2026-07-14T02:49:11.510Z","1.0.7":"2026-07-17T18:46:57.482Z"},"bugs":{"url":"https://github.com/42wp/dev-env/issues"},"author":{"name":"João Carvalho","email":"joao@carvalho.cc"},"license":"MIT","homepage":"https://github.com/42wp/dev-env#readme","keywords":["wordpress","docker","cli","dev-environment","traefik","wp-cli","42wp"],"repository":{"type":"git","url":"git+https://github.com/42wp/dev-env.git"},"description":"42WP — a CLI to spin up disposable WordPress dev environments with Docker (Traefik + MySQL + per-project containers).","maintainers":[{"name":"jv.carvalho","email":"joao@carvalho.cc"}],"readme":"# 42wp — 42WP dev environments\n\n> *O Guia do Mochileiro do WordPress* — a tiny CLI that spins up disposable\n> WordPress dev environments with Docker, the 42WP way.\n\n`42wp` runs a shared **global layer** (Traefik reverse proxy + MySQL + phpMyAdmin +\nMailpit) and, on top of it, **per-project** WordPress containers reachable at\n`http://<project>.localhost`. Your current working directory is mounted as\n`wp-content`, so you develop your theme/plugin locally and WordPress runs in a\ncontainer with Xdebug, Memcached and WP-CLI preinstalled.\n\n## Requirements\n\n- [Docker](https://docs.docker.com/get-docker/) with the Compose v2 plugin (`docker compose`)\n- Node.js **>= 18.17**\n\n## Install\n\n```bash\nnpm install -g @42wp/dev-env\n```\n\nThis installs the `42wp` command globally.\n\n## Usage\n\n```bash\n42wp init [project]        # scaffold a .42wp-dev-env with this project's options\n42wp global start          # start Traefik + MySQL + phpMyAdmin + Mailpit\n42wp start <project>       # build & start a project (run from your theme/plugin repo)\n42wp update <project>      # update an existing project to a newer WordPress image\n42wp wp <project> <args>   # run a WP-CLI command inside the project container\n42wp stop <project>        # stop a project's containers\n42wp rm <project>          # remove a site (container, image, database) — keeps your repo\n42wp seed <project> [n]    # generate demo content in a running project (default 200)\n42wp global stop           # tear the global layer down\n```\n\nRun `42wp` with no arguments for the full command list.\n\n### Project config (`.42wp-dev-env`)\n\nDrop a `.42wp-dev-env` file in your project repo to save its `42wp start` options,\nso you (and your team) can just run `42wp start` with no flags. Scaffold one with\n`42wp init`:\n\n```bash\n42wp init mysite --subdomains --vip --locale pt_BR --theme my-theme --demo-content\n```\n\nThat writes:\n\n```ini\nproject_slug=mysite\nmultisite=subdomain      # false | subdir | subdomain\nusername=admin\npassword=password\nlocale=pt_BR\ndefault_theme=my-theme\nwpvip=true\ninitial_content=200\n```\n\n`42wp start`, run in that directory, reads the file and applies it — and **CLI\nflags override** any value for a one-off run. With `project_slug` set you can run\n`42wp start` with no name. `42wp init` won't overwrite an existing file unless you\npass `--force`.\n\n| Key | Effect |\n| --- | --- |\n| `project_slug`        | project name (so `42wp start` needs no argument) |\n| `multisite`           | `false`, `subdir` or `subdomain` |\n| `username` / `password` | admin credentials (plaintext — local dev only) |\n| `locale`              | WordPress site language, e.g. `pt_BR` (`pt-br` is normalized) |\n| `default_theme`       | theme to `wp theme activate` after install |\n| `wpvip`               | clone + mount the VIP mu-plugins |\n| `initial_content`     | `true` (200 posts) or a number |\n\n### Project dependencies\n\nBefore installing WordPress, `42wp start` installs the project's dependencies in\nyour repo so WordPress and its mu-plugins load cleanly:\n\n- `composer install` — when `composer.json` is present\n- `<pm> install` — when `package.json` is present, where `<pm>` is inferred from the\n  lockfile: `pnpm-lock.yaml` → **pnpm**, `yarn.lock` → **yarn**, `package-lock.json`\n  → **npm** (defaults to npm)\n\nThese run **on your machine**, in the mounted repo, before the containers start.\n**Composer is required**: if a project has a `composer.json` and its PHP\ndependencies can't be installed (composer missing, or the install fails), `start`\nstops — a project with unmet PHP deps would break during the WordPress install\nanyway. The JS install is best-effort (a missing tool or failure just warns). Skip\nthe whole step with `--skip-deps`:\n\n```bash\n42wp start my-site --skip-deps\n```\n\n### WordPress version\n\nBy default projects are built on **`wordpress:php8.4-apache`** (newest WordPress,\nPHP 8.4, Apache). Pick a different image tag per project with `--wp <tag>`:\n\n```bash\n42wp start my-theme --wp latest             # newest WP, image's default PHP\n42wp start legacy   --wp 6.9-php8.5-apache  # pin a specific WP + PHP\n42wp update my-theme                        # rebuild on the default tag, run wp core update-db\n42wp update my-theme --wp php8.5-apache     # update to a specific image\n```\n\n`update` rewrites the project's Dockerfile, re-pulls the base image, recreates the\ncontainer and runs `wp core update-db` to migrate the schema. Set a different\ndefault for every project with the `FORTYTWO_WP_TAG` env var.\n\n### Removing a site\n\n`42wp rm <project>` tears a site down completely — its containers, the locally\nbuilt image, and its database — and deletes the generated project dir\n(`~/.42wp/projects/<name>/`, including any cloned VIP mu-plugins). **Your\nrepository is never touched**: wp-content is a bind mount of your working\ndirectory, which Docker leaves alone. It asks for confirmation; skip the prompt\nwith `--yes` (or `--force`):\n\n```bash\n42wp rm my-theme          # prompts before removing\n42wp rm my-theme --yes    # no prompt (for scripts/CI)\n```\n\n### Demo content\n\nSeed a project with a full demo dataset using `--demo-content` (defaults to 200\nposts), or set a count with `--demo-content=<n>`:\n\n```bash\n42wp start my-site --demo-content       # ~200 posts\n42wp start my-site --demo-content=50    # 50 posts\n```\n\nIt runs a PHP seeder (`wp eval-file`) — no plugin required (FakerPress has no CLI) —\nthat creates:\n\n- ~10 `42wp_author` terms (Portuguese names), ~10 tags, ~10 categories\n- a small pool of real images downloaded from [picsum.photos](https://picsum.photos/),\n  reused as featured + inline images\n- posts with rich HTML content (h1/h2/h3, lists, blockquote, images, links), a\n  plain-text excerpt, varied **past** dates, and each linked to 1 category, 2–5\n  tags and 1–3 authors\n\nWorks on any project (not just `--vip`). It **tops the site up to** the requested\nnumber of posts rather than appending — if the site already has that many\npublished posts it creates none, so re-running `42wp start` never doubles the\ndataset. A failure never aborts `start`. The author terms use the `42wp_author` taxonomy, which the project\nregisters itself (e.g. the `42-framework` mu-plugin) — the seeder does not register\nany taxonomy. If `42wp_author` isn't available, the author links are simply skipped.\n\nWhen the project ships the **42-framework** (detected by `client-mu-plugins/42-framework`\nor a `composer.json` that requires `42wp/wp-mu-plugins`), the seeder additionally\nconfigures — **once, idempotently** — a fuller site:\n\n- the `/%category%/%postname%/` permalink structure\n- a `42wp_homepage` post set as the static front page (falls back to a regular page\n  if the type isn't registered)\n- 4 category-driven menus — Header Primário / Secundário and Footer Primário / Social\n  (with a nested footer and YouTube/X/Instagram links) — assigned to the theme's\n  registered menu locations\n\nRe-running (or `42wp seed`) reuses the existing homepage and menus instead of\nduplicating them; only posts keep appending. On a plain WordPress site these extra\nsteps are skipped and only the content above is seeded.\n\nTo add demo content to an **already-running** project without recreating it, use\n`seed`. Like `start`, it tops the site up to the given count (so `seed 500` on a\n200-post site adds 300, and running it again adds nothing):\n\n```bash\n42wp seed my-site         # up to 200 posts\n42wp seed my-site 500     # up to 500 posts\n42wp seed my-site --demo-content=50\n```\n\n### Admin credentials\n\nThe silent install creates an `admin` / `password` user by default. Override per\nproject on `start`:\n\n```bash\n42wp start my-theme --user joao --pass s3cr3t\n```\n\n### Site language\n\nNew sites install in English (`en_US`) by default. Pick a WordPress locale with\n`--locale`; the language pack is downloaded and activated automatically:\n\n```bash\n42wp start my-site --locale pt_BR      # Brazilian Portuguese\n42wp start my-site --locale es_ES      # Spanish (Spain)\n```\n\nSet a default for every project with the `FORTYTWO_WP_LOCALE` env var. This is the\n**site** language — distinct from `--lang`, which controls the `42wp` CLI's own\nmessages (`en`/`pt`). The pack is downloaded into `wp-content/languages`; if the\ndownload fails (e.g. offline), the site stays in English and `start` continues.\n\n### Multisite\n\nStart a site as a WordPress network with `--multisite` (subdirectory) or add\n`--subdomains` for a subdomain network:\n\n```bash\n42wp start my-network --multisite               # sites at my-network.localhost/site2\n42wp start my-network --multisite --subdomains  # sites at site2.my-network.localhost\n```\n\nThis installs WordPress, converts it to a network, writes the `MULTISITE` constants\ninto `wp-config.php`, and mounts a `.htaccess` with the matching network rewrite\nrules (WP-CLI refuses to generate those for a multisite, which otherwise causes a\nredirect loop on sub-sites). For **subdomain** networks the Traefik router is\nwidened to a wildcard (`*.my-network.localhost`) so sub-sites route to the\ncontainer; `*.localhost` already resolves to `127.0.0.1`, so no `/etc/hosts` edits\nare needed. Network admin lives at `…/wp-admin/network/`.\n\n### WordPress VIP (mu-plugins)\n\nWPVIP sites expect the VIP Go mu-plugins under `wp-content/mu-plugins`. Pass\n`--vip` to `start` and the tool clones\n[`vip-go-mu-plugins-built`](https://github.com/Automattic/vip-go-mu-plugins-built)\n(shallow) and mounts it into the container at `wp-content/mu-plugins`:\n\n```bash\n42wp start my-vip-site --vip\n```\n\nThe clone lives in the project's data dir (`~/.42wp/projects/<name>/mu-plugins`),\nso it never touches your repo, and re-running `start` fast-forwards it. Regular\n(non-VIP) projects are unaffected.\n\n`--vip` also mounts a small **dev-helper mu-plugin** (`00-42wp-dev.php`) that loads\nthe WordPress admin media includes in admin/REST/CLI contexts. This fixes\n\"Call to undefined function `media_handle_sideload()`\"-style errors from plugins\nlike FakerPress, which the VIP environment triggers by loading `file.php` early.\nIt's mounted from the data dir, so your repo and the cloned VIP suite stay clean.\n\n### Example\n\n```bash\ncd ~/code/my-theme\n42wp global start\n42wp start my-theme\n# → http://my-theme.localhost  (admin / password at /wp-admin)\n42wp wp my-theme plugin list\n42wp stop my-theme\n```\n\nShared services once the global layer is up:\n\n| Service     | URL                          |\n| ----------- | ---------------------------- |\n| Traefik     | http://localhost:8080        |\n| phpMyAdmin  | http://db.42wp.localhost     |\n| Mailpit     | http://mail.42wp.localhost   |\n\n## How it works\n\nState lives under `~/.42wp` (override with `FORTYTWO_HOME`):\n\n```\n~/.42wp/\n  docker-compose.global.yml   # the global layer (created on first run)\n  mysql-data/                 # persisted MySQL data\n  projects/<project>/         # generated wp-config.php, Dockerfile, docker-compose.yml, meta.json\n```\n\n`42wp start` generates an ephemeral `wp-config.php` (fetching real salts from\napi.wordpress.org, with a local fallback when offline), a `Dockerfile`, and a\n`docker-compose.yml`, then builds the container and runs a silent\n`wp core install`. The DB name is the project name with hyphens turned into\nunderscores; a trailing `.suffix` (e.g. `.localhost`) is stripped.\n\n**Where a project is bound.** `42wp start` mounts the directory you run it from as\n`wp-content`, so it first checks that directory looks like one — it must contain\n`plugins/` and `themes/`, otherwise `start` refuses (rather than building a broken\nsite). Pass `--force` to override (e.g. bootstrapping a brand-new, empty project).\nThe chosen directory is recorded in the project's `meta.json`, and later `start`s\nreuse it — so re-running from a different folder can't silently re-point the\ncontainer. Run `42wp start <name> --rebind` from a new directory to move the binding\nthere on purpose.\n\nThe generated `wp-config.php` always defines `WP_ENVIRONMENT_TYPE` as `local`, so\n`wp_get_environment_type()` reports `local` (not the WordPress default of\n`production`) — code and plugins that branch on the environment behave as they\nshould in dev. The constant is set before mu-plugins load, so it holds even under\n`--vip`. The config is regenerated every `start`, so to apply this to an\n**existing** project, just re-run `42wp start <project>`.\n\n## Configuration\n\n| Env var         | Default        | Description                                   |\n| --------------- | -------------- | --------------------------------------------- |\n| `FORTYTWO_HOME`   | `~/.42wp`        | Where the global compose, DB data and projects live |\n| `FORTYTWO_WP_TAG` | `php8.4-apache`  | Default WordPress image tag for new projects (overridden by `--wp`) |\n| `FORTYTWO_WP_LOCALE` | unset (`en_US`) | Default WordPress **site** language for new projects (overridden by `--locale`) |\n| `FORTYTWO_LANG`   | auto (`LANG`)    | CLI UI language: `en` or `pt`               |\n| `NO_COLOR`        | unset            | Disable colored output                      |\n\nYou can also pass `--lang en` / `--lang pt` before the command.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}