{"id":25431050,"url":"https://github.com/ericls/imgdd","last_synced_at":"2026-05-11T06:10:18.781Z","repository":{"id":277112293,"uuid":"805646223","full_name":"ericls/imgdd","owner":"ericls","description":"simple image hosting program","archived":false,"fork":false,"pushed_at":"2026-04-21T23:08:42.000Z","size":1813,"stargazers_count":94,"open_issues_count":0,"forks_count":20,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-04-22T00:33:06.136Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ericls.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-05-25T04:21:25.000Z","updated_at":"2026-04-21T23:08:46.000Z","dependencies_parsed_at":"2025-09-20T23:59:11.886Z","dependency_job_id":"0ae027a2-42a2-4367-bf43-b00f467df82d","html_url":"https://github.com/ericls/imgdd","commit_stats":null,"previous_names":["ericls/imgdd"],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/ericls/imgdd","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericls%2Fimgdd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericls%2Fimgdd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericls%2Fimgdd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericls%2Fimgdd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ericls","download_url":"https://codeload.github.com/ericls/imgdd/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ericls%2Fimgdd/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32287399,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T18:29:39.964Z","status":"online","status_checked_at":"2026-04-26T02:00:05.962Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-17T03:48:54.516Z","updated_at":"2026-05-11T06:10:18.775Z","avatar_url":"https://github.com/ericls.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# IMGDD\n\n[![Backend test](https://github.com/ericls/imgdd/actions/workflows/backend.yaml/badge.svg?branch=main)](https://github.com/ericls/imgdd/actions/workflows/backend.yaml)\n[![GitHub Release](https://img.shields.io/github/v/release/ericls/imgdd)](https://github.com/ericls/imgdd/releases/)\n[![Docker Image Version](https://img.shields.io/docker/v/ericls/imgdd)](https://hub.docker.com/r/ericls/imgdd)\n\n## Introduction\nIMGDD is a simple, self-hostable image hosting program.\n\nIt powers an image hosting project that began in early 2023. After some users requested the source code, I decided to make it available following a bit of refactoring and cleanup.\n\nAs of February 2025, the project handles over 1 TB of traffic and 4.2 million requests per day. Since continued growth may force me to stop accepting new images, I open-sourced IMGDD so that anyone can run their own instance and serve their images.\n\n## Live Instances\n- [imgdd.com](https://imgdd.com)\n\n## Features\n- **Pluggable storage backends**: S3 (and S3-compatible services like MinIO), local filesystem, WebDAV, and IPFS MFS. Multiple backends can be enabled at once with configurable priority, defined in the database or the config file. Images can be replicated between backends with the `replicate` CLI command.\n- **Flexible URL formats**: `canonical` (proxied from the best available backend) and `direct` (routed through a specific backend); per-image delivery chooses the highest-priority enabled backend.\n- **Upload pipeline**: automatic EXIF stripping, MIME-type detection with declared/detected mismatch rejection, size limits, and deduplication across stored images. Revisions are linked back to a root image.\n- **Optional safe-image check**: delegate NSFW/abuse screening to an external HTTP endpoint.\n- **Captcha protection**: Google reCAPTCHA or Cloudflare Turnstile, wired into GraphQL via an `@captchaProtected` directive.\n- **Rate limiting** on uploads and other sensitive endpoints.\n- **Identity \u0026 access control**: email/password auth, organizations, role/permission system with built-in roles, site-owner privilege, and password reset via email.\n- **Email backends**: SMTP or a dummy backend for development, with templated messages.\n- **GraphQL API** (gqlgen) covering images, viewer, users, organizations, roles/permissions, and storage definitions, with `@isAuthenticated` / `@isSiteOwner` directives.\n- **Web client**: React + Tailwind admin \u0026 user UI, including a site-admin area for managing users, roles, and storage definitions.\n- **Client plugin hooks**: a lightweight `window.registerPlugin` API lets custom JS inject content into named UI slots without rebuilding the frontend.\n- **Low resource usage**: a single Go binary serves the API, web client, and image proxying; Instance with 256M memory has comfortably handled 1 TB of traffic and 4.2 M requests per day in production.\n- **Operational toggles**: disable new uploads (`ALLOW_UPLOAD`) or new user signups (`ALLOW_NEW_USER`) at runtime.\n- **Background cleanup** of orphaned stored images across backends.\n- **Deployment-friendly**: single Go binary, official Docker image, TOML + env configuration, optional migrate-on-start, Nix flake for reproducible dev.\n- **CLI tooling**: migrations, user/role management, config generation, test email, storage replication, and dev helpers (`gql`, `jet`, `reset-db`, `dev-server` with hot reload).\n\n## Development\n\n### Prerequisites\n\n- Go 1.25+\n- Node.js 20 (for the frontend)\n- Docker \u0026 Docker Compose (for local services)\n\n\u003e If you use nix, you can just do `nix develop`.\n\n### Setup\n\n1. Copy the environment file and adjust if needed:\n   ```bash\n   cp .env.template .env\n   ```\n\n2. Start local services (PostgreSQL, Redis, MinIO ancient version):\n   ```bash\n   docker compose up -d\n   ```\n\n3. Run database migrations:\n   ```bash\n   go run . migrate\n   ```\n\n4. Populate built-in roles:\n   ```bash\n   go run . populate-built-in-roles\n   ```\n\n5. Create a user:\n   ```bash\n   go run . create-user --email you@imgdd.com --password yourpassword --is-site-owner\n   ```\n\n### Building \u0026 Running\n\n```bash\n# Build the frontend\ncd web_client \u0026\u0026 pnpm install \u0026\u0026 pnpm build \u0026\u0026 cd ..\n\n# Start the server\ngo run . serve\n\n# Start with auto-reload (requires air)\ngo run . dev-server\n```\n\n### Code Generation\n\nDev commands are available when running from source:\n\n```bash\n# Regenerate GraphQL code (gqlgen)\ngo run . gql\n\n# Regenerate Jet ORM code (requires running PostgreSQL)\ngo run . jet\n\n# Regenerate frontend GraphQL types\ncd web_client \u0026\u0026 pnpm gen\n```\n\n### Database Commands\n\n```bash\n# Run migrations\ngo run . migrate\n\n# Migrate to a specific version\ngo run . migrate --version 3\n\n# Create a new migration file\ngo run . make-migration --name add_some_table\n\n# Reset the database (dev only)\ngo run . reset-db\n```\n\nAll commands accept a `-c` / `--config` flag to specify the config file path, and a `--log-level` flag (default: `info`).\n\n## Deployment\nSee [Start guide in the Wiki](https://github.com/ericls/imgdd/wiki/Start-guide).\n\n## FAQ\nSee [FAQ in the Wiki](https://github.com/ericls/imgdd/wiki/FAQ).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fericls%2Fimgdd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fericls%2Fimgdd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fericls%2Fimgdd/lists"}