{"id":90,"date":"2026-10-26T08:00:00","date_gmt":"2026-10-26T07:00:00","guid":{"rendered":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/"},"modified":"2026-10-16T14:00:12","modified_gmt":"2026-10-16T12:00:12","slug":"ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project","status":"publish","type":"post","link":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/","title":{"rendered":"DDEV for a TYPO3 site and a WordPress blog in one project"},"content":{"rendered":"<p>Hi folks,<\/p>\n<p>For years my blog lived on its own subdomain, blog.hoja.in, with its own folder on the hosting and its own database. When I rebuilt hoja.in this year on TYPO3 14.3, I moved the blog to hoja.in\/blog. One domain, one repository, and locally one DDEV project. I was a bit afraid of this, because TYPO3 and WordPress both want to own the URL space with their rewrite rules. It turned out simpler than expected. Here is the setup exactly as it runs on my Mac.<\/p>\n<h2>The layout<\/h2>\n<pre><code class=\"language-text\">myport\/\n\u251c\u2500\u2500 .ddev\/\n\u2502   \u251c\u2500\u2500 config.yaml          # TYPO3 project, generated by ddev config\n\u2502   \u2514\u2500\u2500 config.myport.yaml   # my additions\n\u251c\u2500\u2500 config\/                  # TYPO3 system and site configuration\n\u251c\u2500\u2500 public\/                  # web root\n\u2502   \u251c\u2500\u2500 .htaccess            # TYPO3 rules\n\u2502   \u251c\u2500\u2500 index.php            # TYPO3\n\u2502   \u2514\u2500\u2500 blog\/                # WordPress 7.1\n\u2502       \u251c\u2500\u2500 .htaccess        # WordPress rules with RewriteBase \/blog\/\n\u2502       \u251c\u2500\u2500 wp-config.php\n\u2502       \u2514\u2500\u2500 wp-config-ddev.php\n\u251c\u2500\u2500 Source\/Extension\/sitepackage\/\n\u2514\u2500\u2500 composer.json<\/code><\/pre>\n<p>WordPress is simply a folder inside the TYPO3 web root. Its core files are in git next to the TYPO3 project, the WordPress uploads are too, and the TYPO3 <code>vendor\/<\/code> folder is not.<\/p>\n<h2>Step 1: the DDEV config<\/h2>\n<p>The main file is what <code>ddev config<\/code> generated for a TYPO3 project, with PHP and the database pinned:<\/p>\n<pre><code class=\"language-yaml\">name: myport\ntype: typo3\ndocroot: public\nphp_version: \"8.4\"\nwebserver_type: apache-fpm\ndatabase:\n    type: mariadb\n    version: \"10.11\"\ncomposer_version: \"2\"<\/code><\/pre>\n<p>I chose <code>apache-fpm<\/code> on purpose. Both TYPO3 and WordPress ship <code>.htaccess<\/code> files, and the production hosting is Apache too. With nginx I would have to translate both rule sets and keep them in sync with production by hand. With Apache the same files work in both places.<\/p>\n<p>My own additions are in a second file. DDEV reads every <code>config.*.yaml<\/code> in the folder and merges it, so I never touch the generated file:<\/p>\n<pre><code class=\"language-yaml\">disable_settings_management: true\nweb_environment:\n  - TYPO3_CONTEXT=Development\/Ddev\nhooks:\n  post-start:\n    - exec: mysql -uroot -proot -e \"CREATE DATABASE IF NOT EXISTS blog CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; GRANT ALL ON blog.* TO 'db'@'%';\"\n      service: db<\/code><\/pre>\n<p>Three things happen here. <code>disable_settings_management<\/code> stops DDEV from writing its own TYPO3 settings file, because my <code>config\/system\/additional.php<\/code> is in git and handles DDEV itself. <code>TYPO3_CONTEXT<\/code> lets the site configuration pick the local base URL. And the post-start hook creates a second database called <code>blog<\/code> for WordPress, with rights for the normal <code>db<\/code> user. It runs on every start, so <code>IF NOT EXISTS<\/code> is important. (My real file creates a third database, <code>legacy<\/code>, for the old TYPO3 7.6 data the import script read during the migration.)<\/p>\n<h2>Step 2: WordPress config per environment<\/h2>\n<p>WordPress has no environment handling like TYPO3&#8217;s context, so I split <code>wp-config.php<\/code>. The main file is in git and holds nothing secret:<\/p>\n<pre><code class=\"language-php\">&lt;?php\nif (getenv('IS_DDEV_PROJECT') === 'true') {\n    require __DIR__ . '\/wp-config-ddev.php';\n} else {\n    require __DIR__ . '\/wp-config-production.php';\n}\n\ndefine('DB_CHARSET', 'utf8mb4');\ndefine('DB_COLLATE', '');\n\n$table_prefix = 'myblog_';\n\ndefined('WP_DEBUG') || define('WP_DEBUG', false);\n\nif (!defined('ABSPATH')) {\n    define('ABSPATH', __DIR__ . '\/');\n}\n\nrequire_once ABSPATH . 'wp-settings.php';<\/code><\/pre>\n<p>DDEV sets <code>IS_DDEV_PROJECT=true<\/code> inside the containers. The DDEV file then points to the second database and the local URL:<\/p>\n<pre><code class=\"language-php\">define('DB_NAME', 'blog');\ndefine('DB_USER', 'db');\ndefine('DB_PASSWORD', 'db');\ndefine('DB_HOST', 'db');\ndefine('WP_HOME', 'https:\/\/hoja.in\/blog');\ndefine('WP_SITEURL', 'https:\/\/hoja.in\/blog');\ndefine('WP_ENVIRONMENT_TYPE', 'local');\ndefine('WP_DEBUG', true);\ndefine('WP_DEBUG_LOG', true);\ndefine('WP_DEBUG_DISPLAY', false);\n\/\/ plus the salts<\/code><\/pre>\n<p>The production file has the real credentials and is in <code>.gitignore<\/code>. Old habit from the hosting days, but a good one.<\/p>\n<h2>Step 3: the rewrite rules<\/h2>\n<p>This was the part I worried about, and the answer is boring in a good way. Apache reads the <code>.htaccess<\/code> of the deepest directory. A request to <code>\/blog\/some-post\/<\/code> is handled by <code>public\/blog\/.htaccess<\/code>, and its rewrite rules replace the ones from the TYPO3 file one level up, because mod_rewrite does not inherit parent rules unless you ask for it. So the WordPress file only needs the right base:<\/p>\n<pre><code class=\"language-apache\">&lt;IfModule mod_rewrite.c&gt;\nRewriteEngine On\nRewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]\nRewriteBase \/blog\/\nRewriteRule ^index.php$ - [L]\nRewriteCond %{REQUEST_FILENAME} !-f\nRewriteCond %{REQUEST_FILENAME} !-d\nRewriteRule . \/blog\/index.php [L]\n&lt;\/IfModule&gt;<\/code><\/pre>\n<p>That is the standard block WordPress writes itself, with <code>\/blog\/<\/code> instead of <code>\/<\/code>. Everything outside <code>\/blog\/<\/code> still goes to TYPO3. In TYPO3 the &#8220;Blog&#8221; menu entry is a page of the type Link pointing to <code>\/blog\/<\/code>.<\/p>\n<h2>Step 4: import and export both databases<\/h2>\n<p>DDEV&#8217;s database commands take a <code>--database<\/code> flag, so the blog database is handled like the main one:<\/p>\n<pre><code class=\"language-bash\"># TYPO3 (default database \"db\")\nddev import-db --file=hojain_v14.sql.gz\nddev export-db --file=.project-migration\/backups\/pre-change.sql.gz\n\n# WordPress (database \"blog\")\nddev import-db --database=blog --file=blog.sql\nddev export-db --database=blog --file=.project-migration\/backups\/blog-pre-change.sql.gz\n\n# Both at once, as a DDEV snapshot of the whole database server\nddev snapshot --name=before-upgrade<\/code><\/pre>\n<p>After importing an old blog dump, the URLs inside the database still point to the old domain. WP-CLI fixes that, and it is already inside the DDEV web container. Because my project type is <code>typo3<\/code>, I call it with <code>ddev exec<\/code> in the blog folder:<\/p>\n<pre><code class=\"language-bash\">ddev exec --dir \/var\/www\/html\/public\/blog wp search-replace \n  'https:\/\/blog.hoja.in' 'https:\/\/hoja.in\/blog' \n  --all-tables-with-prefix --precise --dry-run<\/code><\/pre>\n<p>Run it with <code>--dry-run<\/code> first and read the counts. Then without. <code>search-replace<\/code> handles serialized PHP arrays correctly, which a plain SQL <code>REPLACE()<\/code> would break.<\/p>\n<h2>Step 5: check both apps in one go<\/h2>\n<p>Two applications means two ways to break things. I keep a plain list of URLs in the repository, old TYPO3 pages and new ones, plus the blog front page and one blog post, and run them through curl after every change:<\/p>\n<pre><code class=\"language-bash\">grep -v '^#' .project-migration\/urls.txt | while read -r url; do\n  printf '%s %sn' \"$(curl -sk -o \/dev\/null -w '%{http_code}' \"$url\")\" \"$url\"\ndone<\/code><\/pre>\n<p>Every line should start with 200. If a WordPress URL suddenly returns the TYPO3 404 page, the blog <code>.htaccess<\/code> is missing or has the wrong base. If a TYPO3 URL returns a WordPress page, something is very wrong with the document root. The check costs two seconds.<\/p>\n<p>Mail is the other shared thing. DDEV catches every outgoing mail in Mailpit, so the TYPO3 contact form and WordPress comment notifications both land there instead of in a real inbox. That is how I tested the new EXT:form contact form of hoja.in before going anywhere near production.<\/p>\n<h2>What I would tell my younger self<\/h2>\n<ul>\n<li>Use the same web server type locally as in production. It saves you from maintaining two rule sets.<\/li>\n<li>Put your DDEV additions in a separate <code>config.*.yaml<\/code>. Updates of the generated file stay clean.<\/li>\n<li>Use the post-start hook for extra databases, and make it idempotent.<\/li>\n<li>Dump before you import. Every time. My backups folder has a <code>pre-\u2026<\/code> dump for every step that changed data.<\/li>\n<\/ul>\n<p>Two CMSs in one project sounds like trouble, but with DDEV it is just one <code>ddev start<\/code> in the morning. Cheers!<\/p>\n<h2>Further reading<\/h2>\n<ul>\n<li><a href=\"https:\/\/ddev.readthedocs.io\/en\/stable\/users\/usage\/database-management\/\">DDEV: Database management<\/a><\/li>\n<li><a href=\"https:\/\/ddev.readthedocs.io\/en\/stable\/users\/configuration\/hooks\/\">DDEV: Hooks<\/a><\/li>\n<li><a href=\"https:\/\/developer.wordpress.org\/cli\/commands\/search-replace\/\">WP-CLI: wp search-replace<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>hoja.in runs TYPO3 14 at the root and WordPress under \/blog, in one repository and one DDEV project. The config, the second database, the rewrite rules and the import commands.<\/p>\n","protected":false},"author":1,"featured_media":91,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21],"tags":[27,45,5,42],"class_list":["post-90","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops-tooling","tag-ddev","tag-devops","tag-typo3","tag-wordpress"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>DDEV for TYPO3 and a WordPress blog in one project<\/title>\n<meta name=\"description\" content=\"One DDEV project for TYPO3 14 at the root and WordPress at \/blog: config.yaml, a second database via a post-start hook, Apache rules and wp-config per env.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"DDEV for TYPO3 and a WordPress blog in one project\" \/>\n<meta property=\"og:description\" content=\"One DDEV project for TYPO3 14 at the root and WordPress at \/blog: config.yaml, a second database via a post-start hook, Apache rules and wp-config per env.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/\" \/>\n<meta property=\"og:site_name\" content=\"Hoja Mustaffa Abdul Latheef \u2013 Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-26T07:00:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Hoja Mustaffa Abdul Latheef\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@hojaonline\" \/>\n<meta name=\"twitter:site\" content=\"@hojaonline\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Hoja Mustaffa Abdul Latheef\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\\\/\"},\"author\":{\"name\":\"Hoja Mustaffa Abdul Latheef\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"headline\":\"DDEV for a TYPO3 site and a WordPress blog in one project\",\"datePublished\":\"2026-10-26T07:00:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\\\/\"},\"wordCount\":791,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"image\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project.jpg\",\"keywords\":[\"DDEV\",\"DevOps\",\"TYPO3\",\"WordPress\"],\"articleSection\":[\"DevOps &amp; tooling\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/hoja.in\\\/blog\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\\\/\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\\\/\",\"name\":\"DDEV for TYPO3 and a WordPress blog in one project\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project.jpg\",\"datePublished\":\"2026-10-26T07:00:00+00:00\",\"description\":\"One DDEV project for TYPO3 14 at the root and WordPress at \\\/blog: config.yaml, a second database via a post-start hook, Apache rules and wp-config per env.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/hoja.in\\\/blog\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\\\/#primaryimage\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project.jpg\",\"contentUrl\":\"https:\\\/\\\/hoja.in\\\/blog\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project.jpg\",\"width\":1200,\"height\":630,\"caption\":\"TYPO3 and WordPress, one project\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/hoja.in\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"DDEV for a TYPO3 site and a WordPress blog in one project\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/hoja.in\\\/blog\\\/\",\"name\":\"Hoja Mustaffa Abdul Latheef \u2013 Blog\",\"description\":\"Notes from daily work with TYPO3, PHP and AI-assisted engineering\",\"publisher\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/hoja.in\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/e6fbd54c2061674d8ea3e7861d858c7b\",\"name\":\"Hoja Mustaffa Abdul Latheef\",\"logo\":{\"@id\":\"https:\\\/\\\/hoja.in\\\/blog\\\/#\\\/schema\\\/person\\\/image\\\/\"},\"description\":\"Senior TYPO3 Developer at jweiland.net, TYPO3 CMS Certified Developer. I write about TYPO3 upgrades, extension development, PHP and AI-assisted engineering with Claude Code.\",\"sameAs\":[\"https:\\\/\\\/hoja.in\\\/\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"DDEV for TYPO3 and a WordPress blog in one project","description":"One DDEV project for TYPO3 14 at the root and WordPress at \/blog: config.yaml, a second database via a post-start hook, Apache rules and wp-config per env.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/","og_locale":"en_US","og_type":"article","og_title":"DDEV for TYPO3 and a WordPress blog in one project","og_description":"One DDEV project for TYPO3 14 at the root and WordPress at \/blog: config.yaml, a second database via a post-start hook, Apache rules and wp-config per env.","og_url":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/","og_site_name":"Hoja Mustaffa Abdul Latheef \u2013 Blog","article_published_time":"2026-10-26T07:00:00+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project.jpg","type":"image\/jpeg"}],"author":"Hoja Mustaffa Abdul Latheef","twitter_card":"summary_large_image","twitter_creator":"@hojaonline","twitter_site":"@hojaonline","twitter_misc":{"Written by":"Hoja Mustaffa Abdul Latheef","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/#article","isPartOf":{"@id":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/"},"author":{"name":"Hoja Mustaffa Abdul Latheef","@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"headline":"DDEV for a TYPO3 site and a WordPress blog in one project","datePublished":"2026-10-26T07:00:00+00:00","mainEntityOfPage":{"@id":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/"},"wordCount":791,"commentCount":0,"publisher":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"image":{"@id":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/#primaryimage"},"thumbnailUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project.jpg","keywords":["DDEV","DevOps","TYPO3","WordPress"],"articleSection":["DevOps &amp; tooling"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/","url":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/","name":"DDEV for TYPO3 and a WordPress blog in one project","isPartOf":{"@id":"https:\/\/hoja.in\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/#primaryimage"},"image":{"@id":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/#primaryimage"},"thumbnailUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project.jpg","datePublished":"2026-10-26T07:00:00+00:00","description":"One DDEV project for TYPO3 14 at the root and WordPress at \/blog: config.yaml, a second database via a post-start hook, Apache rules and wp-config per env.","breadcrumb":{"@id":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/#primaryimage","url":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project.jpg","contentUrl":"https:\/\/hoja.in\/blog\/wp-content\/uploads\/2026\/10\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project.jpg","width":1200,"height":630,"caption":"TYPO3 and WordPress, one project"},{"@type":"BreadcrumbList","@id":"https:\/\/hoja.in\/blog\/ddev-for-a-typo3-site-and-a-wordpress-blog-in-one-project\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/hoja.in\/blog\/"},{"@type":"ListItem","position":2,"name":"DDEV for a TYPO3 site and a WordPress blog in one project"}]},{"@type":"WebSite","@id":"https:\/\/hoja.in\/blog\/#website","url":"https:\/\/hoja.in\/blog\/","name":"Hoja Mustaffa Abdul Latheef \u2013 Blog","description":"Notes from daily work with TYPO3, PHP and AI-assisted engineering","publisher":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/hoja.in\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/e6fbd54c2061674d8ea3e7861d858c7b","name":"Hoja Mustaffa Abdul Latheef","logo":{"@id":"https:\/\/hoja.in\/blog\/#\/schema\/person\/image\/"},"description":"Senior TYPO3 Developer at jweiland.net, TYPO3 CMS Certified Developer. I write about TYPO3 upgrades, extension development, PHP and AI-assisted engineering with Claude Code.","sameAs":["https:\/\/hoja.in\/"]}]}},"_links":{"self":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/90","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/comments?post=90"}],"version-history":[{"count":1,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/90\/revisions"}],"predecessor-version":[{"id":168,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/posts\/90\/revisions\/168"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/media\/91"}],"wp:attachment":[{"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/media?parent=90"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/categories?post=90"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hoja.in\/blog\/wp-json\/wp\/v2\/tags?post=90"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}