aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2023-03-23 16:49:48 +0000
committers-ol <s+removethis@s-ol.nu>2023-03-23 16:49:48 +0000
commit9ddad13146307e964d34291b2cfd7cddbdc77e44 (patch)
treebf115fe12dea8ecdedbb00363cd6aa2ecdd7e431
parentremove debug printing (diff)
downloadelectric-sudoku-9ddad13146307e964d34291b2cfd7cddbdc77e44.tar.gz
electric-sudoku-9ddad13146307e964d34291b2cfd7cddbdc77e44.zip
add Dockerfile, build support
-rw-r--r--.dockerignore13
-rw-r--r--.gitignore1
-rw-r--r--Dockerfile26
-rw-r--r--README.md17
-rw-r--r--deps.edn21
-rw-r--r--resources/public/index.html2
-rw-r--r--shadow-cljs.edn8
-rw-r--r--src-build/build.clj59
-rw-r--r--src/app/sudoku.cljc3
-rw-r--r--src/prod.clj12
-rw-r--r--src/user.clj4
-rw-r--r--src/user.cljs2
12 files changed, 152 insertions, 16 deletions
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..59d20c8
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,13 @@
+**/node_modules
+**/resources/public/js
+**/.cpcache
+**/.shadow-cljs
+**/.nrepl-port
+**/.clj-kondo/.cache
+**/yarn-error.log
+**/report.html
+**/.idea/*
+!**/.idea/ClojureProjectResolveSettings.xml
+**/*.iml
+**/.lsp
+**/.clj-kondo
diff --git a/.gitignore b/.gitignore
index 37bf3d3..addfd6f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,4 @@ report.html
*.iml
.lsp
.clj-kondo
+/target
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..6c39f1e
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,26 @@
+FROM clojure:openjdk-11-tools-deps AS clojure-deps
+WORKDIR /app
+COPY deps.edn deps.edn
+COPY src-build src-build
+RUN clojure -A:dev -M -e :ok # preload deps
+RUN clojure -T:build noop # preload build deps
+
+FROM clojure:openjdk-11-tools-deps AS build
+WORKDIR /app
+COPY --from=clojure-deps /root/.m2 /root/.m2
+COPY shadow-cljs.edn shadow-cljs.edn
+COPY deps.edn deps.edn
+COPY src src
+COPY src-build src-build
+COPY resources resources
+ARG REBUILD=unknown
+ARG VERSION
+RUN clojure -X:build uberjar :jar-name "app.jar" :verbose true :version '"'$VERSION'"'
+
+FROM amazoncorretto:11 AS app
+WORKDIR /app
+COPY --from=build /app/app.jar app.jar
+EXPOSE 8080
+ARG VERSION
+ENV VERSION=$VERSION
+CMD java -DHYPERFIDDLE_ELECTRIC_VERSION=$VERSION -jar app.jar
diff --git a/README.md b/README.md
index dcb60c0..f1289df 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ Multiplayer Sudoku in [<150 LOC](https://github.com/s-ol/electric-sudoku/blob/ma
https://user-images.githubusercontent.com/124158/220984721-bd0960da-8d05-49e1-b9b3-a948e942bfc8.mp4
-# Setup
+# Setup (development)
```
$ clj -A:dev -X user/main
@@ -19,3 +19,18 @@ shadow-cljs - nREPL server started on port 9001
👉 App server available at http://0.0.0.0:8080
```
+
+# Building
+
+For a manual JAR deployment:
+
+```
+$ clj -X:build build-client # release-mode JS client build
+$ clj -X:build uberjar # server jar build (cleans & builds client)
+```
+
+or to create a Docker image:
+
+```
+$ docker build --build-arg VERSION=`git describe ...` -t electric-sudoku .
+```
diff --git a/deps.edn b/deps.edn
index 5c3a869..c160c93 100644
--- a/deps.edn
+++ b/deps.edn
@@ -1,6 +1,6 @@
-{:paths ["src"]
+{:paths ["src" "resources"]
:deps {ch.qos.logback/logback-classic {:mvn/version "1.2.11"}
- com.hyperfiddle/electric {:mvn/version "v2-alpha-60-g4cb70086"}
+ com.hyperfiddle/electric {:mvn/version "v2-alpha-167-gbd475584"}
com.hyperfiddle/rcf {:mvn/version "20220926-202227"}
info.sunng/ring-jetty9-adapter {:mvn/version "0.14.3"
:exclusions [org.slf4j/slf4j-api
@@ -16,10 +16,15 @@
thheller/shadow-cljs {:mvn/version "2.20.1"}}
:jvm-opts
["-Xss2m" ; https://github.com/hyperfiddle/photon/issues/11
- "-Dclojure.tools.logging.factory=clojure.tools.logging.impl/slf4j-factory"
- "-Dlogback.configurationFile=src/logback.xml"
- "-XX:-OmitStackTraceInFastThrow" ;; RCF
- "-XX:+UnlockDiagnosticVMOptions"
- "-XX:+DebugNonSafepoints"]
+ "-XX:-OmitStackTraceInFastThrow"] ;; RCF
:exec-fn user/main
- :exec-args {}}}}
+ :exec-args {}}
+ :build
+ {:extra-paths ["src-build"]
+ :ns-default build
+ :extra-deps {io.github.clojure/tools.build {:git/tag "v0.8.2" :git/sha "ba1a2bf"}
+ io.github.seancorfield/build-clj {:git/tag "v0.8.0" :git/sha "9bd8b8a"}
+ thheller/shadow-cljs {:mvn/version "2.20.1"}}
+ :jvm-opts ["-Xss2m"
+ "-Dclojure.tools.logging.factory=clojure.tools.logging.impl/slf4j-factory"
+ "-Dlogback.configurationFile=src-dev/logback_dev.xml"]}}}
diff --git a/resources/public/index.html b/resources/public/index.html
index 1cce040..598c38d 100644
--- a/resources/public/index.html
+++ b/resources/public/index.html
@@ -8,6 +8,6 @@
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
- <script type="text/javascript" src="/js/main.js"></script>
+ <script type="text/javascript" src="$:hyperfiddle.client.module/main$"></script>
</body>
</html>
diff --git a/shadow-cljs.edn b/shadow-cljs.edn
index e5bf366..50a37a9 100644
--- a/shadow-cljs.edn
+++ b/shadow-cljs.edn
@@ -9,4 +9,10 @@
:modules {:main {:entries [user]
:init-fn user/start!}}
:build-hooks [(shadow.cljs.build-report/hook {:output-to "target/build_report.html"})
- (user/rcf-shadow-hook)]}}}
+ (user/rcf-shadow-hook)]}
+ :prod {:target :browser
+ :output-dir "resources/public/js"
+ :asset-path "/js"
+ :module-hash-names true
+ :modules {:main {:entries [user]
+ :init-fn user/start!}}}}}
diff --git a/src-build/build.clj b/src-build/build.clj
new file mode 100644
index 0000000..3abc8a8
--- /dev/null
+++ b/src-build/build.clj
@@ -0,0 +1,59 @@
+(ns build
+ "build electric.jar library artifact and demos"
+ (:require [clojure.tools.build.api :as b]
+ [org.corfield.build :as bb]
+ [shadow.cljs.devtools.api :as shadow-api] ; so as not to shell out to NPM for shadow
+ [shadow.cljs.devtools.server :as shadow-server]))
+
+
+(def lib 'com.hyperfiddle/electric)
+(def version (b/git-process {:git-args "describe --tags --long --always --dirty"}))
+(def basis (b/create-basis {:project "deps.edn"}))
+
+(defn clean [opts]
+ (bb/clean opts))
+
+(def class-dir "target/classes")
+(defn default-jar-name [{:keys [version] :or {version version}}]
+ (format "target/%s-%s-standalone.jar" (name lib) version))
+
+(defn clean-cljs [_]
+ (b/delete {:path "resources/public/js"}))
+
+(defn build-client [{:keys [optimize debug verbose version]
+ :or {optimize true, debug false, verbose false, version version}}]
+ (println "Building client. Version:" version)
+ (shadow-server/start!)
+ (shadow-api/release :prod {:debug debug,
+ :verbose verbose,
+ :config-merge [{:compiler-options {:optimizations (if optimize :advanced :simple)}
+ :closure-defines {'hyperfiddle.electric-client/VERSION version}}]})
+ (shadow-server/stop!))
+
+(defn uberjar [{:keys [jar-name version optimize debug verbose]
+ :or {version version, optimize true, debug false, verbose false}}]
+ (println "Cleaning up before build")
+ (clean nil)
+
+ (println "Cleaning cljs compiler output")
+ (clean-cljs nil)
+
+ (build-client {:optimize optimize, :debug debug, :verbose verbose, :version version})
+
+ (println "Bundling sources")
+ (b/copy-dir {:src-dirs ["src" "resources"]
+ :target-dir class-dir})
+
+ (println "Compiling server. Version:" version)
+ (b/compile-clj {:basis basis
+ :src-dirs ["src"]
+ :ns-compile '[prod]
+ :class-dir class-dir})
+
+ (println "Building uberjar")
+ (b/uber {:class-dir class-dir
+ :uber-file (str (or jar-name (default-jar-name {:version version})))
+ :basis basis
+ :main 'prod}))
+
+(defn noop [_]) ; run to preload mvn deps
diff --git a/src/app/sudoku.cljc b/src/app/sudoku.cljc
index db70c1b..2137bba 100644
--- a/src/app/sudoku.cljc
+++ b/src/app/sudoku.cljc
@@ -1,6 +1,5 @@
(ns app.sudoku
- #?(:cljs (:require-macros app.sudoku)
- :clj (:import [de.sfuhrm.sudoku Creator]))
+ #?(:clj (:import [de.sfuhrm.sudoku Creator]))
(:require [hyperfiddle.electric :as e]
[hyperfiddle.electric-dom2 :as dom]
diff --git a/src/prod.clj b/src/prod.clj
new file mode 100644
index 0000000..9b34b57
--- /dev/null
+++ b/src/prod.clj
@@ -0,0 +1,12 @@
+(ns prod
+ (:gen-class)
+ (:require app.sudoku ; in prod, load app into server so it can accept clients
+ hyperfiddle.electric-jetty-server))
+
+(def electric-server-config
+ {:host "0.0.0.0", :port 8080, :resources-path "public"})
+
+(defn -main [& args]
+ (hyperfiddle.electric-jetty-server/start-server! electric-server-config))
+
+; On CLJS side we reuse src/user.cljs for prod entrypoint
diff --git a/src/user.clj b/src/user.clj
index 9419d04..9c6cb68 100644
--- a/src/user.clj
+++ b/src/user.clj
@@ -6,7 +6,7 @@
(def shadow-watch (delay @(requiring-resolve 'shadow.cljs.devtools.api/watch)))
(def electric-server-config
- {:host "0.0.0.0", :port 8080, :resources-path "resources/public"})
+ {:host "0.0.0.0", :port 8080, :resources-path "public"})
(defn main [& args]
(println "Starting Electric compiler and server...")
@@ -25,4 +25,4 @@
(shadow.cljs.devtools.api/repl :dev) ; shadow server hosts the cljs repl
; connect a second REPL instance to it
; (DO NOT REUSE JVM REPL it will fail weirdly)
- (type 1)) \ No newline at end of file
+ (type 1))
diff --git a/src/user.cljs b/src/user.cljs
index d1b96fb..b590060 100644
--- a/src/user.cljs
+++ b/src/user.cljs
@@ -1,4 +1,4 @@
-(ns user ^:dev/always ; recompile (macroexpand) electric-main when any cljs src changes
+(ns ^:dev/always user ; recompile (macroexpand) electric-main when any cljs src changes
(:require
app.sudoku
hyperfiddle.electric