Secrets revert to old values on deploy

Hi everyone,

I recently migrated an application from Heroku, then later set up Postgres, Redis, etc. Everything works great and I’m loving fly.io!

The only issue I have is that on deploys my secrets keep reverting to the old Heroku values. I even have to keep a local file with the correct changes and reapply them after each deploy. This is obviously not ideal.

Am I missing something when it comes to secrets?

What command are you using to deploy the app on Fly?

Hey there, thanks for reaching out!

I’m using flyctl deploy. For reference, the secrets always seem to go back to the very original values (those match the imported Heroku environment variables).

I’ve tracked this down to the instances being killed due to memory issues. It seems that WEB_CONCURRENCY is being set to "28" for whatever reason.

I’m still having issues with secrets but the reversion to the original Heroku values doesn’t seem to be happening.

Hi there! Can I ask the name of your app? Feel free to reply on a private message if you don’t want to say it publicly.

Can I also ask if you deployed it via our Turboku (Heroku · Launch on Fly.io)? I have a feeling this might be the case because we sync secrets from Heroku so that’s why it would be overriding it.

The app is next-tms. It was deployed via Turboku. I’ve successfully set a few secrets (mainly REDIS_URL, DATABASE_URL) but now I’m attempting to fix the memory errors via WEB_CONCURRENCY as well as an API key.

Oh, for what it’s worth I deleted the Heroku app just a few hours ago too.

So I’ve narrowed this down to an ENV file for development being included as part of the deploy when done locally.

When I try to deploy with the GitHub Action it fails saying:

ERROR: failed to build: toml: line 7: Key 'metadata' has already been defined.
78
Error failed to fetch an image or build from source: executing lifecycle: failed with status code: 52

So back to my local machine:

flyctl deploy --remote-only --no-cache --build-secret ENV_1='something' ENV_2='something'

Error accepts at most 1 arg(s), received 16

So next I try

flyctl deploy --remote-only --no-cache --build-secret 'ENV_1=something ENV_2=something'

which also fails (the variables are probably mangled because I get missing ENV variable errors during building).

At this point I’ve resorted to rails:assets:clobber and copying production secrets into a file that gets pushed into the build environment and into production.

I really, really hate to do that but it seems like the tooling just won’t work.

If you want to exclude a file from your build, you can add its path to .dockerignore.

I’m not sure if you need build secrets, but if you do, you’ll need to specify each one separately like:

flycyl deploy --build-secret A="something" --build-secret B="something"

Note that build secrets are not available as environment variables. Read more about this specific feature here: Build images with BuildKit | Docker Documentation

I’m looking for a way to set environment variables in the builder (especially if it’s possible via GitHub) because rails assets:precompile fails due to some gems expecting ENV variables.

Using your syntax flycyl deploy --build-secret A="something" --build-secret B="something" did not work and results in the error Error accepts at most 1 arg(s), received 16.

I did try --build-arg as well but I doubt that’s used for environment variables.

The only way I can get this to work is include a file with the env variables during deploy.

You can use build-arg as long as the values you need to add are not sensitive secrets. Can you try using these again and report the results?

build-secrets would only work if your app is using a Dockerfile for deployment. It looks like you’re using a buildpack, so build-arg is probably the best option for now.

The downside is that the resulting images will contain those values permanently. But, these images are only visible to those who have a Fly token for your organization.

% fly deploy --no-cache --remote-only --build-arg DATABASE_URL="[REDACTED]" GEONAMES_USERNAME="[REDACTED]" GOOGLE_API_KEY="[REDACTED]" INTUIT_CLIENT_ID="[REDACTED]" INTUIT_CLIENT_SECRET="[REDACTED]" AWS_ACCESS_KEY_ID="[REDACTED]" AWS_BUCKET="[REDACTED]" AWS_ENDPOINT="[REDACTED]" AWS_REGION="[REDACTED]" AWS_SECRET_ACCESS_KEY="[REDACTED]" POSTMARK_API_TOKEN="[REDACTED]" SELENOID_BASE_URL="[REDACTED]" SELENOID_URL="[REDACTED]" SMARTY_STREETS_AUTH_ID="[REDACTED]" SMARTY_STREETS_AUTH_TOKEN="[REDACTED]" XPO_API_KEY="[REDACTED]" RAILS_MASTER_KEY="[REDACTED]" REDIS_URL="[REDACTED]" STRIPE_API_KEY="[REDACTED]" WEB_CONCURRENCY="2" 
Error: accepts at most 1 arg(s), received 19
Usage:
  flyctl deploy [WORKING_DIRECTORY] [flags]

Flags:
  -a, --app string             Application name
      --build-arg strings      Set of build time variables in the form of NAME=VALUE pairs. Can be specified multiple times.
      --build-only             Build but do not deploy
      --build-secret strings   Set of build secrets of NAME=VALUE pairs. Can be specified multiple times. See https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information
      --build-target string    Set the target build stage to build if the Dockerfile has more than one stage
  -c, --config string          Path to application configuration file
      --detach                 Return immediately instead of monitoring deployment progress
      --dockerfile string      Path to a Dockerfile. Defaults to the Dockerfile in the working directory.
  -e, --env strings            Set of environment variables in the form of NAME=VALUE pairs. Can be specified multiple times.
  -h, --help                   help for deploy
  -i, --image string           The image tag or ID to deploy
      --image-label string     Image label to use when tagging and pushing to the fly registry. Defaults to "deployment-{timestamp}".
      --local-only             Only perform builds locally using the local docker daemon
      --no-cache               Do not use the build cache when building the image
      --now                    Deploy now without confirmation
      --push                   Push image to registry after build is complete
  -r, --region string          The region to operate on
      --remote-only            Perform builds on a remote builder instance instead of using the local docker daemon
      --strategy string        The strategy for replacing running instances. Options are canary, rolling, bluegreen, or immediate. Default is canary, or rolling when max-per-region is set.

Global Flags:
  -t, --access-token string   Fly API Access Token
  -j, --json                  json output
      --verbose               verbose output

Error accepts at most 1 arg(s), received 19

You’ll need to specify each build arg separately like:

fly deploy --build-arg ENV2=1 --build-arg ENV2=2