My recommendation for a calm, sustainable dev machine: 64 GB RAM, a swapfile the same size as RAM, a fast external SSD with at least 500 GB, and only the services you actually need right now.
Not every machine is a high-end workstation, and that is fine. If you work intentionally, keep Docker data off the system disk, and clean up regularly, you can stay productive even on modest hardware.
Goal Hardware
If you want long-term stability and less friction, this is a solid target:
- 64 GB RAM
- a swapfile the same size as RAM
- an external SSD with more than 500 GB
- enough room for Docker images, volumes, build cache, and local repositories
The SSD is often the cheapest and most effective upgrade. If disk space is tight, move Docker data, caches, and ideally your working directory to that drive.
On Linux, you can move Docker to a different data path:
{
"data-root": "/mnt/ssd/docker"
}
Then restart Docker:
sudo systemctl restart docker
Make sure the mount is available before Docker starts. Otherwise the daemon may fall back to the system drive or fail to start cleanly.
On macOS and Windows, this is usually handled through Docker Desktop settings rather than daemon.json.
For swap: on Linux, a swapfile equal to your RAM size is a good buffer against memory spikes, OOM kills, and hard crashes. If you have less RAM, the same idea still helps, but you will need to be even stricter about keeping the stack small. On Windows and macOS, the OS manages virtual memory itself, but free disk space still matters a lot.
Load Only What You Need
For a broad stack like the Community Hub, it helps a lot not to start everything at once. If you are only working on Discourse, you do not automatically need Mastodon, Pixelfed, PeerTube, or Friendica in the same session.
The main lever is each role’s config/main.yml. That is where Compose services are enabled or disabled. The rule is simple:
- use
enabled: trueonly for services you actually need - set
enabled: falsefor optional services - for shared services, also set
shared: falseif they are not needed
Example of a slim local Discourse configuration:
compose:
services:
discourse:
enabled: true
database:
enabled: true
shared: true
type: "postgres"
redis:
enabled: true
oidc:
enabled: false
shared: false
logout:
enabled: false
ldap:
enabled: false
shared: false
dashboard:
enabled: false
matomo:
enabled: false
shared: false
css:
enabled: false
This is a development profile, not a production target. If you need to test SSO, LDAP, or analytics, enable those services deliberately. But on weaker hardware, the general rule is: as little as possible, as much as necessary.
At bundle level, the same principle applies. If you are only changing Discourse in the Community Hub, do not start the whole stack unless you need it.
Test Smarter
On small machines, it helps to limit validation to the one role you are actually touching.
For Discourse, this is usually the best start:
APP=web-app-discourse make test-local-dedicated
If the local inventory and stack are already in place, this is often the faster iteration loop:
APP=web-app-discourse make test-local-rapid
I would only use make test-local-full on weaker hardware if you truly need broad coverage and you have enough time and resources.
Measure Before You Delete
Before cleaning up, it is worth checking what is actually consuming space:
docker system df
docker ps -a
docker images
journalctl --disk-usage
df -h
That usually makes it much easier to see whether the real issue is Docker, journald, a package cache, or simply the project state.
Docker Cleanup
First: there is no single docker prune command. In practice, people usually mean one of these.
For a single project, this is the first cleanup step:
docker compose down --volumes --remove-orphans
If you need the big cleanup, these are the usual commands:
docker system prune -a --volumes -f
docker container prune -f
docker image prune -a -f
docker volume prune -f
docker network prune -f
docker builder prune -a -f
docker context prune -f
When I use what:
docker compose down --volumes --remove-orphansfor one projectdocker system prune -a --volumes -ffor the big hammerdocker builder prune -a -fwhen build cache grows too largedocker volume prune -fwhen old volumes consume spacedocker image prune -a -fwhen old images pile updocker network prune -fwhen old networks remaindocker context prune -fwhen you have many stale Docker contexts
If you use Buildx, add this when needed:
docker buildx prune -a -f
Repo and Project Cleanup
Inside this repository, these commands help a lot:
make down
make stop
make clean
make clean-sudo
make cleanup-ci-images
make test-local-cleanup
make test-local-reset
Quick explanation:
make downstops the stack and removes volumesmake stopstops the stack but keeps the statemake cleanremoves ignored Git filesmake clean-sudodoes the same withsudo, if root-owned files existmake cleanup-ci-imagesremoves old CI imagesmake test-local-cleanupcleans local test statemake test-local-resetresets the local inventory
If you often switch branches or work on only one role at a time, a disciplined down and clean routine usually saves more space than trying to recover later with a huge prune.
Linux
Common
Use these on most Linux setups before you go distro-specific:
docker compose down --volumes --remove-orphans
docker system prune -a --volumes -f
docker builder prune -a -f
docker image prune -a -f
docker volume prune -f
docker network prune -f
docker context prune -f
journalctl --vacuum-size=100M
journalctl --vacuum-time=3h
pip cache purge
npm cache clean --force
yarn cache clean
go clean -cache -modcache
cargo clean
Optional, if you use Flatpak:
flatpak uninstall --unused -y
Arch
sudo pacman -Scc --noconfirm
Debian / Ubuntu
sudo apt-get clean
sudo apt-get autoremove --purge -y
Fedora / CentOS
sudo dnf clean all
sudo yum clean all
This matches the general idea used by the repo’s cleanup roles: keep package caches, tool caches, temp files, and journald under control.
macOS
On macOS, focus on Docker Desktop and Homebrew:
brew cleanup --prune=all
brew autoremove
docker system prune -a --volumes -f
docker builder prune -a -f
If you follow the repo setup, macOS works best when the stack runs in a Linux environment such as Lima. In that case, the same general rule applies: keep Docker and build caches small, and place the Docker disk location on a larger drive if possible.
Windows
On Windows, the most reliable setup is WSL2. In practice, that means:
- do Docker cleanup inside WSL2 or directly via the Docker CLI
- use Windows-side cleanup tools for host cleanup
- run
wsl --shutdownwhen you want memory returned to the host
Useful Windows commands:
docker system prune -a --volumes -f
docker builder prune -a -f
wsl --shutdown
cleanmgr /sageset:1
cleanmgr /sagerun:1
DISM /Online /Cleanup-Image /StartComponentCleanup
cleanmgr /sageset:1 is typically configured once as Administrator. After that, cleanmgr /sagerun:1 reuses the same cleanup profile.
If you are working in WSL2, you can also use the Linux commands from the Linux section inside the WSL shell. That is often the cleanest approach, because the Docker workload usually lives there.
Standard Routine
When the machine starts feeling tight, I usually do this:
- Start only the role I actually need.
- Stop the stack cleanly with
make downordocker compose down --volumes --remove-orphans. - Clear Docker cache with
docker builder prune -a -fanddocker system prune -a --volumes -f. - Clean host caches depending on the operating system.
- Start fresh again.
It sounds simple, but that is exactly what keeps smaller machines usable over time.
If you have to develop on limited hardware, the best strategy is not “more power”, but “less load per session”.
If you want, I can also turn this into a shorter Discourse-ready version with a more conversational forum tone.