Technote

Development workflow Intro

Series From local to production Part 1 of 8

Choosing a local environment: Docker, native stacks, built-in server

The three options differ less in convenience than in what they share with production. Once you know which differences matter to this project, the choice is quick.

Editing files straight on the server is the fastest thing to do at first. Change a line, upload, refresh. The problem is that it leaves nowhere to go back to. There is no record of what changed, mistakes are visible to visitors immediately, and when two people touch the same file one person’s work quietly disappears.

This series builds a pipeline that treats WordPress like code — repository, secrets, database sync, staging, deploys and rollback. All of it starts with a local environment. A problem you cannot reproduce locally is a problem you will end up fixing in production, and at that moment the rest of the discipline collapses.

Three options, and what each gives up

There are realistically three choices. The criterion is not “which is easiest to install” but what each shares with production, and what it does not.

Three local environments — closer to production as you go down, with more moving parts to manage

The built-in server starts with a single wp server. But there is no nginx and no Apache, so anything the web server does — rewrite rules, FastCGI caching, security headers — simply is not reproduced. It also handles one request at a time by default, which matters the moment your code makes an HTTP request back to its own site: that request will sit there. Fine for opening a theme, misleading for anything beyond that.

A native stack is the most comfortable daily driver. Filesystem access is quick and PHP and nginx are already wired together. In exchange, the extension set and server configuration are largely given to you. If production depends on a particular extension — imagick, redis — you need to confirm it exists locally rather than assume.

Containers let you pin the PHP version, extensions, database version, Redis and nginx to the same combination production runs. The price is the number of parts, plus file access speed over bind mounts. For a project that touches caching layers or server configuration, that price is usually worth paying.

The deciding factor is a list of differences

Which option is right depends on the project, and there is only one honest way to decide: actually enumerate the differences between production and local. Do not guess — print both and compare.

# once on production
php -v
php -m | sort > prod-modules.txt

# and locally, the same thing
php -m | sort > local-modules.txt
diff prod-modules.txt local-modules.txt

That diff is your risk list. A missing extension means the feature it powers will never reproduce locally; a different PHP version changes syntax support, deprecation notices and type coercion behaviour. If the diff is a few lines, a native stack is plenty. If it runs long, matching it in a container is the faster route in the end.

Settings that stay local

With the environment chosen, switch on the development settings. These are exactly the values that must never travel to production — the first reason the repository rules in the next part, and the per-environment configuration after that, become necessary.

Local-only settings — the bottom three are the ones that become incidents if they travel

On that last line: an uploads directory easily runs to several gigabytes, and it contains files your customers uploaded. What development needs is usually the structure, not every file. If broken images bother you, a rewrite rule that forwards missing media requests to production costs far less than the copy.

For the server side of this, the Servers & infrastructure archive continues the thread, and if you would rather hand over the job of moving a live site onto a reproducible stack, Docker-based rebuilds are part of our optimization program.

Next part

With a local environment in place, it is time to record changes. The next part is the shape of a WordPress repository — what to commit and what to ignore — and the rule comes down to a single sentence.

More on this topic

All technotes

Development workflow Practical

Turning taste arguments into rule checks

"It feels a bit cramped" can be neither argued with nor fixed. Spacing off the scale, colour off the palette, contrast below threshold, missing states — four rules…

Designers 9 min read

Development workflow Practical

Do not swap everything at once

A full swap makes every problem appear at the same moment — which means none of them can be attributed. So you switch one template at a time.

Designers 6 min read

Development workflow Practical

Adding an SCSS build, and whether to commit the output

WordPress themes are expected to deploy without a build step, which leads to the opposite conclusion from ordinary application code — and to its own costs.

Developers 7 min read

₩270,000 · Join the program