Add forgejo/SETUP_LOCAL.md documenting a self-contained local deployment of Forgejo + ifcurl on Windows using Docker Desktop. Covers Nginx reverse proxy for PR diff images, correct Forgejo v15 custom paths (/data/gitea), libosmesa6 for headless rendering, and a git URL rewrite so the ifcurl container can clone repos from localhost:3000 via the Docker-internal forgejo hostname. Add docker/Dockerfile for the ifcurl preview service. Link SETUP_LOCAL.md from README.md and forgejo/README.md.
7.7 KiB
ifcurl + Forgejo Local Setup (Windows + Docker)
Prerequisites
- Windows 10
- Docker Desktop installed and running
- Git
- The ifcurl repository cloned locally (e.g.
D:\Dropbox\GitHub\ifcurl)
Directory structure
C:\forgejo-local\
docker-compose.yml
nginx.conf
custom\
public\assets\ ← viewer.html, ifcurl.js, etc.
templates\custom\ ← footer.tmpl
D:\Dropbox\GitHub\ifcurl\
docker\
Dockerfile ← already in the repo
Step 1 — Deploy ifcurl assets to the custom directory
Run from the ifcurl repo root in Git Bash:
DEST="C:/forgejo-local/custom"
mkdir -p "$DEST/public/assets" "$DEST/templates/custom"
cp forgejo/custom/public/assets/viewer.html "$DEST/public/assets/"
cp forgejo/custom/public/assets/viewer.js "$DEST/public/assets/"
cp forgejo/custom/public/assets/viewer-url.js "$DEST/public/assets/"
cp forgejo/custom/public/assets/viewer-deps.js "$DEST/public/assets/"
cp forgejo/custom/public/assets/fragments-worker.js "$DEST/public/assets/"
cp forgejo/custom/public/assets/web-ifc.wasm "$DEST/public/assets/"
cp forgejo/custom/public/assets/web-ifc-mt.wasm "$DEST/public/assets/"
cp forgejo/custom/public/assets/ifcurl.js "$DEST/public/assets/"
cp forgejo/templates/custom/footer.tmpl "$DEST/templates/custom/"
Git Bash note: when assigning shell variables, do NOT use a
$prefix — useDEST="..."not$DEST="...".
Step 2 — Create C:\forgejo-local\docker-compose.yml
Nginx sits in front of Forgejo and proxies the ifcurl service endpoints
(/preview, /render_diff, /bcf, /select) at the same origin as Forgejo.
This is required for PR diff images, which are fetched by the browser.
Note: Forgejo's Docker image stores all data under
/data/gitea, not/var/lib/forgejoas older guides suggest.
services:
nginx:
image: nginx:alpine
container_name: nginx
ports:
- "3000:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- forgejo
- ifcurl
restart: unless-stopped
forgejo:
image: codeberg.org/forgejo/forgejo:15
container_name: forgejo
environment:
- USER_UID=1000
- USER_GID=1000
ports:
- "2222:22"
volumes:
- forgejo-data:/data/gitea
- ./custom/public:/data/gitea/public
- ./custom/templates:/data/gitea/templates
depends_on:
- ifcurl
restart: unless-stopped
ifcurl:
build:
context: D:/Dropbox/GitHub/ifcurl
dockerfile: docker/Dockerfile
container_name: ifcurl
restart: unless-stopped
volumes:
forgejo-data:
Step 3 — Create C:\forgejo-local\nginx.conf
server {
listen 80;
location /preview {
proxy_pass http://ifcurl:8000;
proxy_set_header Host $host;
proxy_read_timeout 120s;
}
location /render_diff {
proxy_pass http://ifcurl:8000;
proxy_set_header Host $host;
proxy_read_timeout 120s;
}
location /bcf {
proxy_pass http://ifcurl:8000;
proxy_set_header Host $host;
proxy_read_timeout 120s;
}
location /select {
proxy_pass http://ifcurl:8000;
proxy_set_header Host $host;
proxy_read_timeout 120s;
}
location / {
proxy_pass http://forgejo:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 300s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Step 4 — Dockerfile (already in repo, shown for reference)
docker/Dockerfile is committed to the ifcurl repository. Key points:
libosmesa6provides software OpenGL for headless rendering inside the container (no GPU or display server required).- The
git config url.insteadOfrewrite lets the ifcurl service clone repos fromlocalhost:3000(as it appears inifc://URLs) by transparently redirecting git toforgejo:3000inside the Docker network.
FROM python:3.12-slim
RUN apt-get update && apt-get install -y \
git libgl1 libglib2.0-0 libosmesa6 \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY . .
RUN pip install --no-cache-dir ".[service]"
# Remap localhost:3000 → forgejo:3000 so git can clone from the Forgejo
# container by its Docker-internal hostname when processing ifc:// URLs.
RUN git config --global url."http://forgejo:3000/".insteadOf "http://localhost:3000/"
EXPOSE 8000
CMD ["ifcurl", "serve", "--host", "0.0.0.0", "--port", "8000", "--allowed-hosts", "localhost:3000"]
Step 5 — Start everything
Make sure Docker Desktop is running, then:
cd C:/forgejo-local
docker compose up -d
The first run pulls the Forgejo and Nginx images and builds the ifcurl image — this may take several minutes.
Open http://localhost:3000 and complete the Forgejo setup wizard.
Step 6 — Add ifcurl config to Forgejo
The setup wizard writes its own app.ini inside the container. After
completing the wizard, append the ifcurl setting and restart:
MSYS_NO_PATHCONV=1 docker exec forgejo sh -c 'printf "\n[ifcurl]\nPREVIEW_SERVICE_URL = http://ifcurl:8000\n" >> /data/gitea/conf/app.ini'
docker compose restart forgejo
Verify the setup
Check that Forgejo is serving the ifcurl assets:
http://localhost:3000/assets/ifcurl.js
You should see JavaScript, not a 404.
What works
| Feature | Works? |
|---|---|
"View in 3D" button on .ifc files |
Yes |
| Browser WebGL viewer | Yes |
| PR diff 3D renders (green=added, red=removed) | Yes |
[label](ifc://...) links in markdown → inline preview |
Yes |
CLI rendering (ifcurl render "ifc://...") |
Yes |
Bare ifc://... text in markdown |
No — needs Go patch + Forgejo rebuild |
For normal workflows, use [label](ifc://...) link syntax — the viewer's
Issue button generates this format automatically.
Testing the diff render
To see a diff render on a commit page:
- Push an
.ifcfile to a Forgejo repo - Modify the file (move geometry, add/remove elements) and push a second commit
- Open the second commit's page in Forgejo — the diff section for the
.ifcfile shows a rendered PNG with added geometry in green and removed in red - Click the image to open the interactive viewer at that commit's viewpoint
Useful commands
# View logs for all services
docker compose logs -f
# View ifcurl logs only
docker compose logs ifcurl
# Stop everything
docker compose down
# Rebuild ifcurl image after code changes
docker compose build ifcurl
docker compose up -d
Tips
- Model not visible in viewer? Click the fit button in the toolbar to fit the camera to the model bounds.
- Git Bash path mangling: prefix
docker execcommands that use Linux paths withMSYS_NO_PATHCONV=1. - Forgejo data (repos, users, settings) is stored in the
forgejo-datanamed Docker volume and persists across container restarts. It is lost if you remove the volume (docker compose down -v). - The ifcurl service clones remote git repos as bare repos into the container's
cache on first use. Mutable refs (
@heads/,@HEAD) trigger agit fetchon each request; immutable refs (commit hashes, tags) use the cache as-is. - The Go patch in the ifcurl repo was written against Forgejo v13.0. As of
this writing the latest release is v15.0.0. The patch is optional and only
needed for bare
ifc://URL rendering in markdown.