Upgrade to Pro — share decks privately, control downloads, hide ads and more …

WordPress, Docker and AI agents workshop

WordPress, Docker and AI agents workshop

Workshop deck from WordCamp Belgrade 2026 (18 September). How a solo developer runs a real client project the way a small agency does: DDEV for a local environment that mirrors production, git worktree for parallel tasks, and an AI agent that plans, works, checks and reports under a written contract (AGENTS.md), with a Backlog.md workflow that records estimates, actual time, billable hours and the cost of AI.

One full loop, live, on the participants' own machines: environment → task with acceptance criteria → plan → agent execution → review → deploy to a server.

Repo with preparation guides (macOS, Windows/WSL2, Linux), the agent contract, backlog setup and the demo task: https://github.com/macmladen/workshop-wp-ddev-ai

Preparation, registration and follow-ups: https://macmladen.com/speaking/2026/wordcamp-belgrade-ddev-ai/

#wordpress, #ddev, #docker, #git, #ai, #claude, #codex, #cursor, #workshop, #wordcamp

Avatar for Mladen Đurić

Mladen Đurić

September 13, 2026

More Decks by Mladen Đurić

Other Decks in Programming

Transcript

  1. ]{ KASPAROV, DEEP BLUE I 1997. …and very brie y,

    some musings about DDEV and what it has to do with WordPress and AI?! Mladen Đurić @MacMladen WordPress, Docker i AI agenti — praktično fl @MacMladen v.1 2026-09-18 2
  2. ]{ 2005: Two amateurs and three PCs beat grandmasters and

    supercomputers Freestyle tournament on Playchess, June 2005. Anything goes: human, machine, team. Grandmasters take part with the strongest engines. The winner is ZackS — two American amateurs, Steven Cramton and Zackary Stephen, with three ordinary computers and a process of their own: which engine to ask, when, and how to combine the answers. "Weak human + machine + better process was superior to a strong computer alone and, more remarkably, superior to a strong human + machine + inferior process." — Garry Kasparov, The Chess Master and the Computer, NYRB 2010 @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 4
  3. ]{ Process beats power. Kasparov called it centaur chess. We

    call it agent orchestration. @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 5
  4. ]{ WORDPRESS, DOCKER AND AI AGENTS — HANDS ON Mladen

    Đurić @MacMladen @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 6
  5. ]{ $ whoami A very boring, incompetent guy MLADEN ĐURIĆ

    a.k.a MacMladen @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 7
  6. ]{ I’ve been in IT since the age of mainframes,

    8th year of UNIX epoch. @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 8
  7. ]{ I started with Z80 assembly @MacMladen WordPress, Docker i

    AI agenti — praktično v.1 2026-09-18 9
  8. ]{ I really enjoyed hard core C @MacMladen WordPress, Docker

    i AI agenti — praktično v.1 2026-09-18 10
  9. ]{ As soon as I started learning to code I

    was so fascinated and wanted to share what I learned. I was hardly into secondary school when I organised rst computer club and gave rst BASIC course. It was around 1982. In 2016 I started a Professional Web Development School ]{oder. v.1 2026-09-18 fi WordPress, Docker i AI agenti — praktično fi @MacMladen 11
  10. ]{ DDEV Ever heard of? @MacMladen WordPress, Docker i AI

    agenti — praktično v.1 2026-09-18 12
  11. ]{ DDEV DOCKER? Ever heard of? @MacMladen WordPress, Docker i

    AI agenti — praktično v.1 2026-09-18 13
  12. ]{ The tool to manage the container stack DDEV is

    an open-source tool for launching local web development environments in minutes. It supports PHP, Node.js, and Python (experimental). You can extend, version-control, and share these environments, so you can use a Docker work ow without Docker experience or custom con guration. You can change, power down, or remove projects as easily as you start them. fl WordPress, Docker i AI agenti — praktično fi @MacMladen v.1 2026-09-18 14
  13. ]{ Introduce yourself! Do you do the local development? Git

    and terminal: all the time, sometimes, never? Docker or DDEV: are you using them? AI of choice: chat, Copilot, Cursor, Claude Code, Codex? Mac, Windows, Linux? @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 15
  14. ]{ Timetable: 1. The Thesis ~9 min 6. The Deploy

    ~10 min 2. The DDEV ~8 min 7. 3. The Contract ~10 min 8. The Conclusion ~2 min 4. The Worktree ~12 min 9. Q & A 10 min 5. The Agent ~12 min 10. Resources @MacMladen The Myths ~2 min WordPress, Docker i AI agenti — praktično v.1 2026-09-18 17
  15. ]{ Three ways to follow. All three are ne. 1

    2 3 I work on my laptop I watch, then repeat at home I just listen You type along with everyone. Prerequisites installed; ddev start already done at home. The repo and docs are written so the whole flow can be replayed step by step. No laptop. The repo stays as a reference; the slides are public. Fell behind? git checkout cp-1 … cp-4 returns you to a known state. Note: There is no wrong way. Checkpoint tags are the safety net, nobody has to “keep up”. WordPress, Docker i AI agenti — praktično v.1 2026-09-18 fi @MacMladen 18
  16. ]{ What you take home Local WordPress in DDEV that

    faithfully mirrors production A project under git, with guidelines for the agent (AGENTS.md) A work ow for an agent that plans and works on your code — Claude Code, Codex or Cursor Code on your own URL, deployed through a procedure The repo as a template for your next project A Backlog.md work ow with estimates, a work log and the cost of AI fl WordPress, Docker i AI agenti — praktično fl @MacMladen v.1 2026-09-18 19
  17. ]{ Chapter 1 THE THESIS @MacMladen WordPress, Docker i AI

    agenti — praktično v.1 2026-09-18 20
  18. ]{ One-person studio with an AI team A solo developer

    running a client project the way a small agency does: planning, estimates, parallel work, review, deploy, a record of the work. The agents are the team. The human is the architect. Me — the architect The agent — the team I decide what and why plans before it writes code I write the task and the acceptance criteria works in a worktree, where it is allowed to fail I review the diff runs the checks I am the only one who commits and deploys splits work across subagents: scout · worker · judge @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 21
  19. ]{ A real task, a real estimate, a real price

    AC-181 · Hotfix — category CTA: external registration link Live Novi Pazar page: the CTA points to our signup, but this race registers via TrkaRS. Optional ACF field "External registration link"; when filled, the CTA goes there; when empty, behaviour unchanged. Effort: S Estimate: 1.5h Actual: 2h Billable: yes AI value: plan + implementation + tests; human: the field decision, review, deploy AI time: 1h 10min @MacMladen WordPress, Docker i AI agenti — praktično Estimate before the work, Actual after Billable: does the client pay for this hour AI value: what the agent actually contributed AI time: how long the agent worked on its own All of it from the backlog, not from memory v.1 2026-09-18 22
  20. ]{ Three pillars DDEV git worktree An agent with a

    contract Every project gets its own local environment that mirrors production: the same PHP, the same database, the same extensions. One config.yaml. Enables several tasks to run in parallel, each in its own folder and branch, in the same repo. The agent works where it is allowed to fail. AGENTS.md says what it may do, what it may not, and what "done" looks like. Plan and criteria before code. A human reviews and commits. @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 23
  21. ]{ Chapter 2 THE DDEV @MacMladen WordPress, Docker i AI

    agenti — praktično v.1 2026-09-18 24
  22. ]{ CHECKPOINT 1 Environment $ git clone https://github.com/macmladen/workshop-wp-ddev-ai.git $ cd

    workshop-wp-ddev-ai Expected The site opens in the browser at $ ddev start $ ddev launch https://workshop-wp-ddev-ai.ddev.site $ ddev wp option get siteurl and the wp command prints the same URL. Stuck? git checkout cp-1 8 minutes · we move on at 12:37 @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 26
  23. ]{ Why DDEV: one le, the same machine for everyone

    Same PHP, same database as Invictus production # .ddev/config.yaml name: workshop-wp-ddev-ai type: wordpress Docker underneath, but you never touch it php_version: "8.3" mkcert: https locally, no warnings webserver_type: apache-fpm type: mysql All of it in the repo: clone = working environment version: "8.0" Post-start hook installs WP if it is missing database: hooks: post-start: - exec: ./scripts/wp-install.sh WordPress, Docker i AI agenti — praktično fi @MacMladen v.1 2026-09-18 27
  24. ]{ WP-CLI through DDEV: everything that would be clicking $

    ddev wp plugin list $ ddev wp plugin activate radionica-trening $ ddev wp post create --post_type=trening --post_title="Tuesday 19:00" $ ddev wp db export backup/local.sql $ ddev wp search-replace https://old https://new --dry-run $ ddev exec phpcs --standard=WordPress wp-content/plugins/radionica-trening The agent uses the same commands. @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 28
  25. ]{ Chapter 3 THE CONTRACT @MacMladen WordPress, Docker i AI

    agenti — praktično v.1 2026-09-18 29
  26. ]{ AGENTS.md is the contract 1 One task at a

    time. Execute, then stop. No "while I'm here". I ask for the next step. 2 When something is off, ask — don't improvise. An unexpected result is not an invitation to a workaround. 3 The agent never commits. Files on disk. A human reviews, a human commits. Same le for Claude Code (CLAUDE.md = @AGENTS.md), Codex (AGENTS.md) and Cursor (.cursor/rules). fi @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 30
  27. ]{ The task before the code --id: TASK-1 title: 'WS-01:

    Plugin — show the next training session in the footer' status: To Do milestone: 'M1: Workshop' --## Description Effort: S · Estimate: 45min · Actual: — · Billable: no AI value: — · AI time: — ## Acceptance Criteria - [ ] #1 Plugin activates without errors (ddev wp plugin activate) - [ ] #2 Footer shows the nearest future session (date, time, name) - [ ] #3 With no future session the block does not render - [ ] #4 phpcs WordPress standard passes - [ ] #5 No changes outside wp-content/plugins/radionica-trening fi @MacMladen WordPress, Docker i AI agenti — praktično Backlog.md CLI: backlog task create / edit / list Criteria are an exhaustive list, not a description The agent may not say "done" until the list is con rmed Today, you: this task v.1 2026-09-18 31
  28. ]{ Commit hook: the record as a by-product type [WS-nn]

    Description. feat [WS-01] Show the next training session in the footer. ✔ fix [WS-01] Do not render the block without a future session. ✔ ✖ hook rejects update stuff git config core.hooksPath .githooks # once per clone One task = one commit (or several, each with the ID) git log becomes the work record, per task, per client Types: feat · x · refactor · chore · docs WordPress, Docker i AI agenti — praktično fi @MacMladen v.1 2026-09-18 32
  29. ]{ Three tools, one contract Claude Code Codex CLI Cursor

    Reads rules from CLAUDE.md → @AGENTS.md AGENTS.md .cursor/rules/*.mdc Works in terminal terminal editor + terminal Subagents yes, explicit model yes limited Plan before code plan mode prompt prompt Today on my screen same flow same flow The difference is the tool, not the method. The contract is the same. @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 33
  30. ]{ NEVER DO A LIVE DEMO!* -Morten Birch {{mortend.dk}} @MacMladen

    WordPress, Docker i AI agenti — praktično v.1 2026-09-18 34
  31. ]{ Chapter 4 THE WORKTREE @MacMladen WordPress, Docker i AI

    agenti — praktično v.1 2026-09-18 35
  32. ]{ The plan CHECKPOINT 2 $ git worktree add ../ws-01

    -b ws-01 $ cd ../ws-01 $ claude # or: codex / cursor . # Read backlog/tasks/task-1. Make a plan Expected The agent returns a plan: files it changes, the hook it uses, how it verifies #1–#5. You read it and say yes or send it back. # against the acceptance criteria. Do not write code. Stuck? git checkout cp-2 12 minutes · we move on at 12:59 @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 36
  33. ]{ The plan before the code: what I look for

    A good plan I send it back when it lists the files it touches and why names the WordPress hook/API it uses says how it verifies each criterion has a time estimate says what it does NOT do @MacMladen touches core or the theme for no reason adds a dependency I did not ask for "fixes" something outside the task has no verification plan is longer than the task WordPress, Docker i AI agenti — praktično v.1 2026-09-18 37
  34. ]{ In parallel: two worktrees, two agents $ git worktree

    add ../ws-02 -b ws-02 # second task $ git worktree list /…/workshop-wp-ddev-ai 3d29f8a [main] /…/ws-01 3d29f8a [ws-01] /…/ws-02 3d29f8a [ws-02] Subagent Model Does scout Haiku search, inventory, counting worker Sonnet implementation, research judge Opus verification, review, verdict The main agent orchestrates. A subagent never inherits the model silently — each gets an explicit model and a bounded scope. Use a cheap model for search and an expensive one for judgment. ws-01 and ws-02 should run at the same time. @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 38
  35. ]{ Chapter 5 THE AGENT @MacMladen WordPress, Docker i AI

    agenti — praktično v.1 2026-09-18 39
  36. ]{ CHECKPOINT 3 Execution # Execute the plan. After every

    change run: # ddev exec phpcs --standard=WordPress wp-content/plugins/radionica-trening # ddev wp plugin activate radionica-trening # When criteria #1–#5 are met, stop and report. $ git diff --stat $ git diff Expected Stuck? Diff only in wp-content/plugins/ radionica-trening. phpcs passes. The footer shows the next session. git checkout cp-3 12 minutes · we move on at 13:11 @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 40
  37. ]{ Review is the gate What I look at in

    the diff The agent's report ≠ the code does it change only what the task asks "tests pass" — run them yourself escaping and sanitising on every output "I didn't touch X" — git diff --stat tells the truth the hook in the right place (wp_footer, not echo in a template) what happens with no data would I sign this @MacMladen send it back with a concrete criterion my review and its work are of equal value to the product WordPress, Docker i AI agenti — praktično v.1 2026-09-18 41
  38. ]{ Chapter 6 THE DEPLOY @MacMladen WordPress, Docker i AI

    agenti — praktično v.1 2026-09-18 42
  39. ]{ CHECKPOINT 4 Ship it $ git add -p $

    git commit -m "feat [WS-01] Show the next training session in the footer." $ ./scripts/deploy.sh test --dry-run $ ./scripts/deploy.sh test $ open https://<your-github>.radionica.macmladen.com Expected Stuck? The hook accepts the message. rsync transfers only the plugin. Your URL on your phone shows the next session. git checkout cp-4 10 minutes · content ends at 13:21 @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 43
  40. ]{ What never travels to the server Stays local The

    server owns .git, .ddev, .claude, .cursor, .idea wp-config.php (the active config) AGENTS.md, backlog/, docs/ wp-content/uploads (media flows only towards local) wp-config.php.* templates node_modules, *.log, .DS_Store .htaccess, .user.ini, mu-plugins cache/, upgrade/, wflogs/ The rsync --exclude list is in the repo. Before a deploy: compare WP versions, never downgrade production. @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 44
  41. ]{ The same thing on Invictus, now $ ssh invictus

    'cd ~/public_html_test_… && wp core version' $ ddev wp core version $ cd new-design/challenge && npm run build && cd $ ./scripts/deploy.sh test $ curl -sI https://test.invictuschallenge.rs | head -1 @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 45
  42. ]{ Chapter 7 THE MYTHS @MacMladen WordPress, Docker i AI

    agenti — praktično v.1 2026-09-18 46
  43. ]{ "AI will do it all by itself." Without a

    task, criteria and review, you get fast code nobody understands. Including the agent tomorrow. Process, not power. @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 47
  44. ]{ "I can't trust code I didn't write." You should

    not. That is what the review is for. Neither you trust a plugin from wordpress.org: you check it. Same here. @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 48
  45. ]{ "That's for big teams." The other way round. One

    person with a contract, a backlog and agents works like a small team. Big teams have different problems. @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 49
  46. ]{ Chapter 8 THE CONCLUSION @MacMladen WordPress, Docker i AI

    agenti — praktično v.1 2026-09-18 50
  47. ]{ Five steps for your own project 1 ddev config

    on an existing project; match PHP and database to production 2 AGENTS.md with the three rules; CLAUDE.md = @AGENTS.md 3 backlog init; rst task with criteria, Estimate and Billable 4 commit hook; git log becomes the record 5 deploy.sh with the exclude list; rst deploy to test, never straight to live fi WordPress, Docker i AI agenti — praktično fi @MacMladen v.1 2026-09-18 51
  48. ]{ The right tool for the job Never hand the

    decision to the agent — hand it the work Never without a task and criteria — otherwise it's chat Never a commit you haven't read Cheap model for search, expensive for judgement The same procedure for a small and a big project — that is what scales @MacMladen WordPress, Docker i AI agenti — praktično v.1 2026-09-18 52
  49. ]{ Chapter 9 THE RESOURCES @MacMladen WordPress, Docker i AI

    agenti — praktično v.1 2026-09-18 53
  50. ]{ WP-CLI git worktree Backlog.md developer.wordpress.org/cli git-scm.com/docs/git-worktree github.com/MrLesk/Backlog.md Claude Code

    Codex CLI Cursor CLI code.claude.com developers.openai.com/codex/cli cursor.com/docs/cli WordPress, Docker i AI agenti — praktično v.1 2026-09-18 @MacMladen 54