展示 HN:DD Photos – 开源照片相册网站生成器 (Go 和 SvelteKit)
Show HN: DD Photos – open-source photo album site generator (Go and SvelteKit)

原始链接: https://github.com/dougdonohoe/ddphotos

对现有照片分享网站速度慢和杂乱无章感到沮丧,作者构建了DD Photos——一个快速、简单、无干扰的解决方案,现在作为开源软件提供(photos.donohoe.info)。该系统专注于展示照片,提供简洁的界面,具有深色/浅色主题和移动端友好浏览。 DD Photos通过从Lightroom、Photos或Google Photos等现有整理工具导出相册(文件夹)来工作。可选的`photogen.txt`文件允许添加说明和自定义排序。然后,`photogen`工具将图像调整为WebP格式并生成静态文件(HTML、CSS、JavaScript)——无需服务器端代码或数据库。 主要功能包括简洁的相册视图、具有滑动导航的响应式照片网格、可分享的永久链接以及用于社交媒体的OpenGraph支持。后端高效处理图像调整大小和元数据剥离。部署简单,利用静态网站托管(如Apache或AWS S3)。DD Photos使用SvelteKit构建,并得到Claude Code的大力协助,优先考虑个人照片分享的速度和简洁性。

## DD Photos:快速简单的照片分享方案 开发者 dougdonohoe 对现有的照片分享选项速度慢且充斥广告感到沮丧,因此创建了 **DD Photos**,一个用于快速与家人和朋友分享照片的开源网站生成器。DD Photos 使用 Go 和 SvelteKit 构建,它从整理好的照片文件夹生成静态网站——无需数据库或服务器端代码,即可部署在 Apache 或 S3 等平台上。 该项目利用命令行工具 (`photogen`) 将图像优化为 WebP 格式并创建必要的索引。开发者认为 AI 助手 Claude Code 在完成全栈开发过程中发挥了重要作用。 评论者 giancarlostoro 表达了对 Windows 和 Mac 上默认照片应用速度缓慢的沮丧,强调了像 DD Photos 这样简化且高性能解决方案的需求。 **链接:** [https://github.com/dougdonohoe/ddphotos](https://github.com/dougdonohoe/ddphotos) & [https://photos.donohoe.info](https://photos.donohoe.info)
相关文章

原文

I was dissatisfied with photo sharing sites, especially Apple's iCloud shared albums, which typically take 20+ seconds to load. Other sites for sharing have their own irritations like cumbersome UIs, advertising, hawking of photo paraphernalia and social media distractions.

I just want to share my photos with friends and family. I want it fast, easy, mobile friendly, and distraction free. Focus on the photos. So I built this, with help from Claude Code, and it is what is behind photos.donohoe.info. It's pretty good and meets my needs. Maybe it will meet yours too, which is why I've open-sourced it.

The site has a home page, with all of your albums and their description. You can easily switch between dark and light themes. Click/touch an album and you see a grid of all photos. Click/touch a photo to see the full size version and a caption, if it has one. You can easily swipe between photos (or use arrow keys on a laptop). It works great on mobile, tablet, and desktop.

Here's what it looks like on a big display (see SCREENSHOTS.md for larger versions):

screenshots.png

The idea is that you already use something else to curate and filter your photos. Maybe it is Adobe Lightroom Classic (my tool). Or maybe it is Apple Photos or Google Photos. It doesn't matter, but once you get a selection of photos that comprise an album, you export the photos into a folder. All the photos in a folder make up an album. It's that simple.

You can create an optional photogen.txt file in each album folder to define captions for each photo. This file can also be used to define the album's sort order, if order-by-date isn't sufficient.

With DD Photos, you define where your albums live in an albums.yaml file. In a separate descriptions.txt you provide a short description of each album.

Once you have defined where your photos live, you run the photogen tool, which resizes the photos for web viewing and generates index files that the web app uses.

That's it. Now, you can easily view your photo albums on your machine using the dev server.

Finally, there is a build step which creates a static site that can easily be deployed to a machine that has a web server (like Apache) or theoretically something like AWS S3. No code runs on a server. No database is needed. It's just HTML, CSS, JavaScript and your (resized) photos.

Website features:

  • Concise album cards with description, number of photos, date range and your choice of cover photo.
  • Album page has a nicely justified photo grid layout with PhotoSwipe lightbox that adjusts well to any screen size.
  • Keyboard support: arrow keys navigate in lightbox, ESC key exits lightbox and returns to home page from album page.
  • Optional per-photo descriptions via photogen.txt: used as image "alt" text, grid mouse-hover caption (desktop), always-visible caption (mobile), and lightbox caption.
  • Each photo has a shareable permalink (e.g., /albums/patagonia/5) accessible via a copy-to-clipboard button.
  • Dark/light theme toggle.
  • OpenGraph tags for rich link previews when sharing album or photo URLs on social media or messaging apps, using a JPEG version of the album cover photo as the preview image.

Backend features:

  • Two efficient WebP image sizes created: grid (600px) and full (1600px).
  • EXIF metadata extraction (dimensions, date) stored in JSON.
  • All image metadata stripped from WebP output (smaller files, no GPS leak).
  • Concurrent image resizing via goroutines (buffered channel, WaitGroup).
  • Dry-run mode by default (use -doit to write files).
  • Optionally use photogen.txt to override sort order (default is by capture date).

The photogen Go program (cmd/photogen/photogen.go) resizes your photos to WebP format and generates the JSON index files (albums.json, per-album index.json) that are consumed by the frontend. It also generates a sitemap.xml file that identifies each album.

The site (in web, a Node.js app) is built with SvelteKit and statically generated. The HTML shell and assets are pre-built files served directly by a web server, with photo data fetched client-side from the static JSON indexes generated by photogen.

There are many ways to deploy a static site like this. It is somewhat outside the scope of this project to tackle all the various deployment strategies, but I may add more options in the future if there is interest.

That said, I happen to already run an Apache server on an AWS EC2 instance that is fronted by CloudFront. Deployment for me is an rsync to this server, and I've included the script which does this. My actual AWS setup is maintained in Terraform files in a private repo, but I provide some details in the README-DEV for those that are curious. Part of what makes my photos site fast is the use of the CDN and the fact that the site is entirely static.

The following setup instructions are Mac-centric (via Homebrew). Linux should work with equivalent package manager commands (apt, yum). Windows users should use WSL2.

# Install Go, vips library and pkg-config dependency (for photogen)
brew install go vips pkg-config

# In root of this repo, fetch Go libraries
go mod download

The website is a Node.js app. Install nvm first if you don't already have it.

# Install Node and dependencies (for the web app):
make web-nvm-install  # installs the Node version specified in web/.nvmrc
make web-npm-install  # install npm dependencies

# Optional: Install playwright dependencies if running e2e tests
make web-playwright-install  # installs Playwright + Chromium for e2e tests

You may also want to install Docker if you don't have it, as it is required for testing site behavior using Apache.

Once you have the required software installed, you should be able to build and view the sample site provided within this repo (in the sample dir).

# Resize photos and generate .json files
make sample-photogen

# Run dev server
make sample-npm-run-dev

You should see a VITE message and a browser window should open at localhost:5173.

You can also build the static site and test it in Apache (requires Docker and assumes photogen has been run).

# Build docker image (one time)
make web-docker-build

# Build sample site
make sample-build

# Run it in Docker/Apache
make web-docker-run 

You should be able to see the site at localhost:8080.

Congratulations! Now that you've got the sample site working, you can work on your own albums. You can start first by adding to the sample config in sample/config/albums.yaml. Or you can start building your own using the examples in config. The sections below provide details about how everything works.

There are three configuration files one needs to build a site:

  • albums.yaml - Defines your list of albums, an id for the site (useful if you have multiple sites), and the locations of your photos.
  • descriptions.txt - The description of the album that you see. This is in a separate file to allow sharing of albums across sites (useful in development), and also enables localization in the future.
  • site.env - Global values like site name, description and copyright info.

The config directory contains examples of each, and serves as detailed documentation of each parameter. The sample/config files are a working example that drives our "Sample Photo Album".

The config directory is the default, so feel free to put your config files there (just copy the examples and edit them). Or edit the sample app. Or create your own config directory and use the --config-dir option.

cp config/albums.example.yaml config/albums.yaml
cp config/descriptions.example.txt config/descriptions.txt
cp config/site.example.env config/site.env

TIP: If you use prod as your settings.id value in albums.yaml, you can use some provided make targets, like use-prod.

The Makefile is a good reference for the commands (you used them to run the sample site). Assuming you put your config files in config, these commands are useful:

# Dry run of indexing and resizing
go run cmd/photogen/photogen.go -resize -index

# Do it for real
go run cmd/photogen/photogen.go -resize -index -doit

NOTE: output goes to web/albums/[ID] by default. For example, the sample site is in web/albums/sample. A symlink from web/static/albums points to the current site data you are working with. See the use-prod Makefile target for an example of how this symlink is created.

Once photogen has been successfully run, you can run the dev server.

# Make sure symlink is correct
ln -sfn ../albums/my-site web/static/albums # if id is not 'prod'
make use-prod # if id is 'prod'

# Run dev server
make web-npm-run-dev

To test the build process:

This deletes and recreates the web/build directory, which will have all the files needed to run the site, including copies of your resized photos.

To run it using the Docker/Apache image:

You should be able to see the site at localhost:8080.

Assuming the dev server is running, you can run the playwright tests:

make web-playwright-test-dev

These should pass against sample, but some will fail against your site, because values are hardcoded at the moment (i.e., the smoke/caption tests reference specific album names - antarctica and uganda).

You can also run some smoke tests as defined in bin/test-photos-apache.sh. Assuming Docker/Apache is running:

If Docker/Apache isn't running, you can auto-start and stop it to run these tests against sample site:

See README-DEV for more details about photogen, the SvelteKit site, deployment and other technical details.

Much of this project was built with Claude Code. See HISTORY.md for a detailed session log covering WebP conversion, concurrent image resizing, static site setup, Apache URL routing and Docker test environment, photo descriptions and captions, photo permalinks, Open Graph and social sharing tags, SvelteKit client-side navigation, Playwright E2E tests, YAML-based album configuration, deploy scripts, open-source prep, and more.

This project is licensed under the GNU Affero General Public License v3.0 (AGPL v3).

If you'd like to use this project under different terms, contact doug [at] donohoe [dot] info.

联系我们 contact @ memedata.com