If you edit files present in a Heroku dyno, the edited file comes back to its initial state after some time. This is because Heroku restarts the dynos randomly for keeping them in good health.
Heroku Deployment Process:
skip this if you are familiar
- Initiating deployment:
- Heroku deployment can be triggered manually or it can be configured to get triggered automatically by connecting Heroku to GitHub.
- During deployment:
- Heroku builds the application based on default settings or based on the configured build packs.
- At the end of this process, a slug will be created. A slug is nothing but the files that were generated during the build. A slug is similar to a docker image (not exactly).
- The created slug is deployed in AWS EC2 instances, which is called as dynos by Heroku.
- At random intervals, the slug is redeployed for maintaining the health of the dynos #ref
👆This is the reason why files edited in a dyno will be reset to its initial state.
👻
So, How can we make changes to the files in a Heroku dyno which does not reset to its previous version?
One straightforward solution is to make the changes in the source code and redeploy the application.
Yes, this is one way of achieving it.
But, You may wonder why there would be another scenario. One rare scenario is: You want to change a HTML file (urgent client requirement) that is already part of an application in the production environment, but your build process is getting timed out and you are not able to find the reason.
So, The other solution is:
By editing the previously generated slug and using the edited slug in the required application/environment.
Steps to edit the slug and deploy it:
(100% no build process is required)
- Download Heroku CLI
- Login to your Heroku account using the CLI
$ heroku login
- This will take you to a browser to fill the login form.
- List all the deployed applications
$ heroku list --all
- Get the unique slug identifier and version number
$ heroku slugs -a your_application_name
- Use the name of the application which has the files you want to edit.
- You will get all the unique slug identifiers along with their version numbers that are generated and used by your application until now.
- This version number can be verified from the dashboard https://dashboard.heroku.com/apps/your_application_name/activity
- If you have too many deployments, store the list to a file
$ heroku slugs -a your_application_name > slugsList.txt
- Download the slug
- To download, you need an additional Heroku CLI plugin
- Install the additional plugin using
heroku plugins:install heroku-slugs
- Then
$ heroku slugs:download your_unique_slug_identifier -a your_application_name
- This will download and create a folder with the name of your application.
- The created folder will contain a directory called
app
which contains the generated source code and aslug.tar.gz
file, which is the compressed version the source code.
- Edit the required files present within the
./app
directory. - Create new slug archive
- Heroku currently has limited tar-file compatibility. Please use GNU Tar (and not
bsdtar
) when creating slug archives. You can check your tar version withtar --version
. - While running the below command, you should be in the same directory level as that of
./app
directory. $ tar czfv slug.tgz ./app
-
slug.tgz
is the name of the archive that will be created -
c
- create,z
- gzip format,v
- show status,f
- file name and location
- Heroku currently has limited tar-file compatibility. Please use GNU Tar (and not
- Create a unique identifier for the new slug
-
$ curl -X POST \ -H 'Content-Type: application/json' \ -H 'Accept: application/vnd.heroku+json; version=3' \ -d '{"process_types":{"your_process_type":"your_command"}}' \ -n https://api.heroku.com/apps/your_application_name/slugs
- If you don't know your process type(s) and the respective commands, then go to https://dashboard.heroku.com/apps/your_application_name/resources
- For my application, I have two process types. So I will be sending this data in the API call
{"process_types":{"web": "bundle exec puma -p $PORT -C ./config/puma.rb", "worker": "bundle exec rake jobs:work"}}
-
-n
flag tells curl to read the credentials forapi.heroku.com
from~/.netrc
and automatically sets theAuthorization
header. -
-H
flag sets the respective header -
-d
flag represents the data to be sent in HTTP POST request - You will get a response like this
-
{ "blob":{ "method": "put", "url": "https://s3-external-1.amazonaws.com/herokuslugs/heroku.com/v1/d969e0b3-9892-4567-7642-1aa1d1108bc3?AWSAccessKeyId=AKIAJWLOWWHPBWQOPJZQ&Signature=2oJJEtemTp7h0qTH2Q4B2nIUY9w%3D&Expires=1381273352" }, "commit":null, "created_at":"2013-10-08T22:04:13Z", "id":"d969e0b3-9892-3113-7653-1aa1d1108bc3", "process_types":{ "web":"node-v0.10.20-linux-x64/bin/node web.js" }, "updated_at":"2013-10-08T22:04:13Z" }
-
-
blob.url
- AWS S3 URL for the new slug -
id
- Unique identifier for the new slug - Heroku docs reference
-
- Upload the created slug archive to AWS S3
-
$ curl -X PUT \ -H "Content-Type:" \ --data-binary @slug.tgz \ "https://your_aws_s3_blob_url"
-
slug.tgz
is the name of the archive file we have created.
-
- Create a new release for your application which will use the new slug archive which we have created and uploaded to AWS S3
-
$ curl -X POST \ -H "Accept: application/vnd.heroku+json; version=3" \ -H "Content-Type: application/json" \ -d '{"slug":"your_unique_identifier_of_new_slug"}' \ -n https://api.heroku.com/apps/your_application_name/releases
-
You can verify the release status in the Heroku dashboard or using
heroku releases --app your_application_name
Top comments (6)
I have a Heroku app which is connected to a GitHub repo. I want to add a file in Heroku. I can do that by using bash command from Heroku cli.
Does the generated file persist? For example when I made a push to my GitHub repo
To add a file to Heroku app, you can push your file to your connected GitHub account.
You can check these settings here: dashboard.heroku.com/apps/your_app...
When this deployment succeeds, your new file will become persistently available in your App.
but I don't want to push the file to Github. It is a config file, it will be different based on deployment environment
Use the Heroku config vars option for environment-specific values.
devcenter.heroku.com/articles/conf...
I think I can't. I'm reading value inside JS code, it should be a file
Did you find the solution?