How to run InfluxDB on Heroku? - heroku

Is it possible, and if so, how? I'd like to be able to reach it from my existing Heroku infrastructure.
Will I need a Procfile? From what I understand it's just a standalone binary written in Go! so it shouldn't be that hard to deploy it, I'm just curious how to deploy it because I don't think I understand the ins and outs of Heroku deployment.

Heroku Dynos should not be used to deploy a database application like InfluxDB.
Dynos are ephemeral servers. Data does not persist between dyno restarts and cannot be shared with other dynos. Practically speaking, any database application deployed on a dyno is essentially useless. This is why databases on Heroku (e.g. Postgres) are all Add-ons. InfluxDB should be set up on a different platform (like, AWS EC2 or a VPS) since a Heroku Add-on is not available.
That said, it is possible to deploy InfluxDB to a Heroku dyno.
To get started, it is important to understand the concept of a 'slug'. Slugs are containers (similar to a Docker images) which hold everything needed to run a program on Heroku's infrastructure. To deploy InfluxDB, an InfluxDB slug needs to be created.* There are two ways to create a slug for Go libraries:
Create a slug directly from a Go executable as described here.**
Build the slug from source using the Heroku Go buildpack (explained below).
To build the slug from source using a buildpack, first clone the InfluxDB Github repo. Then add a Procfile at the root of the repo, which tells Heroku the command to run when the dyno starts up.
echo 'web: ./influxd' > Procfile
The Go buildpack requires all dependencies be included in the directory. Use the godep dependency tool to vendor all dependencies into the directory.
go get github.com/tools/godep
godep save
Next, commit the changes made above to the git repo.
git add -A .
git commit -m dependencies
Finally, create a new app and tell it to compile with the Go buildpack.
heroku create -b https://github.com/kr/heroku-buildpack-go.git
git push heroku master
heroku open // Open the newly created InfluxDB instance in the browser.
Heroku will show an error page. An error will be displayed because Heroku's 'web' process type requires an app to listen for incoming requests on the port described by the $PORT environment variable, otherwise it will kill the dyno. InfluxDB's API and admin panel run on ports 8086 and 8083, respectively.
Unfortunately, InfluxDB does not allow those ports to be set from environment variables, only through the config file (/etc/config.toml). A small bash script executed before InfluxDB starts up could set the correct port in the config file before InfluxDB starts up.
Another problem, Heroku only exposes one port per dyno so the API and the admin panel cannot be exposed to the internet at the same time. A smart reverse proxy could work around that issue using Heroku's X-Forwarded-Port request header.
Bottom line, do not use Heroku dynos to run InfluxDB.
* This means the benefits of a standalone Go executable are lost when deploying to Heroku, since it needs to be recompiled for Heroku's stack.
** Creating a slug directly from the InfluxDB executable does not work because there is no built-in way to listen to the right port given by Heroku in the $PORT environment variable.

I like to think anything is possible on a Heroku node when using a custom buildpack, but there are some considerations when hosting with Heroku:
ops, e.g. backup, monitoring (does it entail installing extra services, opening extra ports, etc - Heroku might get in the way here)
performance, considering dyno size
and if you need a larger dyno, cost becomes an issue. You'll get more bang for your buck when you go the IaaS route.
other "features" of a dyno, e.g. disk ephemerality
I highly recommend hosted InfluxDB or spinning up your own on a VPS, all of which you can point your existing Heroku-based apps to. It will then help to get those instances as close together as possible (i.e. same region, or co-located if possible), presuming a need for low latency between DB and app stack.

Related

Is it possible to deploy a raw Java web app to Heroku?

Very inexperienced user here...please be patient!
I inherited maintenance of Heroku app from someone no longer with the company. Having to re-deploy an app update is probably a once-a-year event, and here we are.
The instructions I have include building a standalone jar file containing my app and then deploying it to Heroku. Specifically the procedure for this is to use the Heroku CLI with the following command:
heroku deploy:jar webapp.jar -a my-app
Easy enough. Except he had his own instance of the Heroku CLI, and when I went to download my own copy, it appears that the deploy command no longer exists! Is this the case? Is this a deprecated command? Do I need to go through the process of figuring out how to set up a git repository to deploy this? (We are in fact using git to manage the source for this app, but it's behind our company firewall, so I'm not sure how practical/difficult it will be to set this up for Heroku). I just want to make sure I'm not missing something simple before investing a significant amount of time re-inventing the deployment process. Thanks.
The most popular mechanism is indeed to push the code from git to Heroku, providing the necessary files (i.e. profcile) to deploy the runtime.
An alternative is to create a Docker image and push it to the Heroku Registry (which in your case would require more reworking).
Refer to Deploy with Git, the firewall should not be a problem as Heroku will not access your code, but you will need to perform the push (git push heroku master)
I have to answer my own question because I was able to find the solution.
It turns out there is a plugin available for the heroku CLI that provides the deploy command. Running heroku plugins:install java will install the plugin that provides the deploy command in the heroku CLI.
See https://devcenter.heroku.com/articles/deploying-executable-jar-files for more information.

Keep data after Heroku dyno restart

I have a twitter bot hosted at Heroku, and once a day the server reboots. I have a text file that is constantly being modified, and when the server is restarted the changes in that file are lost. Does anyone know how to keep that file updated when the server is restarted?
Yes,you have to pay heroku for dynos : https://devcenter.heroku.com/articles/dynos
Or you can always choose to deploy it somewhere else
Heroku file system is ephemeral and gets wiped out at every restart.
A solution (if you want to keep using Heroku) is to use an external service to persist your data:
Amazon S3, see Heroku article
Github, an easy and free option if you need to perform simple get/put, see an example
A database (Atlas MongoDB has a free tier which can be used in cases like yours)

Making change to Heroku server

I inherited an app, and while I intend to redeploy everything correctly shortly with a host of other changes, a client of mine wants new branding up quickly on a Heroku server.
I access the server this way:
heroku run bash --app APPNAME
and I pulled down the file via wget and put it into a static files directory.
However, after doing this, the change is not reflected live. Is there anyway to make a temporary change like this without a full redeploy?
File systems on Heroku are ephemeral - the files get deleted and there is no persistence.
The Heroku filesystem is ephemeral - that means that any changes to
the filesystem whilst the dyno is running only last until that dyno is
shut down or restarted. Each dyno boots with a clean copy of the
filesystem from the most recent deploy. This is similar to how many
container based systems, such as Docker, operate.
Why Are My Files Deleted - Heroku

Heroku: what is the difference between "heroku ps:exec" and "heroku run bash"?

What is the difference between heroku ps:exec and heroku run bash? I am just trying to understand the concept. Both seem to be establishing an SSH-tunnel to a remote container/dyno. So why does heroku ps:exec require a dyno-restart on the first use? It seems this command is more generic (since it uses a default shell), so what needs to be configured/installed for it?
heroku run bash creates a standalone (ie not associated with any particular process) that has your application code available and gives you a bash session. This is helpful for running one-off tasks like a database migration it can also be helpful to debug issues where you need to look at the filesystem.
heroku ps:exec tunnels to a dyno that is already running as part of your formation. For instance, if you had 5 web dynos you could tunnel directly to web.3 for instance. This is useful in situations where a dyno is exhibiting issues (memory pressure or high load for example). Being able to connect to the problematic dyno is very useful for debugging.
You should also note that your config vars (ie environment vars set on the heroku settings tab) are not set in heroku ps:exec session.
I can't say for certain why a restart is required but I imagine that some configuration needs to change to enable a connection to a dyno already running in the fleet.

Files different from running process and heroku run bash

I accessed the dyno via heroku run bash and made a file foo. However, when I check from my app, it still cannot find foo. So I dug deeper by trying to install nginx on a dyno, turning on autoindex, and I can confirm that the files are different from what's accessed via heroku run bash and from nginx. Why is that? How do I put files to the filesystem where my running process is showing.
When you issue heroku run bash a new dyno is created just for this one-off, and you are given access to it. Any file you create will "disappear" once your log-off, since the Heroku file-system is ephemeral.
That means the file-system is restored to its native state whenever a new dyno is created, or a dyno is rebooted. The "native" state is what's in your slug -- the "compiled" version of your app -- whatever is built by the build-pack after you "git push" to Heroku.
If you want a read-only file available to all your Dynos, either put it in your slug (for example: by including it in git, but also by using a different build-pack), or put it somewhere all your dynos can access (like a shared database, a Redis/Memcache instance, or most logically: S3).

Resources