{"id":15658584,"url":"https://github.com/wyattjoh/ims","last_synced_at":"2026-03-03T17:08:24.775Z","repository":{"id":19883848,"uuid":"88175077","full_name":"wyattjoh/ims","owner":"wyattjoh","description":"image manipulation service, written in Go","archived":false,"fork":false,"pushed_at":"2025-06-02T21:26:31.000Z","size":2264,"stargazers_count":22,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-06-03T11:53:33.058Z","etag":null,"topics":["go","image-optimization","webservice"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wyattjoh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","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},"funding":{"github":"wyattjoh"}},"created_at":"2017-04-13T14:41:20.000Z","updated_at":"2025-06-02T21:26:49.000Z","dependencies_parsed_at":"2024-06-19T03:04:01.922Z","dependency_job_id":"0d316647-f53e-4980-9a77-181bd2691bbb","html_url":"https://github.com/wyattjoh/ims","commit_stats":null,"previous_names":[],"tags_count":33,"template":false,"template_full_name":null,"purl":"pkg:github/wyattjoh/ims","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wyattjoh%2Fims","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wyattjoh%2Fims/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wyattjoh%2Fims/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wyattjoh%2Fims/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wyattjoh","download_url":"https://codeload.github.com/wyattjoh/ims/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wyattjoh%2Fims/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30052291,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-03T15:26:47.567Z","status":"ssl_error","status_checked_at":"2026-03-03T15:26:17.132Z","response_time":61,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["go","image-optimization","webservice"],"created_at":"2024-10-03T13:13:01.129Z","updated_at":"2026-03-03T17:08:24.756Z","avatar_url":"https://github.com/wyattjoh.png","language":"Go","funding_links":["https://github.com/sponsors/wyattjoh"],"categories":[],"sub_categories":[],"readme":"# ims\n\n![Tests](https://github.com/wyattjoh/ims/workflows/Test/badge.svg)\n[![Go Report](https://goreportcard.com/badge/github.com/wyattjoh/ims)](https://goreportcard.com/report/github.com/wyattjoh/ims)\n[![Docker Image Size](https://img.shields.io/microbadger/image-size/wyattjoh/ims.svg)](https://hub.docker.com/r/wyattjoh/ims/)\n[![GitHub release](https://img.shields.io/github/release/wyattjoh/ims.svg)](https://github.com/wyattjoh/ims/releases/latest)\n\nThe [ims](https://github.com/wyattjoh/ims) (image manipulation service) is\ndesigned to assist with performing image transformations and optimizations on\nthe fly using a full Go solution provided by:\n[github.com/disintegration/imaging](https://github.com/disintegration/imaging).\n\nThe application is also fitted with pprof for performance profiling, refer to\n[golang.org/pkg/net/http/pprof](https://golang.org/pkg/net/http/pprof/) for\nusage information.\n\n## Installation\n\nYou can use the standard Go utility to get the binary and compile it yourself:\n\n```bash\ngo get -u github.com/wyattjoh/ims/...\n```\n\nFrom Homebrew:\n\n```bash\nbrew install wyattjoh/stable/ims\n```\n\nDocker:\n\n```bash\ndocker pull wyattjoh/ims\n# or via the Github Container Registry\ndocker pull ghcr.io/wyattjoh/ims\n```\n\nOr by visiting the [Releases](https://github.com/wyattjoh/ims/releases/latest)\npage to download a pre-compiled binary for your arch/os.\n\n## Usage\n\nThe ims application can be used as such:\n\n```\nNAME:\n   ims - Image Manipulation Server\n\nUSAGE:\n   ims [global options] command [command options] [arguments...]\n\nCOMMANDS:\n     help, h  Shows a list of commands or help for one command\n\nGLOBAL OPTIONS:\n   --listen-addr value     the address to listen for new connections on (default: \"127.0.0.1:8080\")\n   --backend value         comma separated \u003chost\u003e,\u003corigin\u003e where \u003corigin\u003e is a pathname or a url (with scheme) to load images from or just \u003corigin\u003e and the host will be the listen address\n   --origin-cache value    cache the origin resources based on their cache headers (:memory: for memory based cache, directory name for file based, not specified for disabled)\n   --signing-secret value  when provided, will be used to verify signed image requests made to the domain\n   --tracing-uri value     when provided, will be used to send tracing information via opentracing\n   --signing-with-path     when provided, the path will be included in the value to compute the signature\n   --disable-metrics       disable the prometheus metrics\n   --timeout value         used to set the cache control max age headers, set to 0 to disable (default: 15m0s)\n   --cors-domain value     use to enable CORS for the specified domain (note, this is not required to use as an image service)\n   --debug                 enable debug logging and pprof routes\n   --json                  print logs out in JSON\n   --help, -h              show help\n   --version, -v           print the version\n\n\n```\n\nThe default behavior is to serve images out of the present working directory,\nbut it can also be changed to another folder or to an origin server for it to\nmake the request to.\n\nThis application provides no transformation caching support, but will attach\ncache-friendly headers, it is recommend that when deploying in production you\ndo so behind a service like [Varnish](https://www.varnish-cache.org/) or a CDN\nlike [Fastly](https://www.fastly.com/).\n\nSome examples of usage:\n\n```bash\n# will serve images from the $PWD\nims\n\n# will serve images from the specified folder\nims --backend /specific/folder/with/images\n\n# when the request is made to the alpha.example.com host, will serve images from\n# the /var/images/alpha directory, when the request is made to the\n# beta.example.com host, will serve images from the /var/images/beta directory.\nims --backend alpha.example.com,/var/images/alpha \\\n    --backend beta.example.com,/var/images/beta\n```\n\n## Backends\n\nDifferent backends are supported by [ims](https://github.com/wyattjoh/ims).\n\n### Google Cloud Storage\n\nIf the `--backend` is specified with an origin with a `gs://` scheme,\n[ims](https://github.com/wyattjoh/ims) will use the Google Cloud Storage\nprovider. _Note that for authentication purposes, the environment variable\n`GOOGLE_APPLICATION_CREDENTIALS` must be present, refer to\n[Google Application Default Credentials](https://developers.google.com/identity/protocols/application-default-credentials)\nfor more information._\n\nExample:\n\n```bash\nexport GOOGLE_APPLICATION_CREDENTIALS=/path/to/your/application-credentials.json\nims --backend gs://bucket-name\n```\n\n### Minio/Amazon S3\n\nIf the `--backend` is specified with an origin with a `s3://` scheme,\n[ims](https://github.com/wyattjoh/ims) will use the S3 provider. For\nconfiguration, you must specify the following environment variables:\n\n- `S3_ENDPOINT`: the endpoint to use as the base for the s3 client, can be a Amazon S3 endpoint or\n  a [Minio](https://www.minio.io/) one.\n- `S3_ACCESS_KEY_ID`: access key id.\n- `S3_ACCESS_KEY_SECRET`: access key secret.\n- `S3_DONT_USE_SSL`: `TRUE` if your endpoint should be accessed by http instead of https (Default: `FALSE`).\n\nExample:\n\n```bash\nexport S3_ENDPOINT=s3.us-east-2.amazonaws.com\nexport S3_ACCESS_KEY_ID=my-aws-access-key-id\nexport S3_ACCESS_KEY_SECRET=my-aws-key-secret\nexport S3_DONT_USE_SSL=FALSE\nims --backend s3://bucket-name\n```\n\n### Other HTTP/HTTPS\n\nIf the `--backend` is specified with an origin with a `http://` or `https://`\nscheme, then [ims](https://github.com/wyattjoh/ims) will use the standard\nhttp(s) based provider. This will simply perform a GET request (merging the\nrelative path) against the provided origin url.\n\nExample:\n\n```bash\nims --backend https://some-origin-url.com/\n```\n\n### Local/Filesystem\n\nIf the `--backend` is specified with an origin without a scheme, it will be\ninferred that the origin is a local folder instead. This folder may be relative,\nabsolute, and will not be expanded. It is therefore not recommended to use `~`\nin your pathnames.\n\nExample:\n\n```bash\nims --backend /some/folder/location\n```\n\n### Proxy Mode\n\nIf the `--backend` is specified with a `:proxy:` option, it will enable\n[ims](https://github.com/wyattjoh/ims) to use the provided `url` query parameter\non each request to load the image from a remote source. For security reasons\nhowever, this requires that the `--signing-secret` and `--signing-with-path` is\nalso provided.\n\nExample:\n\n```bash\nimg --backend :proxy: --signing-secret \"keyboard cat\" --signing-with-path\n```\n\n## Signing\n\nWhen `--signing-secret` is provided, all requests must include a `sig` query\nparameter that contains the HS256 signature of the sorted query parameters\nencoded as a hex string via the provided secret. This can be used to prevent\nabuse of the ims, and is strongly recommended in production.\n\nThis can get pretty powerful when combined with the `--signing-with-path` option\nthat will include the path in the signature content as it would essentially\nallow you to have ims act as a proxy to your private S3/GCS bucket, and would\nprevent abuse via subsequent requests.\n\nAn example of signing a request in Node:\n\n```javascript\nconst Crypto = require(\"crypto\");\nconst querystring = require(\"querystring\");\n\nconst transformationOptions = {\n  width: 100,\n  height: 200,\n};\n\n// Change this to the secret that you gave to ims via the`--signing-secret`\n// flag.\nconst secret = \"keyboard cat\";\n\n// Create the sorted query object.\nlet value = Object.keys(transformationOptions)\n  .sort()\n  .reduce((result, key) =\u003e {\n    result.push(querystring.stringify({ [key]: transformationOptions[key] }));\n    return result;\n  }, [])\n  .join(\"\u0026\");\n\n// If you've enabled --signing-with-path, you need to include the path component\n// in your value:\n//\n// value = \"/my-image.jpg?\" + value;\n//\n\nconst sig = Crypto.createHmac(\"sha256\", secret).update(value).digest(\"hex\");\n\nconsole.log(value + \"\u0026sig=\" + sig);\n```\n\nExample:\n\n```bash\n# require all requests to have their query parameters signed with a HS256\n# signature\nims --signing-secret \"keyboard cat\"\n\n# require all requests to have their query parameters and path signed with a\n# HS256 signature\nims --signing-secret \"keyboard cat\" --signing-with-path\n```\n\n## API\n\nImage manipulations can be applied by appending a query string with the\nfollowing parameters and as such matches the\n[Fastly API](https://docs.fastly.com/api/imageopto) as much as possible. These\nare also in the same order that they are processed.\n\n- `crop`: crops the image in the form: `{width},{height}`\n- `resize-filter`: select the resize filter to be used. Implementation is sourced via the [github.com/disintegration/imaging](https://github.com/disintegration/imaging) package and we provide the following filters:\n  - `box`: Box filter (averaging pixels).\n  - `netravali`: Mitchell-Netravali cubic filter (BC-spline; B=1/3; C=1/3).\n  - `linear`: Linear filter.\n  - `nearest`: Nearest-neighbor filter, no anti-aliasing.\n  - `gaussian`: Gaussian is a Gaussian blurring Filter.\n  - `lanczos` (**default**): Lanczos filter (3 lobes).\n- `format`: enables source transcoding:\n  - `jpeg`: converts all images to `image/jpeg` encoding with lossless compression, some additional parameters are supported:\n    - `quality`: the quality out of 100 for the output image (Default: 75).\n  - `png`: converts image to `image/png` encoding\n  - `gif`: converts image to `image/gif` encoding\n- `width`: output image width (default is the original width).\n- `height`: output image height. If both `width` and `height` are provided, the\n  `width` will be used instead.\n- `fit`: The fit parameter controls how the image will be constrained within the provided size (width | height) values:\n  - `bounds`: resize the image to fit entirely within the specified region\n  - `cover` (**default**): resize the image to entirely cover the specified region.\n- `orient`: changes the image orientation:\n  - `r`: Orientate the image right.\n  - `l`: Orientate the image left.\n  - `h`: Flip the image horizontally.\n  - `v`: Flip the image vertically.\n  - `hv`: Horizontal and Vertical flip.\n  - `vh`: Vertical and Vertical flip.\n  - `2`: Flip the image horizontally.\n  - `3`: Horizontal and Vertical flip.\n  - `4`: Flip the image vertically.\n  - `5`: Horizontal flip then orientate the image left.\n  - `6`: Orientate the image right.\n  - `7`: Horizontal flip then orientate the image right.\n  - `8`: Orientate the image left.\n- `blur`: produces a blurred version of the image using a Gaussian function,\n  must be positive and indicates how much the image will be blurred, refers to\n  the sigma value.\n- `sig`: Used to specify the signing signature, see [Signing](#signing) above.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwyattjoh%2Fims","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwyattjoh%2Fims","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwyattjoh%2Fims/lists"}