My project is using the latest ruby-buildpack which currently loads nodejs 6.14.4. I'd like to use a more current version of nodejs. What's the best way to get it exposed to the application? Does multi-buildpacks solve this problem, and if so, do I list the nodejs buildpack before or after the ruby buildpack in the manifest file? Or, would it be better to package a custom buildpack?
What's the best way to get it exposed to the application? Does multi-buildpacks solve this problem,
I think multi-buildpacks should work for you. You can put Nodejs as a supply buildpack which would tell it to install Node.js, whatever version you want. Then the Ruby buildpack would run and Node.js should be available on the path while it runs so you can use it to do whatever you want.
and if so, do I list the nodejs buildpack before or after the ruby buildpack in the manifest file
The last buildpack should be the buildpack which supplies the command to start your app. Only the final buildpack is allowed to pick the command which starts your app. Other buildpacks, called supply buildpacks, only contribute/install dependencies.
It sounds like that should be the Ruby buildpack in your case.
Or, would it be better to package a custom buildpack?
I'd strongly advise against this. Forking and maintaining a buildpack is a lot of work. Let other people do this work for you and you'll be a lot happier :)
Related
Terribly sorry if this is an obvious question. But I have a webapp that relies on a CLI tool to get it to work. I was wondering if there was a way I could specify this without using a custom buildpack. And how to go about doing this if possible
Any help on this would be great, thanks
Can you add CLI tools to a Cloud Foundry app?
It's not possible to directly install things with apt or apt-get. Your app runs as an unprivileged user and is unable to run those tools to install things.
This leaves you with a couple options:
Get the binary and bundle it with your app. Some people (no judgement from me though) would say that your app is responsible for bringing everything it needs to run anyway, so you should be doing this already.
Twelve-factor apps also do not rely on the implicit existence of any system tools. Examples include shelling out to ImageMagick or curl. [1]
This path works well for dependencies that are small or self contained, like statically built Go apps. If your app need shared libraries or other resources to function, you need to bundle those with your app too. It's also not great if the size of what you bundle is large. Everything you bundle will be pushed up with the app, so it can slow down your pushes. You are also responsible for tracking updates and making sure that you have the latest, bug free & security patched binaries & libraries.
The general steps for doing this are:
Create a folder like binaries/ under the root of your app, with subfolders of bin/ and lib/.
Place all your binaries under binaries/bin and any shared libraries they require under binaries/lib.
Add a .profile file at the root of your app. This will be sourced prior to your app starting so it will put any binaries you bundle on the path and add libraries to the search path.
In .profile put the following:
export PATH=$HOME/binaries/bin:$PATH
export LD_LIBRARY_PATH=$HOME/binaries/lib:$LD_LIBRARY_PATH
That should be it. Just push your app with all the new files.
Another easier option, is to use the Apt buildpack [2]. This buildpack can install required dependencies using apt. You just need to add an apt.yml file to the root of your app & run your app with multi-buildpacks (apt buildpack first, then your normal buildpack).
The main benefit of doing this is that you don't have to manage the dependencies. The apt buildpack will automatically install them from the repo you tell it to use, so it'll pick up new versions from there as well. This is good if what you need to install has a lot of dependencies, particularly sensitive dependencies (like openssl) or dependencies that get updated/patched often like other language runtimes (Python, Perl, Ruby, etc...).
Other benefits. It's easier because the buildpack takes care of adjusting PATH & LD_LIBRARY_PATH. It also makes the app size smaller so pushes are faster.
The downsides of this option are that the apt-buildpack is not an official buildpack (it's community maintained). It also works best when you have Internet access, so it can download binaries from the Internet, although you can work around this by using an internal repo.
There's a couple other options as well, but I wouldn't recommend them unless both options above are definitely not going to work for you.
Use Docker. You can set up your own Docker container with all the dependencies you need, plus your app code and cf push the Docker image to CF. The downside of this is that your lose the advantages of using buildpacks, so you're back to building and managing Docker images and all the required dependencies of your app all on your own.
You could create your own custom buildpack and supply the dependencies that way. I don't see any reason you'd want to do this though. It's a decent bit of work and in the end, you'd have something that's just more brittle and less flexible than Apt Buildpack.
It's technically possible to ship your own rootfs, but you really really shouldn't (I'm just including this to be thorough). This is the base file system that's used by all apps on CF. Doing this has a lot of drawbacks though, chiefly being that it's difficult. It also applies to all apps on the foundation, can bloat the size of the rootfs, and makes a larger attack surface for anything using the rootfs (i.e. all apps).
Hope that helps!
[1] https://12factor.net/dependencies
[2] https://github.com/cloudfoundry/apt-buildpack
I have a CIO Blumix Cloud Foundry PHP app developed that needs some additional components.
I used https://github.com/cloudfoundry/php-buildpack for the build. I read in its documentation that I can add my own extension. I did that and added a tar.tgz and added instructions in the extention.py how to install it.
The target location is: /home/vcap/.
I see the installation running okay, and I see the folder during deploy stage (in DevOps Pipelines deployment stage log&history).
But when deployment passes and I read with a deployed php page the folder, I see that it is not there. I read "container destroyed successfully" message in the log of the deploy. Maybe the whole installation environment goes destroyed? Where is a safe place in the deployment file structure where I can install components so they remain after the deployment passes?
I'm using the def compile(install): to place my unix commands. Example: os.system('ls') to list the installation folders content. They work properly.
Thx in advance!
There are two totally different environments used by your app: staging and runtime. Staging is where the buildpack runs & runtime is where the product of staging (i.e. your app) is run.
Unfortunately, paths are not the same in staging and runtime. At runtime your app lives under /app or /home/vcap/app (the former is a symlink to the latter). Staging is different. There is a /home/vcap directory but it's not used for anything.
Instead, the buildpack scripts are fed paths to use via cli arguments. This is all documented here.
As a PHP buildpack extension, you can access the cli args, and many other things, by looking at the context that is maintained by the buildpack. This gets passed directly into the buildpack extension methods like service_environment & service_commands. The compile buildpack extension method is slightly different as the argument passed in is not the content, but that argument does have a reference to the context (it's install.builder._ctx).
Having said all that, I would not recommend using PHP buildpack extensions at this point. The buildpack is being rewritten and that functionality is being dropped. It's not going to have a direct replacement, but the closest thing would be Composer's ability to execute scripts. My suggestion would be to see if you can use the Composer functionality. It'll be more portable as it won't depend on buildpack specific behavior.
I used to use Anvil (through hammer) to build some native libs to be bundled with a rails app. Specifically I was building libapngasm using this:
https://github.com/Kagetsuki/heroku-buildpack-apngasm
Unfortunately it seems Anvil has been discontinued and I couldn't find any information on how to do a remote build and retrieve the resulting binaries through the Build API.
Is there a new alternative to Anvil? What is a "correct" way to do this?
OK, the official answer here was a little more obvious than I had expected. Basically if you're running the same gcc/libc~ as that stack your dyno is running compile locally. Otherwise just spin up a VM or a docker image with a compatible version and build on that. Then just vendorize the libraries/binaries into your app repository so they'll be bundled up with the slug when you push. Finally, set your heroku environment load path to find the libs/bins you bundled.
We use maven to deploy the code changes to cq interner server / CRX Lite and the problem here is that it takes long time where the changes itself is often only one line code.
Has somebody experience with CQ5 with jetty and can give me a good Guide?
am not sure i understand the relationship with jetty (which ships as servlet container of latter versions of AEM/CQ5), but will answer to the code deployment part:
deploying a full content package (full content) should be done using
maven-content-package plugin for smaller deployments of content,
when you can't use integrated dev environments like sling eclipse dev
tools, i'd suggest you use the excellent repo command that basically zips the current folder and deploy it. I'm using it as an external tool command of intellij and it's really fast.
finally, if the deployment you're referring to is osgi deployment, maven sling plugin can help you with that (will still compile/package the whole osgi bundle though)
Does anyone know of a good Django equivalent of Capistrano/Webistrano?
Fabric is a Python-based application deployment system. It can be used to deploy Django projects.
Capistrano (and therefore Webistrano) can be used for pretty much any deployment, so long as you use SSH. Capistrano is Rails-ready out-of-the-box but it can easily be configured to deploy PHP, Django, Java...whatever really.
Capistrano is a Ruby application so you'll need to have Ruby (and the required Gems) installed to run it.
Webistrano is a Rails application and you can run this locally or deploy it to a server if you wish.
I googled around for a simple formula, and then created my own at: http://www.sandelman.ca/mcr/blog/ruby-on-rails/deploying_django_applications_with_capistrano/