{"id":18603605,"url":"https://github.com/cogini/phoenix_container_example_old","last_synced_at":"2025-04-10T19:31:59.790Z","repository":{"id":43322255,"uuid":"274809988","full_name":"cogini/phoenix_container_example_old","owner":"cogini","description":"Full featured example of building a container for an Elixir Phoenix project, taking advantage of BuildKit caching and multi-platform builds (Arm). Shows raw docker, docker-compose, and Earthly; mirrored base images from Docker Hub to AWS ECR; deploys to AWS ECS using CodeBuild / CodeDeploy","archived":false,"fork":false,"pushed_at":"2023-12-29T01:05:26.000Z","size":1599,"stargazers_count":55,"open_issues_count":0,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-25T03:34:29.867Z","etag":null,"topics":["arm64","aws","aws-codebuild","aws-codedeploy","aws-ecs","docker","docker-buildkit","docker-image","dockerfile","ecs","elixir","elixir-lang","elixir-library","elixir-phoenix"],"latest_commit_sha":null,"homepage":"","language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cogini.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}},"created_at":"2020-06-25T02:06:30.000Z","updated_at":"2025-03-18T14:50:52.000Z","dependencies_parsed_at":"2023-10-01T20:59:52.133Z","dependency_job_id":"706391d7-26a4-4563-9879-bb94e25fcc22","html_url":"https://github.com/cogini/phoenix_container_example_old","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cogini%2Fphoenix_container_example_old","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cogini%2Fphoenix_container_example_old/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cogini%2Fphoenix_container_example_old/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cogini%2Fphoenix_container_example_old/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cogini","download_url":"https://codeload.github.com/cogini/phoenix_container_example_old/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248281415,"owners_count":21077423,"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":["arm64","aws","aws-codebuild","aws-codedeploy","aws-ecs","docker","docker-buildkit","docker-image","dockerfile","ecs","elixir","elixir-lang","elixir-library","elixir-phoenix"],"created_at":"2024-11-07T02:14:53.245Z","updated_at":"2025-04-10T19:31:58.606Z","avatar_url":"https://github.com/cogini.png","language":"Dockerfile","readme":"This is a full featured example of building and deploying an Elixir / Phoenix\napp using containers.\n\n* Supports Debian, Ubuntu, and Alpine using [hexpm/elixir](https://hub.docker.com/r/hexpm/elixir)\n  base images. Supports Google [Distroless](https://github.com/GoogleContainerTools/distroless)\n  and Ubuntu [Chisel](https://github.com/canonical/chisel) to build small distribution images.\n\n* Uses Erlang releases for the final image, resulting in an image size of\n  less than 20MB (5.6 MB Alpine OS files, 1.3 MB TLS libraries, 12 MB Erlang VM + app).\n\n* Uses Docker [BuildKit](https://github.com/moby/buildkit)\n  for [multistage builds](https://docs.docker.com/develop/develop-images/multistage-build/)\n  and caching of OS files and language packages. Multistage builds compile\n  dependencies separately from app code, speeding rebuilds and reducing final\n  image size. Caching of packages reduces size of container layers and allows\n  sharing of data betwen container targets.\n\n* Supports a full-featured CI with Github Actions, running static code analysis\n  and security scanners in parallel.\n\n* Supports container-based testing, running tests against the production build\n  using Postman/Newman, with containerized builds of Postgres, MySQL, Redis, etc.\n\n* Supports development in a Docker container with Visual Studio Code.\n\n* Supports mirroring base images from Docker Hub to AWS ECR to avoid rate\n  limits and ensure consistent builds.\n\n* Supports building for multiple architectures, e.g. AWS\n  [Gravaton](https://aws.amazon.com/ec2/graviton/) Arm processor.\n  Arm builds work on Intel with both Mac hardware and Linux (CodeBuild), and\n  should work the other direction on Apple Silicon.\n\n* Supports deploying to AWS ECS using CodeBuild, CodeDeploy Blue/Green\n  deployment, and AWS Parameter Store for configuration. See\n  [ecs/buildspec.yml](ecs/buildspec.yml). Terraform is used to set up the\n  environment, see https://github.com/cogini/multi-env-deploy/\n\n* Supports compiling assets such as JS/CSS within the container, then\n  exporting them to the Docker host so that they can be uploaded to a CDN.\n\n* Supports building with `docker buildx bake`, a docker-native build tool\n  similar to docker-compose which uses the more powerful HCL syntax\n  and supports native caching functionality.\n\n* Supports building with [Earthly](https://earthly.dev/), an improved Dockerfile\n  with better syntax, caching, and testing workflows.\n\n## Usage\n\n[docker-compose](https://docs.docker.com/compose/) lets you define multiple\nservices in a YAML file, then build and start them together. It's particularly\nuseful for development or running tests in a CI/CD environment which depend on\na database.\n\n  ```shell\n  # Registry for mirrored source images, default is Docker Hub if not set\n  export REGISTRY=123456789.dkr.ecr.us-east-1.amazonaws.com/\n\n  # Destination repository for app final image\n  export REPO_URL=${REGISTRY}foo/app\n\n  # Login to registry, needed to push to repo or use mirrored base images\n  # Docker Hub\n  # docker login --username cogini --password \u003caccess-token\u003e\n  # AWS ECR\n  aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $REGISTRY\n\n  # Build all images (dev, test and app prod, local Postgres db)\n  docker compose build\n\n  # Run tests, talking to db in container\n  docker compose up test\n  docker compose run test mix test\n\n  # Push final app image to repo REPO_URL\n  docker compose push app\n  ```\n\nYou can also run the docker build commands directly, which give more control\nover caching and cross builds. `build.sh` is a wrapper on `docker buildx build`\nwhich sets various options.\n\n  ```shell\n  DOCKERFILE=deploy/debian.Dockerfile ecs/build.sh\n  ```\n\nTo run the prod app locally, talking to the db container:\n\n  ```shell\n  # Create prod db schema via test stage\n  DATABASE_DB=app docker compose run test mix ecto.create\n\n  export SECRET_KEY_BASE=\"JBGplDAEnheX84quhVw2xvqWMFGDdn0v4Ye/GR649KH2+8ezr0fAeQ3kNbtbrY4U\"\n  DATABASE_DB=app docker compose up app\n\n  # Make request to app running in Docker\n  curl -v http://localhost:4000/\n  ```\n\nTo develop the app in a container:\n\n  ```shell\n  # Start dev instance\n  docker compose up dev\n\n  # Create dev db schema by running mix\n  docker compose run dev mix ecto.create\n\n  # Make request to app running in Docker\n  curl -v http://localhost:4000/\n\n  # Open a shell on the running dev environment\n  docker compose run dev bash\n  ```\n\n## Building for multiple platforms\n\nBuilding in emulation is considerably slower, mainly due to lack of precompiled\npackages for Arm. The key in any case is getting caching optimized.\n\n  ```shell\n  PLATFORM=\"--platform linux/amd64,linux/arm64\" ecs/build.sh\n  docker buildx imagetools inspect $REPO_URL\n  ```\n\nIt can also be configured in `docker compose.yml`.\n\n## Environment vars\n\nThe new BuildKit features are enabled with environment vars:\n\n`DOCKER_BUILDKIT=1` enables the new\n[experimental](https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md)\nDockerfile caching syntax with the standard `docker build` command. It requires Docker version 18.09.\n\n`DOCKER_CLI_EXPERIMENTAL=enabled` enables the new Docker\n[buildx](https://github.com/docker/buildx) CLI command (and the new file\nsyntax). It is built in with Docker version 19.03, but can be installed\nmanually before that.\n\n`COMPOSE_DOCKER_CLI_BUILD=1` tells [docker-compose](https://docs.docker.com/compose/) to use `buildx`.\n\nThe prod deploy container uses the following env vars:\n\n* `DATABASE_URL` defines the db connection, e.g. `DATABASE_URL=ecto://user:pass@host/database`\nYou can configure the number of db connections in the pool, e.g. `POOL_SIZE=10`.\n\n* `SECRET_KEY_BASE` protects Phoenix cookies from tampering.\nGenerate it with the command `mix phx.gen.secret`.\n\n* `PORT` defines the port that Phoenix will listen on, default is 4000.\n\n## Mirroring source images\n\nYou can make a mirror of the base images that your build depends on to your own\nregistry. This is particularly useful since Docker started rate limiting\nrequests to public images.\n\nSee https://earthly.dev/blog/how-to-setup-and-use-amazons-elastic-container-registry/\n\nTo use the mirror registry, set the `REGISTRY` env variable:\n\n```shell\nexport REGISTRY=1234567890.dkr.ecr.ap-northeast-1.amazonaws.com/\ndocker compose build\n```\n\n## skopeo\n\n```yaml\ndocker.io:\n  images:\n    earthly/buildkitd:\n      - 'v0.6.2'\n\n    earthly/dind:\n      - 'alpine'\n\n    ubuntu:\n      # CodeBuild base image\n      - 'focal'\n\n    # Target base image, choose one\n    alpine:\n      - '3.12.1'\n      - '3.13.2'\n      - '3.15.0'\n\n    debian:\n      - 'buster-slim'\n\n    postgres:\n      - '12'\n      - '14'\n      - '14.1-alpine'\n\n    mysql:\n      - '8'\n\n    # Build base images\n    hexpm/elixir:\n      # Choose one\n      # - '1.11.2-erlang-23.1.2-alpine-3.12.1'\n      # - '1.11.2-erlang-23.1.2-debian-buster-20201012'\n      - '1.11.2-erlang-23.2.1-alpine-3.12.1'\n      - '1.11.2-erlang-23.2.1-debian-buster-20201012'\n      - '1.11.2-erlang-23.2.4-alpine-3.13.1'\n      - '1.11.2-erlang-23.2.4-debian-buster-20201012'\n      - '1.11.3-erlang-23.2.6-alpine-3.13.2'\n      - '1.11.3-erlang-23.2.6-debian-buster-20210208'\n      - '1.13.1-erlang-24.2-alpine-3.15.0'\n\n    node:\n      - '14.4-stretch'\n      - '14.15.1-stretch'\n      - '14.4-buster'\n      - '14.15.1-buster'\n\n  mcr.microsoft.com:\n    mssql/server:\n      - '2019-latest'\n```\n\n```shell\naws ecr create-repository --repository-name centos\naws ecr get-login-password | skopeo login -u AWS --password-stdin $REGISTRY_NOSLASH\nskopeo sync --all --src yaml --dest docker skopeo-sync.yml $REGISTRY\n```\n\nhttps://polyverse.com/blog/skopeo-the-best-container-tool-you-need-to-know-about/\nhttps://github.com/onfido/ecr-mirror\nhttps://alexwlchan.net/2020/11/copying-images-from-docker-hub-to-amazon-ecr/\n\nhttps://shazi.info/docker-build-x86-arm-multi-arch-images-with-aws-ecr/\n\n[Dregsy](https://github.com/xelalexv/dregsy) is a utility which mirrors\nrepositories from one registry to another.\n\nNOTE: dregsy does not currently support multi-arch images\nhttps://github.com/xelalexv/dregsy/issues/43\n\n`dregsy.yml`\n\n```yaml\nrelay: skopeo\n\n# relay config sections\nskopeo:\n  # path to the skopeo binary; defaults to 'skopeo', in which case it needs to\n  # be in PATH\n  binary: skopeo\n\n# list of sync tasks\ntasks:\n  - name: docker\n\n    # interval in seconds at which the task should be run; when omitted,\n    # the task is only run once at start-up\n    # interval: 60\n\n    # determines whether for this task, more verbose output should be\n    # produced; defaults to false when omitted\n    verbose: true\n\n    source:\n      registry: docker.io\n      # Authenticate with Docker Hub to get higher rate limits\n      # echo '{\"username\":\"cogini\",\"password\":\"sekrit\"}' | base64\n      # auth: xxx\n    target:\n      registry: 1234567890.dkr.ecr.ap-northeast-1.amazonaws.com\n      auth-refresh: 10h\n\n    # 'mappings' is a list of 'from':'to' pairs that define mappings of image\n    # paths in the source registry to paths in the destination; 'from' is\n    # required, while 'to' can be dropped if the path should remain the same as\n    # 'from'. Additionally, the tags being synced for a mapping can be limited\n    # by providing a 'tags' list. When omitted, all image tags are synced.\n    # mappings:\n    #   - from: test/image\n    #     to: archive/test/image\n    #     tags: ['0.1.0', '0.1.1']\n    mappings:\n      # - from: moby/buildkit\n      #   tags: ['latest']\n\n      # CodeBuild base image\n      - from: ubuntu\n        tags: ['bionic', 'focal']\n\n      # Target base image, choose one\n      - from: alpine\n        tags:\n          - '3.12.1'\n          - '3.13.2'\n          - '3.15.0'\n\n      - from: debian\n        tags: ['buster-slim']\n\n      - from: postgres\n        tags:\n          - '12'\n          - '14.1-alpine'\n\n      # Build base images\n      # - from: hexpm/erlang\n      - from: hexpm/elixir\n        tags:\n          # Choose one\n          - '1.11.3-erlang-23.2.6-alpine-3.13.2'\n          - '1.11.3-erlang-23.2.6-debian-buster-20210208'\n          - '1.13.1-erlang-24.2-alpine-3.15.0'\n      - from: node\n        tags:\n          - '14.4-buster'\n          - '14.15.1-buster'\n\n  - name: microsoft\n    verbose: true\n\n    source:\n      registry: mcr.microsoft.com\n\n    target:\n      registry: 770916339360.dkr.ecr.ap-northeast-1.amazonaws.com\n      auth-refresh: 10h\n\n    mappings:\n      - from: mssql/server\n        tags: ['2019-latest']\n```\n\nRun `dregsy` to sync docker images, using AWS credentials from your\n`~/.aws/config` file specified by `AWS_PROFILE` environment var:\n```shell\ndocker run --rm -v $(pwd)/dregsy.yml:/config.yaml -v $HOME/.aws:/root/.aws -e AWS_PROFILE xelalex/dregsy\n```\nor get AWS credentials from `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` env vars:\n```shell\ndocker run --rm -v $(pwd)/dregsy.yml:/config.yaml -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY xelalex/dregsy\n```\n\n# Developing in a Docker container\n\nVisual Studio Code has support for developing in a Docker container.\n\n* https://code.visualstudio.com/docs/remote/containers-tutorial\n* https://code.visualstudio.com/docs/remote/remote-overview\n* https://code.visualstudio.com/docs/remote/containers\n* https://code.visualstudio.com/docs/remote/devcontainerjson-reference\n* https://code.visualstudio.com/docs/containers/docker-compose\n* https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack\n\nSee [.devcontainer/devcontainer.json](.devcontainer/devcontainer.json).\n\nIt uses the `docker compose.yml` plus an `.env` file to set environment\nvariables.\n\nThe default `.env` file is picked up from the root of the project, but you can\nuse `env_file` in `docker compose.yml` file to specify an alternate location.\n\n`.env`\n\n  ```shell\n  IMAGE_NAME=\"foo-app\"\n  IMAGE_OWNER=\"cogini\"\n  IMAGE_TAG=latest\n\n  SECRET_KEY_BASE=\"JBGplDAEnheX84quhVw2xvqWMFGDdn0v4Ye/GR649KH2+8ezr0fAeQ3kNbtbrY4U\"\n  DATABASE_URL=ecto://postgres:postgres@db/app\n  ```\n\nAfter the container starts, in the VS Code shell, start the app:\n\n  ```shell\n  mix phx.server\n  ```\n\nOn your host machine, connect to the app running in the container:\n\n  ```shell\n  open http://localhost:4000/\n  ```\n\n## Caching\n\nBuildKit supports caching intermediate build files such as OS or programming\nlanguage packages outside of the Docker images.\n\nThis is done by specifying a cache when running comands in a `Dockerfile`, e.g.:\n\n```Dockerfile\nRUN --mount=type=cache,id=apt-cache,target=/var/cache/apt,sharing=locked \\\n    --mount=type=cache,id=apt-lib,target=/var/lib/apt,sharing=locked \\\n    --mount=type=cache,id=debconf,target=/var/cache/debconf,sharing=locked \\\n    set -exu \\\n    \u0026\u0026 apt-get update -qq \\\n    \u0026\u0026 apt-get install -y -qq -o=Dpkg::Use-Pty=0 --no-install-recommends \\\n        openssl\n```\n\nThis keeps the OS packages separate from the image layers, only the results of\nthe install are in the image. It can significantly speed up builds, as it's not\nnecessary to download packages. The cache can also be shared between stages/targets.\n\nThe cache can be stored locally, or potentially stored in the registry as extra\ndata layers. `docker buildkit build` then uses `--cache-from` and `--cache-to`\noptions to control the location of the cache. See `build.sh` for details.\n\n  ```shell\n  CACHE_REPO_URL=$REPO_URL CACHE_TYPE=registry DOCKERFILE=deploy/alpine.Dockerfile ecs/build.sh\n  ```\n\nIt currently works quite well for local cache. At some point, registry caching\nmay be a fast way to share build cache inside of CI/CD environments. This is\npretty bleeding edge right now, though. It works with Docker Hub, but there are\nincompatibilities e.g. between docker and AWS ECR.\nSee https://github.com/aws/containers-roadmap/issues/876 and https://github.com/aws/containers-roadmap/issues/505\nThe registry needs to have a fast/close network connection, or it can be quite slow.\n\n## Chisel\n\nChisel is a tool to create distroless images by copying the necessary parts of\nDebian packages into a `scratch` image. It's still early days for Chisel, but I\nlike the approach a lot. It automates the janky part of manually adding\nlibraries to a Google Distroless image.\n\nSee https://ubuntu.com/blog/craft-custom-chiselled-ubuntu-distroless\n\nThey don't yet have formal releases, so you need to build the `chisel` tool\nfrom source.\n\n* Check out the [Chisel source](https://github.com/canonical/chisel) locally\n* Copy `deploy/chisel.Dockerfile` to the chisel source dir\n* Build an image and push it to your repo\n\nThis builds for Arm and Intel architectures:\n\n```command\ndocker buildx create --name mybuilder --use\ndocker buildx build --builder mybuilder -t cogini/chisel --platform linux/arm64/v8,linux/amd64 --push .\n```\n\nSpecs for the slices are stored in `deploy/chisel/release`. They come from\n[the upstream repo](https://github.com/canonical/chisel-releases/tree/ubuntu-22.04/slices),\nwith the addition of some missing things.\n\n## AWS CodeBuild\n\nWe use a custom build image for CodeDeploy with tools installed, speeding up the build.\n\nIt includes:\n\n* Latest Docker\n* `docker-compose`\n* AWS CLI v2.0\n* `amazon-ecr-credential-helper`\n\n```shell\naws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $REGISTRY\n\ndocker compose build codebuild\ndocker compose push codebuild\n```\n\nSame thing, built with Earthly:\n\n```shell\naws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $REGISTRY\nearthly -V --build-arg REGISTRY --strict --push ./deploy/codebuild+deploy\n```\n\n```shell\naws ssm put-parameter --name /cogini/foo/dev/creds/dockerhub_username --value \"$DOCKERHUB_USERNAME\" --type String --region $AWS_REGION\naws ssm put-parameter --name /cogini/foo/dev/creds/dockerhub_token --value \"$DOCKERHUB_TOKEN\" --type SecureString --region $AWS_REGION\n```\n\nhttps://github.com/cogini/aws-otel-collector/blob/main/docs/developers/build-docker.md\n\n## AWS CodeDeploy\n\nAfter building a new contaner and pushing it to ECR, it's necessary to update\nthe ECS task with the new image version. CodeBuild has support to do this by\ngenerating JSON output files.\n\n[ecs/buildspec.yml](ecs/buildspec.yml):\n\n  ```shell\n  # Generate imagedefinitions.json file for standard ECS deploy action\n  - printf '[{\"name\":\"%s\",\"imageUri\":\"%s\"}]' \"$CONTAINER_NAME\" \"$REPO_URL:$IMAGE_TAG\" | tee imagedefinitions.json\n  # Generate imageDetail.json file for CodeDeploy ECS blue/green deploy action\n  - printf '{\"ImageURI\":\"%s\"}' \"$REPO_URL:$IMAGE_TAG\" | tee imageDetail.json\n  ```\n\nSee https://docs.aws.amazon.com/codepipeline/latest/userguide/file-reference.html\n\n## Earthly\n\nTo build with Earthy, run:\n\n```shell\nearthly -V -P +all\n```\n\n## Links\n\n* https://docs.aws.amazon.com/codepipeline/latest/userguide/tutorials-ecs-ecr-codedeploy.html\n* https://www.giantswarm.io/blog/container-image-building-with-buildkit\n* https://docs.docker.com/engine/reference/commandline/build/\n* https://github.com/phoenixframework/phoenix/blob/master/Earthfile\n\n## Step by step\n\nCreate initial project:\n\n    mix archive.install hex phx_new\n    mix phx.new phoenix_container_example\n\nGenerate templates to customize release:\n\n    mix release.init\n    * creating rel/vm.args.eex\n    * creating rel/env.sh.eex\n    * creating rel/env.bat.eex\n\n    mix phx.gen.release\n    * creating rel/overlays/bin/server\n    * creating rel/overlays/bin/server.bat\n    * creating rel/overlays/bin/migrate\n    * creating rel/overlays/bin/migrate.bat\n    * creating lib/phoenix_container_example/release.ex\n\nhttps://hexdocs.pm/mix/Mix.Tasks.Release.html\n\nGenerate `assets/package-lock.json`:\n\n    cd assets \u0026\u0026 npm install \u0026\u0026 node node_modules/webpack/bin/webpack.js --mode development\n\nBuild:\n\n    MIX_ENV=prod mix deps.get --only $MIX_ENV\n    MIX_ENV=prod mix compile\n\nUse `releases.exs`:\n\n    cp config/prod.secret.exs config/releases.exs\n\nChange `use Mix.Config` to `import Config`\nUncomment \"server: true\" line\n\nComment out import in in `config/prod.exs`\n\n    import_config \"prod.secret.exs\"\n\nAllow db configuration to be overridden by env vars:\n\n`config/dev.exs` and `config/test.exs':\n\n```elixir\n # Configure your database\n config :phoenix_container_example, PhoenixContainerExample.Repo,\n   username: System.get_env(\"DATABASE_USER\") || \"postgres\",\n   password: System.get_env(\"DATABASE_PASS\") || \"postgres\",\n   database: System.get_env(\"DATABASE_DB\") || \"app\",\n   hostname: System.get_env(\"DATABASE_HOST\") || \"localhost\",\n   show_sensitive_data_on_connection_error: true,\n   pool_size: 10\n ```\n\n```command\ncreateuser --createdb --encrypted --pwprompt postgres\ndocker compose run test mix ecto.setup\n```\n\n```command\nearthly -V -P --build-arg REGISTRY --build-arg REPO_URL --remote-cache=\"cogini/foo-app:cache\" --strict --no-output --push +all\n\ndocker buildx build -t distroless-prod-base -f deploy/distroless/Dockerfile --progress plain --load .\n```\n\nhttps://blog.tedivm.com/guides/2021/10/github-actions-push-to-aws-ecr-without-credentials-oidc/\n\n```command\ndocker compose -f docker-compose.gha.yml --env-file .envrc build scan\ndocker compose -f docker-compose.gha.yml run scan trivy filesystem /\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcogini%2Fphoenix_container_example_old","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcogini%2Fphoenix_container_example_old","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcogini%2Fphoenix_container_example_old/lists"}