{"id":13514053,"url":"https://github.com/cactus/go-camo","last_synced_at":"2025-10-21T04:08:50.036Z","repository":{"id":3617154,"uuid":"4682612","full_name":"cactus/go-camo","owner":"cactus","description":"A secure image proxy server","archived":false,"fork":false,"pushed_at":"2025-03-30T02:41:53.000Z","size":1371,"stargazers_count":266,"open_issues_count":0,"forks_count":46,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-03-30T03:26:14.983Z","etag":null,"topics":["camo","go","golang","golang-application","image-proxy","mixed-content","mixed-content-error","proxy-server"],"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/cactus.png","metadata":{"files":{"readme":"README.adoc","changelog":"CHANGELOG.adoc","contributing":null,"funding":null,"license":"LICENSE.adoc","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2012-06-16T05:36:17.000Z","updated_at":"2025-03-30T02:41:57.000Z","dependencies_parsed_at":"2023-11-15T19:28:54.497Z","dependency_job_id":"0bd5e3e1-b213-4e68-93be-cad64c4291c6","html_url":"https://github.com/cactus/go-camo","commit_stats":{"total_commits":715,"total_committers":23,"mean_commits":31.08695652173913,"dds":"0.26433566433566436","last_synced_commit":"1f86cb50dde8bffffa6c47ac755830465fa3281a"},"previous_names":[],"tags_count":74,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cactus%2Fgo-camo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cactus%2Fgo-camo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cactus%2Fgo-camo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cactus%2Fgo-camo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cactus","download_url":"https://codeload.github.com/cactus/go-camo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246407401,"owners_count":20772126,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["camo","go","golang","golang-application","image-proxy","mixed-content","mixed-content-error","proxy-server"],"created_at":"2024-08-01T05:00:44.800Z","updated_at":"2025-10-21T04:08:50.030Z","avatar_url":"https://github.com/cactus.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"= go-camo\n:toc: macro\n:hide-uri-scheme:\nifdef::env-github[]\n:toc-title:\n:tip-caption: :bulb:\n:note-caption: :bulb:\n:important-caption: :heavy_exclamation_mark:\n:caution-caption: :fire:\n:warning-caption: :warning:\nendif::[]\n\n// some links\n:link-atmos-camo: https://github.com/atmos/camo[camo]\n:link-hmac: https://en.wikipedia.org/wiki/HMAC[HMAC]\n:link-hsts: https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security[HSTS]\n:link-asciidoctor: https://asciidoctor.org[asciidoctor]\n:link-scdoc: https://git.sr.ht/~sircmpwn/scdoc/[scdoc]\n:link-damontools: https://cr.yp.to/daemontools.html[daemontools]\n:link-runit: https://en.wikipedia.org/wiki/Runit[runit]\n:link-upstart: https://en.wikipedia.org/wiki/Upstart_(software)[upstart]\n:link-launchd: https://en.wikipedia.org/wiki/Launchd[launchd]\n:link-systemd: https://www.freedesktop.org/wiki/Software/systemd/[systemd]\n:link-daemontools-why: https://cr.yp.to/daemontools/faq/create.html#why[daemontools/why]\n:link-heroku-buildpack-go: https://github.com/kr/heroku-buildpack-go\n:link-dns-rebinding: https://en.wikipedia.org/wiki/DNS_rebinding[dns rebinding]\n:link-ip6-special-addresses: https://en.wikipedia.org/wiki/IPv6_address#Special_addresses\n:link-docker-containers: https://hub.docker.com/r/cactus4docker/go-camo[docker hub]\n:link-github-containers: https://github.com/cactus/go-camo/pkgs/container/go-camo[github packages]\n:link-releases: https://github.com/cactus/go-camo/releases[binary releases]\n:link-mit-license: https://www.opensource.org/licenses/mit-license.php[MIT license]\n:link-mrsaints: https://github.com/MrSaints[MrSaints]\n:link-arachnys-fork: https://github.com/arachnys/go-camo[fork]\n:link-smokescreen: https://github.com/stripe/smokescreen[smokescreen]\n:link-codeberg-mirror: https://codeberg.org/dropwhile/go-camo[codeberg-mirror]\n\nimage:https://img.shields.io/github/release/cactus/go-camo.svg[Current Release,link=http://github.com/cactus/go-camo/releases]\nimage:https://img.shields.io/docker/image-size/cactus4docker/go-camo?label=container%20size[Container Image Size (latest by date),link=https://hub.docker.com/r/cactus4docker/go-camo]\nimage:https://github.com/cactus/go-camo/workflows/unit-tests/badge.svg[BuildStatus]\nimage:.github/img-readme-license.svg[License,link=https://github.com/cactus/go-camo/blob/master/LICENSE.md]\nimage:https://img.shields.io/badge/codeberg-1890ff?label=mirror[mirror:codeberg,link=https://codeberg.org/dropwhile/go-camo]\n// image:https://circleci.com/gh/cactus/go-camo.svg?style=svg[CircleCI,link=https://circleci.com/gh/cactus/go-camo]\n\nifdef::env-github[]\n[discrete]\n== Contents\nendif::[]\ntoc::[]\n\n== About\n\ngo-camo is a go version of a https://github.com/atmos/camo[camo] server.\n\nA camo server is a special type of image proxy\nthat proxies non-secure images over SSL/TLS,\nin order to prevent mixed content warnings on secure pages.\nThe server works in conjunction with back-end code\nthat rewrites image URLs and signs them with an {link-hmac}.\n\n== How it works\n\nThe general steps are as follows:\n\n*   A client requests a page from the web app.\n*   The original URL in the content is parsed.\n*   An HMAC signature of the URL is generated.\n*   The URL and hmac are encoded.\n*   The encoded URL and hmac are placed into the expected format,\n    creating the signed URL.\n*   The signed URL replaces the original image URL.\n*   The web app returns the content to the client.\n*   The client requests the signed URL from Go-Camo.\n*   Go-Camo validates the HMAC, decodes the URL,\n    then requests the content from the origin server and streams it to the client.\n\n[source,text]\n----\n  +----------+           request            +-------------+\n  |          |-----------------------------\u003e|             |\n  |          |                              |             |\n  |          |                              |   web-app   |\n  |          | img src=https://go-camo/url  |             |\n  |          |\u003c-----------------------------|             |\n  |          |                              +-------------+\n  |  client  |\n  |          |     https://go-camo/url      +-------------+ http://some/img\n  |          |-----------------------------\u003e|             |---------------\u003e\n  |          |                              |             |\n  |          |                              |   go-camo   |\n  |          |           img data           |             |    img data\n  |          |\u003c-----------------------------|             |\u003c---------------\n  |          |                              +-------------+\n  +----------+\n----\n\nGo-Camo supports both hex and base64 encoded urls at the same time.\n\n[%header%autowidth.stretch]\n|===\n| encoding | tradeoffs\n| hex | longer, case insensitive, slightly faster\n| base64 | shorter, case sensitive, slightly slower\n|===\n\nBenchmark results with go1.12.7:\n\n[source,text]\n----\nBenchmarkHexEncoder-4           \t 1000000\t      1364 ns/op\nBenchmarkB64Encoder-4           \t 1000000\t      1447 ns/op\nBenchmarkHexDecoder-4           \t 1000000\t      1312 ns/op\nBenchmarkB64Decoder-4           \t 1000000\t      1379 ns/op\n----\n\nFor examples of url generation, see the link:examples/[examples] directory.\n\nWhile Go-Camo will support proxying HTTPS images as well,\nfor performance reasons you may choose to filter HTTPS requests out from proxying,\nand let the client simply fetch those as they are.\nThe linked code examples do this.\n\nNote that it is recommended to front Go-Camo with a CDN when possible.\n\n== Differences from Camo\n\n*   Go-Camo supports 'Path Format' url format only.\n    Camo's \"Query String Format\" is not supported.\n*   Go-Camo supports some optional \"allow/deny\" origin filters.\n*   Go-Camo supports client http keep-alives.\n*   Go-Camo provides native SSL support.\n*   Go-Camo provides native HTTP/2 support\n*   Go-Camo supports using more than one os thread (via GOMAXPROCS)\n    without the need of multiple instances or additional proxying.\n*   Go-Camo builds to a static binary.\n    This makes deploying to large numbers of servers a snap.\n*   Go-Camo supports both Hex and Base64 urls.\n    Base64 urls are smaller, but case sensitive.\n*   Go-Camo supports HTTP HEAD requests.\n*   Go-Camo allows custom default headers to be added --\n    useful for things like adding {link-hsts} headers.\n\n== Installing pre-built binaries\n\nDownload the tarball appropriate for your OS/ARCH from {link-releases}. +\nExtract, and copy files to desired locations.\n\n== Building\n\nBuilding requires:\n\n*   make\n*   posix compatible shell (sh)\n*   git\n*   go (most recent version recommended)\n*   {link-scdoc} (for building man pages only)\n\nBuilding:\n\n[source,text]\n----\n# first clone the repo\n$ git clone git@github.com:cactus/go-camo\n$ cd go-camo\n\n# show make targets\n$ make\nAvailable targets:\n  help                this help\n  clean               clean up\n  all                 build binaries and man pages\n  check               run checks and validators\n  test                run tests\n  cover               run tests with cover output\n  build               build all binaries\n  man                 build all man pages\n  tar                 build release tarball\n  cross-tar           cross compile and build release tarballs\n\n# build all binaries (into ./bin/) and man pages (into ./man/)\n# strips debug symbols by default\n$ make all\n\n# do not strip debug symbols\n$ make all GOBUILD_LDFLAGS=\"\"\n----\n\n== Running\n\n[source,text]\n----\n$ go-camo -k \"somekey\"\n# run the gc less frequently (a bit better performance, uses more memory)\n$ env GOGC=300 go-camo -k \"somekey\"\n----\n\nGo-Camo does not daemonize on its own.\nFor production usage,\nit is recommended to launch in a process supervisor,\nand drop privileges as appropriate.\n\nExamples of supervisors include:\n{link-damontools}, {link-runit}, {link-upstart},\n{link-launchd}, {link-systemd},\nand many more.\n\nFor the reasoning behind lack of daemonization, see {link-daemontools-why}.\nIn addition, the code is much simpler because of it.\n\n== Running on Heroku\n\nIn order to use this on Heroku with the provided Procfile, you need to:\n\n*   Create an app specifying the {link-heroku-buildpack-go} buildpack\n*   Set `GOCAMO_HMAC` to the key you are using\n\n== Securing an installation\n\ngo-camo will generally do what you tell it to with regard to fetching signed urls.\nThere is some limited support for trying to prevent {link-dns-rebinding} attacks.\n\ngo-camo will attempt to reject any address matching an rfc1918 network block,\nor a private scope ipv6 address, be it in the url or via resulting hostname\nresolution.\n\nPlease note, however, that this does not provide protection for a network that\nuses public address space (ipv4 or ipv6), or some of the\n{link-ip6-special-addresses}[more exotic] ipv6 addresses.\n\nThe list of networks rejected includes...\n\n[%header%autowidth.stretch]\n|===\n| Network | Description\n\n| `127.0.0.0/8`\n| loopback\n\n| `169.254.0.0/16`\n| ipv4 link local\n\n| `10.0.0.0/8`\n| rfc1918\n\n| `172.16.0.0/12`\n| rfc1918\n\n| `192.168.0.0/16`\n| rfc1918\n\n| `::1/128`\n| ipv6 loopback\n\n| `fe80::/10`\n| ipv6 link local\n\n| `fec0::/10`\n| deprecated ipv6 site-local\n\n| `fc00::/7`\n| ipv6 ULA\n\n| `::ffff:0:0/96`\n| IPv4-mapped IPv6 address\n|===\n\nMore generally, it is recommended to either:\n\n*   Run go-camo on an isolated instance (physical, vlans, firewall rules, etc).\n*   Run a local resolver for go-camo that returns NXDOMAIN responses\n    for addresses in deny-listed ranges (e.g. unbound's `private-address` functionality).\n    This is also useful to help prevent dns rebinding in general.\n*   Use something like {link-smokescreen} as an upstream proxy to filter outgoing\n    requests (note caveats in \u003c\u003cUpstream Http Proxying\u003e\u003e).\n\n== Configuring\n\n=== Environment Vars\n\n*   `GOCAMO_HMAC` - HMAC key to use.\n*   `HTTPS_PROXY` - Configure an outbound proxy for HTTPS requests. +\n    Either a complete URL or a `host[:port]`, in which case an HTTP scheme\n    is assumed. See \u003c\u003cUpstream Http Proxying\u003e\u003e notes for more information.\n*   `HTTP_PROXY` - Configure an outbound proxy for HTTP requests. +\n    Either a complete URL or a `host[:port]`, in which case an HTTP scheme\n    is assumed. See \u003c\u003cUpstream Http Proxying\u003e\u003e notes for more information.\n\n=== Command line flags\n\n[source,text]\n----\n$ go-camo -h\nUsage: go-camo [flags]\n\nAn image proxy that proxies non-secure images over SSL/TLS\n\nFlags:\n  -h, --help                     Show context-sensitive help.\n  -k, --key=STRING               HMAC key\n  -H, --header=HEADER,...        Add additional header to each response.\n                                 This option can be used multiple times to add\n                                 multiple headers.\n      --listen=\"0.0.0.0:8080\"    Address:Port to bind to for HTTP\n      --ssl-listen=HOST_PORT     Address:Port to bind to for HTTPS/SSL/TLS\n      --socket-listen=PATH       Path for unix domain socket to bind to for HTTP\n      --quic                     Enable http3/quic. Binds to the same port\n                                 number as ssl-listen but udp+quic.\n      --automaxprocs             Set GOMAXPROCS automatically to match Linux\n                                 container CPU quota/limits.\n      --ssl-key=PATH             ssl private key (key.pem) path\n      --ssl-cert=PATH            ssl cert (cert.pem) path\n      --max-size=INT             Max allowed response size (KB)\n      --timeout=4s               Upstream request timeout\n      --max-redirects=3          Maximum number of redirects to follow\n      --max-size-redirect=URL    redirect to URL when max-size is exceeded\n      --metrics                  Enable Prometheus compatible metrics endpoint\n      --no-debug-vars            Disable the /debug/vars/ metrics endpoint.\n                                 This option has no effects when the metrics are\n                                 not enabled.\n      --no-log-ts                Do not add a timestamp to logging\n      --prof                     Enable go http profiler endpoint\n      --log-json                 Log in JSON format\n      --no-fk                    Disable frontend http keep-alive support\n      --no-bk                    Disable backend http keep-alive support\n      --allow-content-video      Additionally allow 'video/*' content\n      --allow-content-audio      Additionally allow 'audio/*' content\n      --allow-credential-urls    Allow urls to contain user/pass credentials\n      --filter-ruleset=PATH      Text file containing filtering rules (one per\n                                 line)\n      --server-name=\"go-camo\"    Value to use for the HTTP server field\n      --user-agent=\"go-camo\"     user-agent for outgoing requests\n      --expose-server-version    Include the server version in the HTTP server\n                                 response header\n      --enable-xfwd4             Enable x-forwarded-for passthrough/generation\n  -v, --verbose                  Show verbose (debug) log level output\n  -V, --version                  Print version and exit; specify twice to show\n                                 license information.\n----\n\nA few notes about specific flags:\n\n* `--filter-ruleset`\n+\n--\nIf a `filter-ruleset` file is defined,\nthat file is read and each line is converted into a filter rule.\nSee link:man/go-camo-filtering.5.scd[`go-camo-filtering(5)`]\nfor more information regarding the format for the filter file itself.\n\nRegarding evaluation: The ruleset is NOT evaluated in-order.\nThe rules process in two phases: \"allow rule phase\" where the allow rules are evaluated,\nand the \"deny rule phase\" where the deny rules are evaluated.\nFirst match in each phase \"wins\" that phase.\n\nIn the \"allow phase\", an origin request must match at least one allow rule.\nThe first rule to match \"wins\" and the request moves on to the next phase.\nIf there are no allow rules supplied, this phase is skipped.\n\nIn the deny rule phase, any rule that matches results in a rejection.\nThe first match \"wins\" and the request is failed.\nIf there are no deny rules supplied, this phase is skipped.\n\n[NOTE]\n====\nIt is always preferable to do filtering at the point of URL generation and signing.\nThe `filter-ruleset` functionality (both allow and deny) is supplied\npredominantly as a fallback safety measure,\nfor cases where you have previously generated a URL and you need a quick temporary fix,\nor where rolling keys takes a while and/or is difficult.\n====\n--\n\n* `--max-size`\n+\n--\nThe `--max-size` value is defined in KB.\nSet to `0` to disable size restriction.\nThe default is `0`.\n--\n\n* `--metrics`\n+\n--\nIf the `metrics` flag is provided, then the service will expose a Prometheus\n`/metrics` endpoint and a `/debug/vars` endpoint from the go `expvar` package.\n--\n\n* `--no-debug-vars`\n+\n--\nIf the `no-debug-vars` flag is provided along with the `metrics` flag, the\n`/debug/vars` endpoint is removed.\n--\n\n* `-k`, `--key`\n+\n--\nIf the HMAC key is provided on the command line,\nit will override (if present),\nan HMAC key set in the environment var.\n--\n\n* `-H, --header`\n+\n--\nAdditional default headers (sent on every response) can also be set.\nThis argument may be specified many times.\n\nThe list of default headers sent are:\n\n[source,text]\n----\nX-Content-Type-Options: nosniff\nX-XSS-Protection: 1; mode=block\nContent-Security-Policy: default-src 'none'; img-src data:; style-src 'unsafe-inline'\n----\n\nAs an example, if you wanted to return a `Strict-Transport-Security` header\nby default, you could add this to the command line:\n\n[source,text]\n----\n-H \"Strict-Transport-Security: max-age=16070400\"\n----\n--\n\n* `--allow-content-video` and `--allow-content-audio`\n+\n--\nBy default only `image/*` content-types are accepted and proxied, all other\ncontent-types are rejected.\n\nAdd the `--allow-content-video` argument to addtionally allow `video/*` content\ntypes.\n\nAdd the `--allow-content-audio` argument to addtionally allow `audio/*` content\ntypes.\n--\n\n== Upstream Http Proxying\n\nCare should be taken when using upstream http proxy support. go-camo has\nseveral protections against SSRF vectors, for example:\n\n*   Checking http redirect chains against rfc1918 addresses.\n*   Limits to maximum number of redirects.\n*   Protection against self-redirect loops.\n*   Various other protections.\n\nThe use of an upstream http proxy may subvert several of these protections, as\ngo-camo will be required to offload certain operations to the upstream http proxy.\n\nSome examples (list is not exhaustive):\n\n*   The upstream http proxy itself may be responsible for following redirects\n    (depending on configuration). As such, go-camo may not have visibility into\n    the redirect chain. This could result in resource exhaustion (redirect\n    loops), or SSRF (redirects to internal URLs).\n*   The upstream http proxy itself will be responsible for connecting to external\n    servers, and would need to be configured for any request size limits.\n    While go-camo would still limit request sizes based on its own configuration,\n    the upstream http proxy may still fetch the content before handoff.\n*   There may be other chances for \"configuration confusion\" -- where two\n    services are configured together in such a way, that introduces\n    issues not possible when operating standalone.\n\nProper configuration of the upstream http proxy may mitigate these issues. +\nTest your configurations and monitor carefully!\n\n== Monitoring\n\n=== Metrics\n\nWhen the `--metrics` flag is used,\nthe service will expose a Prometheus-compatible `/metrics` endpoint.\nThis can be used by monitoring systems to gather data.\n\nThe endpoint includes all of the default `go_` and `process_`.\nIn addition, a number of custom metrics.\n\n[%header%autowidth.stretch]\n|===\n| Name | Type | Help\n\n| camo_response_duration_seconds | Histogram\n| A histogram of latencies for proxy responses.\n\n| camo_response_size_bytes | Histogram\n| A histogram of sizes for proxy responses.\n\n| camo_proxy_content_length_exceeded_total | Counter\n| The number of requests where the content length was exceeded.\n\n| camo_proxy_reponses_failed_total | Counter\n| The number of responses that failed to send to the client.\n\n| camo_proxy_reponses_truncated_total | Counter\n| The number of responses that were too large to send.\n\n| camo_responses_total | Counter\n| Total HTTP requests processed by the go-camo, excluding scrapes.\n|===\n\nIt also includes a `camo_build_info` metric that exposes the version.\nIn addition, you can expose some extra data to metrics via env vars, if desired:\n\n*   Revision via `APP_INFO_REVISION`\n*   Branch via `APP_INFO_BRANCH`\n*   BuildDate via `APP_INFO_BUILD_DATE`\n*   You can also override the version by setting `APP_INFO_VERSION`\n\nA `/debug/vars` endpoint is also included with `--metrics` by default.\nThis endpoint returns memstats and some additional data. This endpoint can be\ndisabled by additionally supplying the `--no-debug-vars` flag.\n\n== Additional tools\n\nGo-Camo includes a couple of additional tools.\n\n=== url-tool\n\nThe `url-tool` utility provides a simple way to generate signed URLs\nfrom the command line.\n\n[source,text]\n----\n$ url-tool -h\nUsage:\n  url-tool [OPTIONS] \u003cdecode | encode\u003e\n\nApplication Options:\n  -k, --key=    HMAC key\n  -p, --prefix= Optional URL prefix used by encode output\n\nHelp Options:\n  -h, --help    Show this help message\n\nAvailable commands:\n  decode  Decode a URL and print result\n  encode  Encode a URL and print result\n----\n\nExample usage:\n\n[source,text]\n----\n# hex\n$ url-tool -k \"test\" encode -p \"https://img.example.org\" \"http://golang.org/doc/gopher/frontpage.png\"\nhttps://img.example.org/0f6def1cb147b0e84f39cbddc5ea10c80253a6f3/687474703a2f2f676f6c616e672e6f72672f646f632f676f706865722f66726f6e74706167652e706e67\n\n$ url-tool -k \"test\" decode \"https://img.example.org/0f6def1cb147b0e84f39cbddc5ea10c80253a6f3/687474703a2f2f676f6c616e672e6f72672f646f632f676f706865722f66726f6e74706167652e706e67\"\nhttp://golang.org/doc/gopher/frontpage.png\n\n# base64\n$ url-tool -k \"test\" encode -b base64 -p \"https://img.example.org\" \"http://golang.org/doc/gopher/frontpage.png\"\nhttps://img.example.org/D23vHLFHsOhPOcvdxeoQyAJTpvM/aHR0cDovL2dvbGFuZy5vcmcvZG9jL2dvcGhlci9mcm9udHBhZ2UucG5n\n\n$ url-tool -k \"test\" decode \"https://img.example.org/D23vHLFHsOhPOcvdxeoQyAJTpvM/aHR0cDovL2dvbGFuZy5vcmcvZG9jL2dvcGhlci9mcm9udHBhZ2UucG5n\"\nhttp://golang.org/doc/gopher/frontpage.png\n----\n\n== Containers\n\nThere are containers built automatically from version tags, pushed to both {link-docker-containers} and {link-github-containers}.\n\nThese containers are untested and provided only for those\nwith specific containerization requirements.\nWhen in doubt, prefer the statically compiled {link-releases},\nunless you specifically need a container.\n\n== Changelog\n\nSee xref:CHANGELOG.md[CHANGELOG].\n\n== License\n\nReleased under the {link-mit-license}.\nSee xref:LICENSE.md[LICENSE] file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcactus%2Fgo-camo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcactus%2Fgo-camo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcactus%2Fgo-camo/lists"}