I run an Etsy print-on-demand shop on the side — book-lover and travel apparel. Every design starts as one vector file, and from there it needs to become a handful of different things: web preview images, listing photos, whatever format the print provider actually wants. Doing that by hand in an image editor is fine for one listing and miserable for ten.

Comb started as the fix for that. It’s grown since then, but it’s not running my whole pipeline — it’s a couple of pieces of it, stitched together enough to save me from repeating the same manual export five times per design.

One Vector, Several Outputs

The first version was small: a Flask app that takes one SVG and rasterizes it into the sizes and formats I need, using cairosvg to handle the SVG-to-raster conversion and Pillow for the resizing and format work on top. Nothing clever in the conversion itself — the point was just that changing the design upstream means one upload instead of re-exporting it five different ways by hand.

Adding the Mockup Workflow

Once comb existed as a conversion tool, it made sense to extend it into mockup generation rather than build a separate app — so it’s a second Flask blueprint in the same project.

The workflow: click to calibrate where the print area sits on a blank shirt photo, and comb remembers those coordinates. It also auto-detects whether the shirt is light or dark and adjusts the blend mode so the design doesn’t look wrong on one or the other. Feed it a design, get a zip of mockups back.

It didn’t work right away. There was a blueprint static file path bug that took a bit to track down, and the blend mode was actively wrong on light shirts specifically — fine on dark, off on light, which is exactly the kind of bug that hides for longer than it should because you only notice it half the time.

The two workflows — conversion and mockups — still work as separate steps right now, and the print-area calibration is per set of mockups, not per mockup image, so if different colors in a mockup set are in different positions, then it doesnt look right. Both are on the list: make the print area adjustable per image, and maybe fold the two workflows into one so a design goes in one end and mockups + web/provider assets come out the other, instead of two passes.

The Volume That Didn’t Remount

Comb’s data lives on a DigitalOcean block volume attached to the droplet. At some point it didn’t remount after a reboot — no fstab entry telling it to — and comb came back up with no data. Nothing was actually lost; I had the original files and just redid the runs. But it happened twice before I did anything about it.

The fix, so far, is an fstab entry with the nofail option, so a missing mount doesn’t hang the boot. I’m not fully convinced yet that it plays well with how Docker and containerd handle the volume on startup — it’s held since I added it, but I haven’t stress-tested it enough to call it solved. More of a “watching it” than a “fixed it.”