Fork me on GitHub
#boot
<
2016-01-05
>
crisptrutski00:01:05

@fappy: syntax error, sent you a PR with the fix

danielsz01:01:50

Does Boot has something like Leiningen's checkouts for development?

crisptrutski01:01:05

@danielsz probably a better doc link for it, but this should help: https://github.com/boot-clj/boot/issues/154

seancorfield01:01:21

My team all came back from their holiday vacations today, and had their first exposure to Boot and our new build system. It went pretty well overall simple_smile

danielsz01:01:09

Here's a textbook Boot task that should exist (if it doesn't exist already): compress all png's in the fileset with zopfli. https://github.com/google/zopfli

micha01:01:15

@danielsz: 2.6.0-SNAPSHOT has a better checkouts implementation

danielsz01:01:26

@micha: Oh, thank you!

micha01:01:29

let me know if you have any issues, the checkout task has a couple of quirks

micha01:01:44

2.6.0-SNAPSHOT has a --checkout option to boot itself

danielsz01:01:01

@micha: is this still accurate for 2.6.0-SNAPSHOT; https://github.com/boot-clj/boot/issues/154

micha01:01:38

we won't make any breaking changes till 3.0.0 which won't be for a long time

micha01:01:47

so that will continue to work the same

micha01:01:06

we just added a new --checkouts option to boot that does it a little better i think

danielsz01:01:31

Okay, cool, can't wait to try it out, will report back, thanks

be906:01:09

hi, I’m looking for an example of a full-stack app which would comprise clj backend, cljs, SASS stylesheets, live REPL and a way to deploy all these goodies to production

be906:01:23

my current knowledge of tooling, esp. boot, doesn’t allow me to come up with my own solution yet

jethroksy06:01:52

@be9 to include sass just add the boot task i mentioned earlier and compose it

jethroksy06:01:15

you might need to learn the reloaded workflow but its worth it

be906:01:59

what do you mean by «reloaded workflow»? leiningen -> boot?

jethroksy06:01:42

holygrail uses mount which are just pre-configured components

be906:01:40

thanks, I have a small experience with this library

be906:01:26

@micha any good boot+docker recipes? or you just add the target directory and that’s it?

micha06:01:06

usually don't use a target directory at all

micha06:01:18

the application runs from the classpath

micha06:01:44

looks like boot serve -p 3000 repl -sp 1337 wait

jethroksy06:01:46

docker confuses me

micha06:01:46

more or less

micha06:01:08

that starts my serve task on port 3000, starts a repl server on port 1337, and then waits forever

micha06:01:16

(otherwise it would just exit)

micha06:01:38

the serve task would start a webserver of course

be906:01:20

I see, thanks simple_smile

micha06:01:23

this works well on things like elastic beanstalk

micha06:01:40

you can also make uberjar if you want to

micha06:01:48

and just run that with java -jar

micha06:01:11

but some of the applications i'm working on use pods internally

micha06:01:21

so they need to run in boot, currently

be906:01:54

ok thanks @micha and @jethroksy, reading boot docs now

micha06:01:31

👍 good luck!

jethroksy07:01:43

@micha: what does your Dockerfile look like? looks like I have the chance now to deploy to docker with boot

micha07:01:18

sure, one sec

micha07:01:28

here is the docker image in dockerhub

micha07:01:44

this has pretty much all the elements in it

micha07:01:04

it'll roll all your maven deps into the image etc

micha07:01:50

you can extend that, and just put like ENTRYPOINT ["/usr/bin/boot" "serve" ...

micha07:01:02

we usually have a start.sh script though

micha07:01:11

that does some setup of things before starting boot

micha07:01:34

like getting credentials from the environment to configure external services like datadog

jethroksy07:01:03

its just gonna be a simple web server that accepts post requests though

jethroksy07:01:12

serve should be sufficient

micha07:01:26

cool thing is you can test it locally pretty well

micha07:01:42

like if the docker image works locally it'll probably work on beanstalk or whatever

jethroksy07:01:52

yeah beanstalk is where its going

micha07:01:09

yeah we use the eb tool to do the actual deploy

micha07:01:21

with a Dockerrun.aws.json file

micha07:01:26

and a Dockerfile

micha07:01:58

dockerrun.aws.json is very minimal:

micha07:01:02

{
  "AWSEBDockerrunVersion": "1",
  "Ports": [
    {
      "ContainerPort": "80"
    }
  ],
  "Volumes": [],
  "Logging": "/var/log/nginx"
}

jethroksy07:01:23

wew so many tools to learn

micha07:01:42

Dockerfile:

micha07:01:46

FROM adzerk/boot-clj:2.2.0

# Datadog
RUN apt-get update && apt-get install -y adduser
RUN echo 'deb  stable main' > /etc/apt/sources.list.d/datadog.list
RUN apt-key adv --recv-keys --keyserver  C7A7DA52
RUN apt-get update && apt-get install -y datadog-agent

# Application
RUN mkdir /app /app/src app/resources /m2
WORKDIR /app

# next line is for dev
# ADD m2 /m2
ENV BUILT_AT 2015-09-01:15:44:00 # Image checkpoint
ADD src/backend /app/src/backend
ADD resources/config /app/resources/config
ADD start.sh /app/start.sh
ADD src/boot /app/src/boot
COPY build.boot /app/build.boot
COPY boot.properties /app/boot.properties

ENV BOOT_LOCAL_REPO /m2
RUN boot -C serve-proxy # download dependencies

EXPOSE 3000
ENTRYPOINT ["/app/start.sh"]

jethroksy07:01:48

on my prev app i got frustrated and just used tomcat hahaha

micha07:01:03

yeah tomcat is good too

micha07:01:16

especially if you already are familiar with all of its quirks

jethroksy07:01:40

unfamiliar actually, but didn't give me problems like docker did

micha07:01:10

this is for a pretty complex application

micha07:01:14

that dockerfile i pasted

micha07:01:22

so it has accumulated some things lol

jethroksy07:01:25

yeah i think I could use the prev one

jethroksy07:01:31

just change the entry point

micha07:01:46

well you can just do FROM ...

micha07:01:52

and then all you need is the entry point

micha07:01:09

that image is on dockerhub

jethroksy07:01:10

and EXPOSE i assume

micha07:01:40

i think that dockerfile is actually generated by boot

micha07:01:49

you can see the timestamp in there

micha07:01:03

part of the deploy task

jaen07:01:30

Someone said something about using docker+boot?

micha07:01:28

docker compose

micha07:01:37

this is something i want to learn about

jethroksy07:01:35

looks like a whole load of overhead to get an image running

jaen07:01:55

With Ruby I used custom scripting that called capistrano + vagrant for controlling docker and it worked quite well, but it would have been to much overhead if you basically only need the jar. So I decided to try out docker compose instead.

jaen07:01:16

Yeah, it's a bit of overhead, some of that comes from being able to actually develop inside the container.

jethroksy07:01:53

my next app is just gonna be one that accepts a single post request so i was hoping it would be simpler

jethroksy07:01:06

its a code in an hour, deploy and forget kinda thing

jaen07:01:44

I wrote it that way because only me and a girl from the project were running on Linux in the project, the rest three guys were on Windows and I thought it would be easier for them to just run docker image instead of figuring out how to set-up boot.

jaen07:01:51

(I remember it being a hassle on windows)

micha07:01:57

for something like that you can juse base your docker image on adzerk/boot-clj and use that dockerrun file i pasted

jaen07:01:04

But in the end the docker didn't work as flawlessly as I hoped xD

jethroksy07:01:39

ah yes the boot/windows issue

jaen07:01:16

@jethroksy: yeah, in that case I can agree it's a bit too much. You can basically just create the jar and ADD it to the image.

jethroksy07:01:22

i think its about time someone came along and solved this deployment thing

micha07:01:22

windows support is improving, little by little

jethroksy07:01:31

deployment shouldn't be so hard

micha07:01:49

have you looked at the amazon container service?

micha07:01:03

it might be simpler

jaen07:01:05

I dunno, this doesn't seem to hard to me, but maybe I'm biased.

jaen07:01:36

There's also heroku or openshift where you can just throw jars at them and they will run it.

jethroksy07:01:16

a lil' on the pricey end though

jethroksy07:01:35

i don't personally have money to host things actually

jethroksy07:01:45

just hit 20 and heading to uni

jethroksy07:01:55

gonna be in debt for a long time

jaen07:01:57

Openshift and Heroku have free options IIRC.

jethroksy07:01:16

heroku has that 6h hibernation thing that makes it unusable now

jethroksy07:01:28

i used up my free openshift one too 😄

jaen07:01:39

Tough luck then xD

jethroksy07:01:50

anw i'm sure its not as hard as i think it is

jethroksy07:01:00

possibly because of my lack of experience deploying

jaen07:01:01

Openshift is pretty cool, apart from having old postgres

jaen07:01:42

If you're heading to university you could probably snag the $50 Digital Ocean credit from Github as well.

jaen07:01:02

AWS isn't as cheap as DO or Linode once you get out of the free tier.

jethroksy07:01:16

I've used both before

jethroksy07:01:22

DO was pretty good for rails

jaen07:01:29

@micha: yeah, last time I tried boot on Windows was circa summer, on a friend's tablet running Windows 10 and for the longest time we couldn't figure how to get boot.exe to work.

jethroksy07:01:31

but this was all before docker came out

jaen07:01:43

Well, it's even better for Java

jethroksy07:01:52

then army happened and i lost touch with coding

jaen07:01:58

Since you only need to do java -jar uberjar.jar and call it a day.

jethroksy07:01:24

for all my free heroku deployments java -jar didn't /justwork/ for me

jethroksy07:01:34

i had to use web: lein ring server-headless

jaen07:01:35

Compulsory army tour where you're from?

jethroksy07:01:41

conscript army

micha07:01:23

haha not much computing in the army

jaen07:01:36

Hah, I've barely dodged that bullet, the year before mine was the last that was conscripted in Poland.

jethroksy07:01:44

I actually managed servers because of my IT background

jethroksy07:01:58

but that's all the old legacy stuff

micha07:01:13

when i needed to make myself useful i'd whip out some computer skills

jethroksy07:01:14

oracledb with eclipse modules lol

micha07:01:23

but mostly i didn't tell anyone i knew about computers simple_smile

jaen07:01:28

Oh God, Oracle D :

jethroksy07:01:45

could probably get charged with treason if i share too much

jethroksy07:01:07

cold booting took about 4 hours

jethroksy07:01:39

haha its always good to pretend not to know stuff

micha07:01:47

especially in the army

jethroksy07:01:00

I guess I never really had that choice

jethroksy07:01:10

one-man deployments

jethroksy07:01:45

they caught me reading the joy of clojure after automating everything

jethroksy07:01:50

then that was it for me

micha07:01:14

subversive samisdat

jaen07:01:39

Well, you can at least be sure the university won't make you a bad programmer, if you already know a sensible progtamming language before heading there : V

jaen07:01:56

Hmm, why didn't java -jar just work in your case? You had to run more processes than just one? Or just not using standalone webserver?

jethroksy07:01:57

I'm studying local because I plan on starting something this year hopefully

jethroksy07:01:09

standalone web server

jethroksy07:01:23

National University of Singapore though

jethroksy07:01:33

not sure how reputable it is overseas

jethroksy07:01:41

but apparently its rather prestigious

jaen07:01:53

Ah, so using immutant for example should make your life easier.

jethroksy07:01:25

does it work with boot-http?

jaen07:01:31

I used it in the repo I linked and as you can see running the app was basically a java -jar plus bunch of Java opts.

jethroksy07:01:49

hmm i'll give it a shot

jaen07:01:50

Well, you don't really need boot-http in general then.

jaen07:01:10

I mean, that depends on what you're doing as well.

jethroksy07:01:14

just need it to run the main function i guess

micha07:01:45

oh sure @crisptrutski no problem

jaen07:01:53

Yeah, so you basically can just have some (start-webserver!) function you can call from -main and from REPL that runs immutant - something like`(defn start-webserver! [](immutant/webrun your-handler {:port 4242}))`.

micha07:01:16

i want to make bootlaces simpler, maybe time for beaking changes there

micha07:01:39

it makes a lot of assumptions

crisptrutski07:01:50

wondering if task-options! shouldn’t just get some CLI-set-ability in boot itself though

crisptrutski07:01:56

via an -o task or env vars

micha07:01:32

how would that be different than just giving options to the tasks?

crisptrutski07:01:44

for setting options on tasks called indirectly

micha07:01:46

oh like if the task isn't called directly

jaen07:01:53

As for universities - NUS can just as well be a good university. I'm probably a bit too soured by having only Pascal, C, C++ and Java on mine and professors mistaking structural programming for FP, because it has you know, functions '

micha07:01:04

seems like this may indicate some other problem though

crisptrutski07:01:08

in boot-cljs-test i end up passing a lot of options on to boot-cljs, would be nice if those knobs were “free"

micha07:01:17

we just need to design the bootlaces api better i think

micha07:01:52

also the push task has too many options

micha07:01:03

now i think that it would have been better to have a separate check task

jethroksy07:01:04

i think mine is worse in that it only offers C, C++ and Java

micha07:01:17

or validate or something

jethroksy07:01:41

we have too many foreign scholars spoiling the market too

jethroksy07:01:57

the courses are too standard

jaen07:01:02

Well, that first semester of Pascal was a waste, so you lose nothing of value.

jethroksy07:01:14

I did take part in IOI

jethroksy07:01:24

so i got to take the year 3 course

jaen07:01:24

But not having any FP on a university? It is a shame. Good thing you took care of that by yourself though ;' )

jethroksy07:01:38

it was challenging so I'm kinda looking forward to that

jethroksy07:01:50

but that's year 3...

jaen07:01:10

I've got saved from being imperatively rotten to the core by a friend who knew Haskell (in his first semester, no less).

jethroksy07:01:32

I really wanna learn Idris actually

jaen07:01:42

Wow, CS olympics. Hats off. I'm probably not smart enough for that.

jethroksy07:01:46

but that requires some degree of knowledge of haskell as a transition

jethroksy07:01:04

and i've been doing too much language hopping

jethroksy07:01:22

its really not that hard, especially when your country's population is so small

jaen07:01:09

If you want to learn Haskell http://haskellbook.com is awesome. And I don't think language hopping is all that bad either - you get to learn more perspectives on programming.

jaen07:01:31

And to be more ono-topic: one thing you could look into (when you start doing more complex things) is using some sort of components - libs like component/mount/bounce.

jaen07:01:05

Developing applications with reloadable workflow using https://github.com/danielsz/system is pretty cool.

jethroksy07:01:19

system has immutant so i might use it

jaen07:01:36

Though I'm not sure I like how component pushes you in a more OO-way of writing code, but I didn't yet have chance to try mount or bounce.

jethroksy07:01:52

OO isn't particularly bad

jaen07:01:59

Well, writing a component for immutant is about ~15 lines of code, so it doesn't buy you much.

jethroksy07:01:03

its alright if approached correctly

jaen07:01:16

The best thing of that is the system boot task, which gets you this whole reloadable workflow.

jethroksy07:01:43

component requires a full buy-in though

jethroksy07:01:01

so its not easy to integrate into existing apps

jaen07:01:30

Mount or bounce seem to be an answer to that concern, so I hope to be able to try them in the future.

jaen07:01:55

Well, I don't really like OO because IMO most of the problems it solves are problems that arise from mutability an imperativeness and they can be resolved differently, without requiring objects.

jaen07:01:01

But the problem with OO-ness of component

jaen07:01:19

Is that in Clojure it results in two choices that are equally awkward

jaen07:01:29

Either you have to write all your code inside defrecord which makes you basically write an awkward lispy Java or write free-standign functions, but have to pass the system around and destructure it all the time.

jaen07:01:57

Mount and bounce seems to be better in that regard since they don't force you to use records.

jethroksy08:01:13

have yet to see what bounce does

jaen08:01:56

If you're interested in looking at it later - https://github.com/jarohen/bounce

jaen08:01:30

It grew out of his previous library, which was monadic, but handling monads in Clojure is considerably more awkward than in Haskell, so he decided to simplify it IIRC.

micha08:01:15

boot tasks achieve the same thing, in my experience

micha08:01:23

especially the bounce thing

jaen08:01:47

Interesting. How so?

micha08:01:10

like running a boot pipeline in the repl

micha08:01:26

there is the cleanup macro that is the equivalent of being "closeable"

micha08:01:41

and the scope and all that happens automatically because of the way boot works

micha08:01:21

you can run your pipeline in a future so it's in the background and bring it back to the foreground by derefing

micha08:01:50

when you press ctrl-c in the repl it ends the pipeline, which cleans up after itself

jaen08:01:54

But how would that work exactly? Would I write a database task that creates a database connection and an application task that creates the application that depends on the database?

micha08:01:56

and you can then run it again

jaen08:01:59

Unless I'm misunderstanding something?

jaen08:01:04

Ah, you mean the reloadable part only.

micha08:01:11

you could, yes

micha08:01:45

i generally don't like that way of doing things, but it's certainly possible

jaen08:01:56

Hm, I must say I can't really wrap my head around how this could work. But this could be an interesting example of how flexible boot is.

jethroksy08:01:57

my task is defined as follows:

(deftask run []
  (comp
   (with-pre-wrap fileset
     (edubot.core/-main)
     fileset)
   (wait)))

jethroksy08:01:27

and I have the barebones immutant stuff up:

(ns edubot.core
  (:gen-class)
  (:require [immutant.web :as web]))

(defn app [request]
  {:status 200
   :body "Hello world!"})

(defn -main []
  (web/run app))

jethroksy08:01:01

but i get an error when doing boot run

jethroksy08:01:20

clojure.lang.ExceptionInfo: edubot.core
    data: {:file
           "/var/folders/z2/tkdntvps3z9fyvhxq34gdhkw0000gn/T/boot.user5287752172357405327.clj",
           :line 7}
java.lang.ClassNotFoundException: edubot.core
               ...
boot.main/-main/fn     main.clj: 169
   boot.main/-main     main.clj: 169
               ...
  boot.App.runBoot     App.java: 361
     boot.App.main     App.java: 441
               ...
  boot.Loader.main  Loader.java: 253

jethroksy08:01:21

oh wait i probably forgot to require it in build.boot

jethroksy08:01:50

ah ok it works sry for spam

jaen08:01:43

No problem, though won't that break when the pipeline re-runs? You don't seem to stop the server so the port will be taken.

jethroksy08:01:24

that's my dev task so i just stop it with Ctrl - C

jethroksy08:01:41

it seems ok to rerun though

jaen08:01:40

Interesting. I thought it would contend on the port if you used watch in pipeline or something.

jethroksy08:01:25

tbh i'm shamefully unfamiliar with boot internals

jethroksy08:01:04

when things break i just bash at it

jaen08:01:23

Hah, I'm not much aware how boot works internally exactly either.

jethroksy08:01:25

clojure is sort of a serious hobby langauge, haven't been using it for long

jaen08:01:37

BTW if you're not using component or something right now, you might be interested in run-dmc - http://immutant.org/documentation/current/apidoc/immutant.web.html#var-run-dmc - it gets you some semblance of reloadability

micha08:01:42

most tasks are designed to be used in that way

micha08:01:54

like they clean up after themselves when the pipeline is killed

micha08:01:10

and they don't do things multiple times if they're run more than once in a pipeline

micha08:01:16

unless they're supposed to of course

micha08:01:24

so like servers you start with a delay

micha08:01:31

which you deref in the task body

micha08:01:43

and you stop the server in the cleanup expression

jethroksy08:01:07

good to know!

micha08:01:12

like boot-jetty, if you run it from the repl

micha08:01:22

you can kill it and you'll see it shut itself down

micha08:01:27

so you can then start it again

micha08:01:00

that's the public api thing for it

micha08:01:11

that other function is not part of the api

jaen08:01:11

Oh, I see, that's interesting. TIL

micha08:01:18

that's basically how i do my reloaded workflow

micha08:01:26

just delay and cleanup

micha08:01:33

and tasks of course

micha08:01:53

it's useful because they have control over the classpath transactionally too, via the fileset

micha08:01:49

so when you kill the pipline you are back to a clean classpath

micha08:01:36

pods are destroyed and recreated with a fresh clojure runtime when you start the pipeline again

micha08:01:57

that boot-jetty task is a little unusual in that the pod is created inside the with-pre-wrap scope

micha08:01:08

that's a workaround for a different issue

socksy09:01:23

if i replace the exec with echo, I get something like java -Dboot.app.path=/home/ben/rpm/rpm2/scripts/head.sh -jar ./head.sh, where the ben/rpm/ blah blah is the path where i put the file

socksy09:01:41

(also, wrt. bash, I have it with /usr/bin/env bash, it's just that nixos doesn't put anything in /bin apart from sh. Everything goes in its own sha hashed path)

alandipert13:01:31

@socksy: head.sh gets appended to boot.jar during build

alandipert13:01:03

boot.sh is mostly a jar, with that at the front. it's a jar that can exec itself

socksy13:01:03

yes, but what's it supposed to return?

alandipert14:01:02

it returns 0 on success, 1 on error - do you mean something else by return?

alandipert14:01:30

btw i believe @onetom is a heavy nix user who might be able to help

socksy22:01:46

i meant what is eval'd, as if you take that script and run it with "echo" instead of eval

socksy22:01:57

and good to know, thanks simple_smile

micha22:01:10

@socksy: that function i linked to the is-shebang? one

micha22:01:43

that's where boot decides whether it's running in a shebang script or as boot ...

socksy22:01:55

i think that's probably where it's failing then. That function returns nil for me

micha23:01:43

@socksy: if you can see where it's going wrong i can include a fix with the next release