Giter VIP home page Giter VIP logo

heroku-buildpack-clojure's Introduction

Heroku buildpack: Clojure CI

clojure

This is the official Heroku buildpack for Clojure apps. It uses Leiningen.

Note that you don't have to do anything special to use this buildpack with Clojure apps on Heroku; it will be used by default for all projects containing a project.clj file, though it may be an older revision than what you're currently looking at.

How it works

The buildpack will detect your app as Clojure if it has a project.clj file in the root. If you use the clojure-maven-plugin, the standard Java buildpack should work instead.

Documentation

For more information about using Clojure and buildpacks on Heroku, see these Dev Center articles:

Usage

Example usage for an app already stored in git:

$ tree
|-- Procfile
|-- project.clj
|-- README
`-- src
    `-- sample
        `-- core.clj

$ heroku create
...

$ git push heroku main
...
remote: -----> Fetching custom tar buildpack... done
remote: -----> Clojure (Leiningen 2) app detected
remote: -----> Installing OpenJDK 1.8...done
remote: -----> Installing Leiningen
remote:        Downloading: leiningen-2.5.2-standalone.jar
remote:        Writing: lein script
remote: -----> Building with Leiningen
remote:        Running: lein uberjar
remote:        Created /tmp/build_37f1ae84b9f8b63c3ddef2a4b691ef41/target/clojure-getting-started-1.0.0-SNAPSHOT.jar
remote:        Created /tmp/build_37f1ae84b9f8b63c3ddef2a4b691ef41/target/clojure-getting-started-standalone.jar
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing... done, 53.6MB
remote: -----> Launching... done, v5
remote:        https://gentle-water-6857.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy.... done.

Configuration

Leiningen 1.7.1 will be used by default, but if you have :min-lein-version "2.0.0" in project.clj (highly recommended) then the latest Leiningen 2.x release will be used instead.

Your Procfile should declare what process types which make up your app. Often in development Leiningen projects are launched using lein run -m my.project.namespace, but this is not recommended in production because it leaves Leiningen running in addition to your project's process. It also uses profiles that are intended for development, which can let test libraries and test configuration sneak into production.

In order to ensure consistent builds, normally values set with heroku config:add ... (other than LEIN_USERNAME, LEIN_PASSWORD, and LEIN_PASSPHRASE) will not be visible at compile time. To expose more to the compilation process, set a BUILD_CONFIG_ALLOWLIST config var containing a space-delimited list of config var names. Note that this can result in unpredictable behaviour since changing your app's config does not result in a rebuild of your app. So it's easy to get into a situation where your build is broken, but you don't notice it until later when you push. For this reason it's recommended to take care with this feature and always push after changing a allowlisted config value.

Uberjar

If your project.clj contains an :uberjar-name setting, then lein uberjar will run during deploys. If you do this, your Procfile entries should consist of just java invocations.

If your main namespace doesn't have a :gen-class then you can use clojure.main as your entry point and indicate your app's main namespace using the -m argument in your Procfile:

web: java -cp target/myproject-standalone.jar clojure.main -m myproject.web

If you have custom settings you would like to only apply during build, you can place them in an :uberjar profile. This can be useful to use AOT-compiled classes in production but not during development where they can cause reloading issues:

:profiles {:uberjar {:main myproject.web, :aot :all}}

If you need Leiningen in a heroku run session, it will be downloaded on-demand.

Note that if you use Leiningen features which affect runtime like :jvm-opts, extraction of native dependencies, or :java-agents, then you'll need to do a little extra work to ensure your Procfile's java invocation includes these things. In these cases it might be simpler to use Leiningen at runtime instead.

Leiningen at Runtime

Instead of putting a direct java invocation into your Procfile, you can have Leiningen handle launching your app. If you do this, be sure to use the trampoline and with-profile tasks. Trampolining will cause Leiningen to calculate the classpath and code to run for your project, then exit and execute your project's JVM, while with-profile will omit development profiles:

web: lein with-profile production trampoline run -m myapp.web

Including Leiningen in your slug will add about ten megabytes to its size and will add a second or two of overhead to your app's boot time.

Overriding build behavior

If neither of these options get you quite what you need, you can check in your own executable bin/build script into your app's repo and it will be run instead of compile or uberjar after setting up Leiningen.

Leiningen Version

The buildpack will check for a bin/lein script in the repo, and run it instead of the default lein command. This allows you to control the exact version of Leiningen used to build the app.

JDK Version

By default you will get OpenJDK 1.8. To use a different version, you can commit a system.properties file to your app.

$ echo "java.runtime.version=1.7" > system.properties
$ git add system.properties
$ git commit -m "JDK 7"

Hacking

To change this buildpack, fork it on GitHub. Push up changes to your fork, then create a test app with --buildpack YOUR_GITHUB_URL and push to it. If you already have an existing app you may use heroku config:add BUILDPACK_URL=YOUR_GITHUB_URL instead.

For example, you could adapt it to generate a tarball at build time.

Open bin/compile in your editor, and replace the block labeled "Calculate build command" with something like this:

echo "-----> Generating tar with Leiningen:"
echo "       Running: lein tar"
cd $BUILD_DIR
PATH=.lein/bin:/usr/local/bin:/usr/bin:/bin JAVA_OPTS="-Xmx500m -Duser.home=$BUILD_DIR" lein tar 2>&1 | sed -u 's/^/       /'
if [ "${PIPESTATUS[*]}" != "0 0" ]; then
    echo " !     Failed to create tar with Leiningen"
    exit 1
fi

Commit and push the changes to your buildpack to your GitHub fork, then push your sample app to Heroku to test. The output should include:

-----> Generating tar with Leiningen:

If it's something other users would find useful, pull requests are welcome.

Troubleshooting

To see what the buildpack has produced, do heroku run bash and you will be logged into an environment with your compiled app available. From there you can explore the filesystem and run lein commands.

heroku-buildpack-clojure's People

Contributors

alexati avatar danskarda avatar dependabot[bot] avatar doriskwan avatar dzaporozhets avatar edmorley avatar jkutner avatar joshwlewis avatar kochb avatar maio avatar malax avatar mattgraham avatar mmcgrana avatar nvbn avatar pelle avatar ruudud avatar schneems avatar technomancy avatar wjlroe avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

heroku-buildpack-clojure's Issues

:production profile two ways

Currently, what's the correct way to configure the :production profile?

As is in this repo's readme.md

:production {:app-specific "config"
             :mirrors {"central" "http://s3pository.herokuapp.com/maven-central"}}
web: lein with-profile offline,production trampoline run -m myapp.web

or?

as is on heroku dev center

:production {:misc "configuration" ; app-specific stuff
             :offline true
             :mirrors {#"central|clojars"
                       "http://s3pository.herokuapp.com/clojure"}}
web: lein with-profile production trampoline run -m myapp.web # 2.x

bash: lein: command not found

I'm trying to deploy a clojure web app on heroku. Compilation works fine and heroku says it has launched my app. When I open it in the browser I get an application error. When I check the logs I see an error message that it could not find lein command. Any ideas?

Logs:

± % g push heroku master                                                                                                                                                                              !1076
Counting objects: 25, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (16/16), done.
Writing objects: 100% (19/19), 1.71 KiB, done.
Total 19 (delta 10), reused 0 (delta 0)

-----> Heroku receiving push
-----> Fetching custom buildpack... done
-----> Clojure (Leiningen 2) app detected
-----> Installing Leiningen
       Downloading: leiningen-2.0.0-preview8-standalone.jar
       Writing: lein script
-----> Building with Leiningen
       Running: lein with-profile production do compile :all, clean-m2
       Retrieving lein-clean-m2/lein-clean-m2/0.1.2/lein-clean-m2-0.1.2.pom (2k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving lein-newnew/lein-newnew/0.3.4/lein-newnew-0.3.4.pom (2k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving stencil/stencil/0.2.0/stencil-0.2.0.pom (2k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving slingshot/slingshot/0.8.0/slingshot-0.8.0.pom (1k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving bultitude/bultitude/0.1.5/bultitude-0.1.5.pom (2k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving thneed/thneed/1.0.0-SNAPSHOT/maven-metadata.xml (1k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving thneed/thneed/1.0.0-SNAPSHOT/maven-metadata.xml (1k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving lein-clean-m2/lein-clean-m2/0.1.2/lein-clean-m2-0.1.2.jar (3k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving slingshot/slingshot/0.8.0/slingshot-0.8.0.jar (6k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving stencil/stencil/0.2.0/stencil-0.2.0.jar (16k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving lein-newnew/lein-newnew/0.3.4/lein-newnew-0.3.4.jar (14k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving bultitude/bultitude/0.1.5/bultitude-0.1.5.jar (3k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.2.1/clojure-1.2.1.jar (3165k)
           from http://s3pository.herokuapp.com/clojure/
       Performing task 'do' with profile(s): 'production'
       Retrieving commons-io/commons-io/1.4/commons-io-1.4.pom (13k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/maven-metadata.xml (1k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/maven-metadata.xml (1k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.3.0-alpha6/clojure-1.3.0-alpha6.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.3.0-alpha7/clojure-1.3.0-alpha7.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.3.0-alpha8/clojure-1.3.0-alpha8.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.3.0-beta2/clojure-1.3.0-beta2.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.3.0-beta3/clojure-1.3.0-beta3.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.3.0-RC0/clojure-1.3.0-RC0.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.4.0-alpha1/clojure-1.4.0-alpha1.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.4.0-alpha2/clojure-1.4.0-alpha2.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.4.0-alpha3/clojure-1.4.0-alpha3.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.4.0-alpha4/clojure-1.4.0-alpha4.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.4.0-alpha5/clojure-1.4.0-alpha5.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.4.0-beta1/clojure-1.4.0-beta1.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.4.0-beta2/clojure-1.4.0-beta2.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.4.0-beta3/clojure-1.4.0-beta3.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.4.0-beta4/clojure-1.4.0-beta4.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.4.0-beta5/clojure-1.4.0-beta5.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.4.0-beta6/clojure-1.4.0-beta6.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.4.0-beta7/clojure-1.4.0-beta7.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.5.0-alpha1/clojure-1.5.0-alpha1.pom (6k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.5.0-alpha2/clojure-1.5.0-alpha2.pom (6k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving org/clojure/clojure/1.5.0-alpha3/clojure-1.5.0-alpha3.pom (6k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving clojurewerkz/support/0.2.0/support-0.2.0.pom (4k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving com/google/guava/guava/11.0.1/guava-11.0.1.pom (5k)
           from http://s3pository.herokuapp.com/clojure/
       Retrieving com/google/guava/guava-parent/11.0.1/guava-parent-11.0.1.pom (2k)
           from http://s3pository.herokuapp.com/clojure/
       Compiling workoutbook.templates.session
       Compiling workoutbook.templates.layouts
       Compiling workoutbook.templates.workoutbook.entries
       Compiling workoutbook.templates.workoutbook
       Compiling workoutbook.models.user
       Compiling workoutbook.models.entries
       Compiling workoutbook.routes
       Compiling workoutbook.views.session
       Compiling workoutbook.views.common
       Compiling workoutbook.views.workoutbook.entries
       Compiling workoutbook.views.workoutbook
       Compiling workoutbook.setup
-----> Discovering process types
       Procfile declares types -> web
-----> Compiled slug size is 10.3MB
-----> Launching... done, v8
       http://workoutbook.herokuapp.com deployed to Heroku

To [email protected]:workoutbook.git
   ef89450..6856f76  master -> master
2012-08-22T17:41:06+00:00 heroku[api]: Deploy 6856f76 by [email protected]
2012-08-22T17:41:06+00:00 heroku[web.1]: State changed from crashed to starting
2012-08-22T17:41:07+00:00 heroku[slugc]: Slug compilation finished
2012-08-22T17:41:08+00:00 heroku[web.1]: Starting process with command `lein ring server-headless`
2012-08-22T17:41:09+00:00 app[web.1]: bash: lein: command not found
2012-08-22T17:41:10+00:00 heroku[web.1]: State changed from starting to crashed
2012-08-22T17:41:10+00:00 heroku[web.1]: Process exited with status 127

And my Procfile

web: lein ring server-headless

Question: Using bin/build script

When using the bin/build script with the following

#!/usr/bin/env bash

./bin/lein with-profile production trampoline run

cf push returns with a timeout. Am I doing something wrong here?

Error staging application <app-name>: timed out after 15 minute(s)

The app starts and runs just fine, just getting the above error

Could not transfer artifact lein-cprop:lein-cprop:pom:1.0.1 from/to central

I'm new and I'm not sure if this is an issue with my cf, with this buildpack, or something else, but I thought I'd try here:

[my-hostname]$ cf push
  Using manifest file /home/my-login/repos/routes-diff-cl/manifest.yml

  Using stack cflinuxfs2...
  OK
  Updating app routes-diff-cl in org [email protected] / space dev as [email protected]...
  OK

  Uploading routes-diff-cl...
  Uploading app files from: /home/my-login/repos/routes-diff-cl
  Uploading 7.2M, 3272 files
  Done uploading               
  OK

  Stopping app routes-diff-cl in org [email protected] / space dev as [email protected]...
  OK

  Starting app routes-diff-cl in org [email protected] / space dev as [email protected]...
  -----> Downloaded app package (47M)
  Cloning into '/tmp/buildpacks/heroku-buildpack-clojure'...
  -----> Installing OpenJDK 1.8... done
  -----> Installing Leiningen
  Downloading: leiningen-2.6.1-standalone.jar
  Writing: lein script
  -----> Building with Leiningen
  Running: lein uberjar
  Could not transfer artifact lein-cprop:lein-cprop:pom:1.0.1 from/to central (https://repo1.maven.org/maven2/): java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
  This could be due to a typo in :dependencies or network issues.
  If you are behind a proxy, try setting the 'http_proxy' environment variable.
  !     Failed to build.
  Staging failed: Buildpack compilation step failed

  FAILED
  BuildpackCompileFailed

  TIP: use 'cf logs routes-diff-cl --recent' for more information
  [my-hostname]$ 

cf logs doesn't show any more information than what is above. I can build the jar locally.

java/bin missing during deploy

I'm getting the following error during deploy, which I believe must be related to this change:
5ae20b7#diff-c7b43338c09c3c9afd420fd8b6bb5198L13

-----> Fetching custom git buildpack... done
-----> Clojure (Leiningen 2) app detected
tar: bin/java: Not found in archive
tar: Exiting with failure status due to previous errors

 !     Push rejected, failed to compile Clojure (Leiningen 2) app

Basically it's trying to extract bin/java and failing on it. I've tried locally and it is available in the tar file. So I'm a bit confused whats going on. Am I the only person seeing this problem? Could it be a network issue?

Make node available at build time

Currently, the way to make node available at build time is using multi-pack support like this:

$ heroku buildpacks:clear
$ heroku buildpacks:add https://github.com/heroku/heroku-buildpack-nodejs
$ heroku buildpacks:add https://github.com/heroku/heroku-buildpack-clojure

But this requires the presence of a minimal package.json file with at least the contents:

{}

For apps that use lein-npm this is a problem in part because lein-npm generates the package.jsonon the fly (during the build), which causes the nodejs buildpack's detection to fail.

It would be preferable if the nodejs buildpack was not necessary, or if there were an easier way to use it.

See also: http://stackoverflow.com/questions/32693625/add-nodejs-to-a-clojure-app-in-heroku/32695104

CLI and tools.deps support

Lots of projects now use tools.deps with the Clojure CLI.

Personally, I haven't used leiningen in over a year and avoid uberjar whereever I can (and I very well can with tools.deps!)

If a project has a deps.edn it can be run directly (no uberjars needed):
clj -m my-project.main

This is a much simpler, lightweight and flexible approach. It would be awesome if heroku supported it, especially given that it looks like the Clojure CLI is already installed by this buildpack.

Repo auth settings in :dev profile affect deploys

My project.clj includes an override for developers to use gpg instead of env vars to access an S3 repo:

  :profiles {:production {:env {:production true}}
             :dev {:dependencies [[midje "1.4.0"]]
                   ;; :repositories [["snapshots" {:url "s3p://mybucket/snapshots/"
                   ;;                              :username :gpg
                   ;;                              :passphrase :gpg}]]

                   }}

but if the :repositories aren't commented out then Heroku deploys fail with

-----> Heroku receiving push
-----> Fetching custom git buildpack... done
-----> Clojure (Leiningen 2) app detected
-----> Using cached Leiningen 2.0.0-preview10
       Writing: lein script
-----> Building with Leiningen
       Running: lein with-profile production compile :all
       No matching ctor found for class org.sonatype.aether.repository.Authentication
 !     Failed to build.
 !     Heroku push rejected, failed to compile Clojure (leiningen 2) app

Based on issue #18 my impression is that Leiningen shouldn't be doing anything with the dev profile now.
Is this a regression in Lein or the buildpack?

Travis fails for PRs with "Invalid credentials provided"

The Travis run for #51 failed due to something that appears unrelated to the PR:

Uploading /home/travis/.ssh/id_rsa.pub SSH key... !
 ▸    Invalid credentials provided.
Enter your Heroku credentials:
Email:  ▸    CLI needs to prompt for Password but stdin is not a tty.

The command "bash etc/travis-setup.sh" failed and exited with 1 during .

(See: https://travis-ci.org/heroku/heroku-buildpack-clojure/jobs/244984109)

I believe this is because the Travis job has a hard dependency on the secure environment variables that are not accessible by PRs from forks (Travis docs).

Normally jobs that make use of these will do so for optional parts of the build (eg publishing new builds after tagging), rather than the main test run. I haven't looked closely at the tests here, but now that there are decent Docker images available for Heroku-16, perhaps the testing can be moved locally, rather than needing to spin up Heroku apps?

(See also heroku/heroku-buildpack-jvm-common#28)

CI is failing after herokuapp.com default domain name change

CI on main is currently failing with:

Failures:

  1) Compojure on jdk-1.8 deploys clojure-minimal successfully
     Failure/Error: expect(http_get(app)).to include('["Hello" :from Heroku]')

     Excon::Error::NotFound:
       Expected(200) <=> Actual(404 Not Found)

eg:
https://github.com/heroku/heroku-buildpack-clojure/actions/runs/5531841256/jobs/10093073350?pr=142#step:5:477

This is due to:
https://devcenter.heroku.com/changelog-items/2640

And means needing to update this helper:

def http_get(app, options = {})
retry_limit = options[:retry_limit] || 50
path = options[:path] ? "/#{options[:path]}" : ""
Excon.get("https://#{app.name}.herokuapp.com#{path}", :idempotent => true, :expects => 200, :retry_limit => retry_limit).body
end

Similar to:
https://github.com/heroku/heroku-buildpack-nodejs/pull/1110/files

This blocks being able to merge #142.

cc @Malax

uberjar branch: Release versions may not depend upon snapshots

Using the uberjar branch I get:

       Release versions may not depend upon snapshots.
       Freeze snapshots to dated versions or set the `LEIN_SNAPSHOTS_IN_RELEASE` environment variable to override.
 !     Failed to build.

 !     Push rejected, failed to compile Clojure (Leiningen 2) app

I set the LEIN_SNAPSHOTS_IN_RELEASE env with heroku config:
LEIN_SNAPSHOTS_IN_RELEASE: override
but the same error happens.

I tried exporting LEIN_SNAPSHOTS_IN_RELEASE with that value in my local machine and I could create the uberjar.

Can you reproduce this error by using snapshots?

nodejs downloaded over HTTP

The buildpack downloads nodejs over HTTP and then doesn't perform any additional (hash, signature) validation:

echo "Downloading and installing node $version..."
local download_url="http://s3pository.heroku.com/node/v$version/node-v$version-$os-$cpu.tar.gz"
curl "$download_url" --silent --fail -o /tmp/node.tar.gz || (echo "Unable to download node $version; does it exist?" && false)
tar xzf /tmp/node.tar.gz -C /tmp
mv /tmp/node-v$version-$os-$cpu $dir
chmod +x $dir/bin/*

The s3pository.heroku.com redirector supports HTTPS, so a s/http:/https:/ should work fine:

$ curl -I https://s3pository.heroku.com/node/v7.10.0/node-v7.10.0-linux-64.tar.gz
HTTP/1.1 301 Moved Permanently
...
Location: https://nodejs.org/dist/v7.10.0/node-v7.10.0-linux-64.tar.gz
...

repl socket fails to open

Is lein repl supported with the lein2 branch of the buildpack?

I end up with the following stacktrace:

All namespaces already :aot compiled.
Exception in thread "main" java.net.ConnectException: Connection refused
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:327)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:193)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)
        at java.net.Socket.connect(Socket.java:546)
        at java.net.Socket.connect(Socket.java:495)
        at java.net.Socket.<init>(Socket.java:392)
        at java.net.Socket.<init>(Socket.java:206)
        at clojure.tools.nrepl$connect.doInvoke(nrepl.clj:173)
        at clojure.lang.RestFn.invoke(RestFn.java:421)
        at clojure.tools.nrepl.ack$send_ack.invoke(ack.clj:47)
        at clojure.tools.nrepl.server$start_server.doInvoke(server.clj:95)
        at clojure.lang.RestFn.invoke(RestFn.java:457)
        at user$eval730.invoke(NO_SOURCE_FILE:1)
        at clojure.lang.Compiler.eval(Compiler.java:6511)
        at clojure.lang.Compiler.eval(Compiler.java:6501)
        at clojure.lang.Compiler.eval(Compiler.java:6477)
        at clojure.core$eval.invoke(core.clj:2797)
        at clojure.main$eval_opt.invoke(main.clj:297)
        at clojure.main$initialize.invoke(main.clj:316)
        at clojure.main$null_opt.invoke(main.clj:349)
        at clojure.main$main.doInvoke(main.clj:427)
        at clojure.lang.RestFn.invoke(RestFn.java:421)
        at clojure.lang.Var.invoke(Var.java:419)
        at clojure.lang.AFn.applyToHelper(AFn.java:163)
        at clojure.lang.Var.applyTo(Var.java:532)
        at clojure.main.main(main.java:37)
REPL server launch timed out.

Consider providing default Procfile

It seems the majority of Clojure apps would work with a simple one-line Procfile: web: lein run

It seems to be a general goal of our build process to require as few heroku-specific changes as possible; this would allow existing conventions (specifying :main in project.clj) to take the place of the heroku-specific Procfile.

In general it's healthy to have a deep mistrust of special cases or magic behaviour, but I think this could get a pass because it only turns an error condition (no Procfile) into a working one and it's very easy to detect whether a :main key is specified and emit a big warning when it's not.

We'd also want to update the existing articles in the devcenter to reflect this if we end up doing it.

Thoughts?

AgentProxyException when referencing a git repo in deps.edn

I'm trying to deploy a project that references another gitlab repo as a dependency through clojure deps.

In order to have the required ssh keys, I use the following custom buildpack on top of the clojure one: https://github.com/simon0191/custom-ssh-key-buildpack

But when trying to pull this private gitlab repo through clojure deps, I get the following message:

       com.jcraft.jsch.agentproxy.AgentProxyException: connector is not available: 
        at com.jcraft.jsch.agentproxy.ConnectorFactory.createConnector (ConnectorFactory.java:120)
           clojure.tools.gitlibs.impl$fn__1007.invokeStatic (impl.clj:30)
           clojure.tools.gitlibs.impl/fn (impl.clj:28)
           (...)

There seems to be some configuration that needs to be amended, but I can't find where.

CLI tools step failure message could be improved in cases when download.clojure.org certificate is expired

remote: -----> Installing Clojure 1.10.0.411 CLI tools
remote:  !     Push rejected, failed to compile Clojure (Leiningen 2) app.
remote: 
remote:  !     Push failed
remote: Verifying deploy...
remote: 
remote: !	Push rejected to foo-app.
curl https://download.clojure.org/install/linux-install-1.10.0.411.sh
curl: (60) SSL certificate problem: certificate has expired
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

Alex Miller is aware of this issue and is currently working on fixing it afaik.
Hopefully it won't happen again, so priority of this issue is probably low.

Compiling ClojureScript with advanced optimizations takes a lot of time

Deploying my open-source noir-auth-app project ( https://github.com/xavi/noir-auth-app/blob/heroku-deploy/project.clj ) to Heroku takes 6–7 minutes. Approximately half of this time is spent compiling less than 200 lines of ClojureScript with :advanced optimizations.

The deployment is done via uberjar, as I understand this is now the recommended deployment method, and lein-cljsbuild Leiningen hooks are configured (see project.clj linked above for details).

Taking into account that running lein uberjar in my MBP (2.26 GHz Intel Core 2 Duo) takes less than 1 minute and a half, is it normal that deploying to Heroku takes more than 6 minutes?

Looking at the logs, it seems the problem is the :advanced optimizations build, which takes more than 3 minutes in Heroku, but less than 30 seconds in my MBP (in contrast, the other configured ClojureScript build, which uses :whitespace optimizations, takes around the same time, ~16 s, in both my MBP and Heroku, actually a few seconds less in Heroku).

What's even worse is that I'm also working on another project (not open-source) with just 50 more lines of ClojureScript and Heroku cannot complete the deployment in 15 minutes and times out (if there's luck, it takes nearly 7 minutes to compile the ClojureScript with advanced optimizations, and nearly 15 minutes to complete the deployment). (In my MBP, lein uberjar in this project takes 1 min 37 s.)

Is there some problem with :advanced ClojureScript compilation in the Heroku buildpack for Clojure? Am I doing something wrong?

Thanks in advance.

JDK from system.properties is ignored due to config_vars

Update: This is a problem with Dokku and its /start but I believe it should still be fixed in this buildpack as I do not see a reason why it should use different path than the Java buildpack.

Even though setting JDK version > 6 in system.properties results in the correct path being added to clojure.sh, this has no effect because the path is overriden by the path specified in config_vars. This is due to /start sourcing all the .sh files in /app/.profile.d/ prior to running the app.
The default config_vars contains:

PATH: .lein/bin:/usr/local/bin:/usr/bin:/bin

(Contrary to the Java buildpack, which has the JDK included: PATH: /app/.jdk/bin:/usr/local/bin:/usr/bin:/bin.)

Therefore setting the path in clojure.sh has no effect.

For completeness, this part of the /start script causes the path to be overriden:

for file in $app_root/.profile.d/*; do source \$file; done

(Since config_vars is read after clojure.sh)

I believe that the correct solution is to include the path to JDK in config_vars as the Java buildpack does (and remove it from clojure.sh).

I must admit that I am quite surprised nobody has ever had this problem before. It seems that I must be doing something wrong ...

lein2 repl ConnectException Connection refused

Is lein2 repl connect not support the remote nrepl?

lein2 version:Leiningen 2.0.0-preview10 on Java 1.7.0_05 Java HotSpot(TM) 64-Bit Server VM
server 1 ip:172.1.1.1
server 2 ip:172.1.1.2
os:centos

I use lein2 repl it output
nREPL server started on port 49189
REPL-y 0.1.0-beta10
Clojure 1.4.0
Exit: Control+D or (exit) or (quit)
Commands: (user/help)
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
(user/sourcery function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Examples from clojuredocs.org: [clojuredocs or cdoc](user/clojuredocs name-here)
(user/clojuredocs "ns-here" "name-here")
user=>

In the same server use lein2 repl :connect nrepl://localhost:49189
I can connect the nrepl

But in server 2 use lein2 repl :connect nrepl://172.1.1.1:49189
I get
ConnectException Connection refused
java.net.PlainSocketImpl.socketConnect (PlainSocketImpl.java:-2)
java.net.AbstractPlainSocketImpl.doConnect (AbstractPlainSocketImpl.java:339)
java.net.AbstractPlainSocketImpl.connectToAddress (AbstractPlainSocketImpl.java:200)
java.net.AbstractPlainSocketImpl.connect (AbstractPlainSocketImpl.java:182)
java.net.SocksSocketImpl.connect (SocksSocketImpl.java:391)
java.net.Socket.connect (Socket.java:579)
java.net.Socket.connect (Socket.java:528)
java.net.Socket. (Socket.java:425)
java.net.Socket. (Socket.java:208)
clojure.tools.nrepl/connect (nrepl.clj:173)
clojure.core/apply (core.clj:601)
clojure.tools.nrepl/add-socket-connect-method!/fn--1120 (nrepl.clj:215)
Bye for now!

And use lein2 repl :connect nrepl://172.1.1.1:49189
in server1 is the same in server 2

netstat in server1 output
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp6 0 0 localhost:49189 localhost:45265 ESTABLISHED
tcp6 0 0 localhost:45266 localhost:49189 FIN_WAIT2
tcp6 0 0 localhost:45265 localhost:49189 ESTABLISHED

Boot support

There is another build tool for Clojure, called Boot. It's not as popular now as Leiningen now, but its great. Is it possible to add support for it?

clojure / clj command not available during build

During build (or with the "heroku run bash" command), clojure is not available as a command. With the new tooling provided by clojure 1.9 and clojure 1.10 (https://clojure.org/reference/deps_and_cli), more packages are depending on it; so it would be useful to have the command available in the build pack.

More specifically, if dependencies are specified through a deps.edn file that is loaded during uberjar creation with lein-tool-deps (https://github.com/RickMoynihan/lein-tools-deps), which enables to reference github and gitlab repos, the process fails, stating the following error:

remote:        clojure.lang.ExceptionInfo: Could not find clojure executable
remote:         at clojure.core$ex_info.invokeStatic (core.clj:4617)
remote:            clojure.core$ex_info.invoke (core.clj:4617)
remote:            lein_tools_deps.env$clojure_exe.invokeStatic (env.clj:22)
remote:            lein_tools_deps.env$clojure_exe.invoke (env.clj:16)
remote:            lein_tools_deps.env$scrape_clojure_env.invokeStatic (env.clj:28)
remote:            lein_tools_deps.env$scrape_clojure_env.invoke (env.clj:24)
(etc.)

Clear out m2 cache using plugin

Since ~/.m2 needs to be part of the slug in the lein-2 branch, we need to trim it down so that old dependencies that aren't used any more are removed. This was implemented in bin/compile, but never satisfactorily. I think it needs to run inside Leiningen to really work properly.

Leiningen trouble downloading dependencies

I just started getting this problem while trying to deploy a very simple Clojure app. Leiningen seems to try and download the dependencies twice resulting in this error:

Retrieving compliment/compliment/0.1.0/compliment-0.1.0.jar from clojars
   java.lang.IllegalArgumentException: Multiple mirrors configured to match repository {"central" "http://repo1.maven.org/maven2/"}: {"central" {:url "http://s3pository.herokuapp.com/maven-central"}}
    at cemerick.pomegranate.aether$mirror_selector_fn.invoke(aether.clj:463)
    at clojure.lang.AFn.applyToHelper(AFn.java:163)
    at clojure.lang.AFn.applyTo(AFn.java:151)
    at clojure.core$apply.invoke(core.clj:619)
    at clojure.core$partial$fn__4190.doInvoke(core.clj:2396)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:617)
    at clojure.core$memoize$fn__5049.doInvoke(core.clj:5735)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at cemerick.pomegranate.aether$mirror_selector$reify__141.getMirror(aether.clj:478)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:93)
    at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:28)
    at cemerick.pomegranate.aether$resolve_dependencies_STAR_$fn__156.invoke(aether.clj:579)
    at clojure.core$map$fn__4207.invoke(core.clj:2485)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    at clojure.lang.LazySeq.seq(LazySeq.java:60)
    at clojure.lang.RT.seq(RT.java:484)
    at clojure.lang.LazilyPersistentVector.create(LazilyPersistentVector.java:31)
    at clojure.core$vec.invoke(core.clj:354)
    at cemerick.pomegranate.aether$resolve_dependencies_STAR_.doInvoke(aether.clj:577)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:617)
    at cemerick.pomegranate.aether$resolve_dependencies.doInvoke(aether.clj:594)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:617)
    at cemerick.pomegranate$add_dependencies.doInvoke(pomegranate.clj:74)
    at clojure.lang.RestFn.invoke(RestFn.java:2088)
    at leiningen.core.classpath$fn__2759.invoke(classpath.clj:170)
    at clojure.lang.AFn.applyToHelper(AFn.java:167)
    at clojure.lang.AFn.applyTo(AFn.java:151)
    at clojure.core$apply.invoke(core.clj:617)
    at clojure.core$memoize$fn__5049.doInvoke(core.clj:5735)
    at clojure.lang.RestFn.invoke(RestFn.java:436)
    at leiningen.core.classpath$get_dependencies.doInvoke(classpath.clj:299)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:621)
    at leiningen.core.classpath$resolve_dependencies.doInvoke(classpath.clj:343)
    at clojure.lang.RestFn.invoke(RestFn.java:464)
    at leiningen.core.project$load_plugins.invoke(project.clj:524)
    at leiningen.core.project$load_plugins.invoke(project.clj:535)
    at leiningen.core.project$set_profiles.doInvoke(project.clj:638)
    at clojure.lang.RestFn.invoke(RestFn.java:442)
    at leiningen.core.project$merge_profiles.invoke(project.clj:649)
    at leiningen.uberjar$uberjar.invoke(uberjar.clj:128)
    at leiningen.uberjar$uberjar.invoke(uberjar.clj:149)
    at clojure.lang.Var.invoke(Var.java:415)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.Var.applyTo(Var.java:532)
    at clojure.core$apply.invoke(core.clj:619)
    at leiningen.core.main$resolve_task$fn__3029.doInvoke(main.clj:189)
    at clojure.lang.RestFn.invoke(RestFn.java:410)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.RestFn.applyTo(RestFn.java:132)
    at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:619)
    at leiningen.core.main$apply_task.invoke(main.clj:230)
    at lein_environ.plugin$write_env_to_file.invoke(plugin.clj:11)
    at clojure.lang.Var.invoke(Var.java:427)
    at clojure.lang.AFn.applyToHelper(AFn.java:172)
    at clojure.lang.Var.applyTo(Var.java:532)
    at clojure.core$apply.invoke(core.clj:619)
    at robert.hooke$compose_hooks$fn__8655.doInvoke(hooke.clj:40)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:617)
    at robert.hooke$run_hooks.invoke(hooke.clj:46)
    at robert.hooke$prepare_for_hooks$fn__8660$fn__8661.doInvoke(hooke.clj:54)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
    at clojure.lang.RestFn.invoke(RestFn.java:436)
    at leiningen.core.main$resolve_and_apply.invoke(main.clj:234)
    at leiningen.core.main$_main$fn__3092.invoke(main.clj:303)
    at leiningen.core.main$_main.doInvoke(main.clj:290)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.lang.Var.invoke(Var.java:415)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.Var.applyTo(Var.java:532)
    at clojure.core$apply.invoke(core.clj:617)
    at clojure.main$main_opt.invoke(main.clj:335)
    at clojure.main$main.doInvoke(main.clj:440)
    at clojure.lang.RestFn.invoke(RestFn.java:436)
    at clojure.lang.Var.invoke(Var.java:423)
    at clojure.lang.AFn.applyToHelper(AFn.java:167)
    at clojure.lang.Var.applyTo(Var.java:532)
    at clojure.main.main(main.java:37)
!     Failed to build.

!     Push rejected, failed to compile Clojure (Leiningen 2) app

min-lein-version doesn't work with multi-line

The Clojure buildpack ignores :min-lein-version in project.clj unless it's all on one line. The following works:

:min-lein-version "2.5.0"

While the multi-line version, which is valid Clojure, does not:

:min-lein-version
"2.5.0"

Heroku config problem

I set the BUILD_CONFIG_WHITELIST to be S3_AWS_ACCESS_KEY_ID S3_AWS_SECRET_KEY

I also set the S3 environmental variables in the config. This is what I get when I push to heroku:

-----> Clojure (Leiningen 2) app detected
-----> Installing OpenJDK 1.6...done
-----> Using cached Leiningen 2.4.2
Writing: lein script
-----> Building with Leiningen
cat: /tmp/d20140709-320-1t3x36/S3_AWS_ACCESS_KEY_ID S3_AWS_SECRET_KEY: No such file or directory
/app/tmp/buildpacks/clojure/bin/compile: line 121: export: `S3_AWS_ACCESS_KEY_ID S3_AWS_SECRET_KEY=': not a valid identifier

! Push rejected, failed to compile Clojure (Leiningen 2) app

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.