From f868dc19d4e25a5ffc5611542b8760ea3a08e110 Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Tue, 18 Apr 2017 22:02:29 +0200 Subject: [PATCH 1/7] Build uberjar in Dockerfile --- Dockerfile | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Dockerfile b/Dockerfile index 74e4c48..9b35824 100644 --- a/Dockerfile +++ b/Dockerfile @@ -97,6 +97,15 @@ RUN cd a2png && npm install COPY a2png /app/a2png RUN cd a2png && lein cljsbuild once main && lein cljsbuild once page +# build uberjar + +COPY project.clj /app/ +RUN lein deps + +COPY src /app/src +COPY resources /app/resources +RUN lein uberjar + # copy the rest of the source code COPY . /app From 70fd5608f613b0700719f1e0bf536d73dc3aff43 Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Tue, 18 Apr 2017 23:36:10 +0200 Subject: [PATCH 2/7] Use DATABASE_URL compatible with PostgreSQL JDBC driver --- .env.production.sample | 2 +- Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.production.sample b/.env.production.sample index 4ee2faa..d7b5055 100644 --- a/.env.production.sample +++ b/.env.production.sample @@ -12,7 +12,7 @@ BASE_URL=http://localhost:3000 SECRET_KEY_BASE= ## PostgreSQL connection URL. -## Default: postgresql://postgres@postgres/postgres +## Default: postgresql://postgres/postgres?user=postgres # DATABASE_URL= ## Redis connection URL. diff --git a/Dockerfile b/Dockerfile index 9b35824..7c68b0e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -110,7 +110,7 @@ RUN lein uberjar COPY . /app -ENV DATABASE_URL "postgresql://postgres@postgres/postgres" +ENV DATABASE_URL "postgresql://postgres/postgres?user=postgres" ENV REDIS_URL "redis://redis:6379" # compile terminal.c From a3feeb6454bee3276ded5c8e3d573d3bde849ff2 Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Tue, 18 Apr 2017 23:57:02 +0200 Subject: [PATCH 3/7] Use :uri instead of :host/:port as :spec for carmine --- resources/asciinema/system.edn | 3 +-- src/asciinema/component/redis_client.clj | 8 ++++---- src/asciinema/main.clj | 3 +-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/resources/asciinema/system.edn b/resources/asciinema/system.edn index aa5b2c8..5948b61 100644 --- a/resources/asciinema/system.edn +++ b/resources/asciinema/system.edn @@ -25,8 +25,7 @@ :bucket s3-bucket :path-prefix "uploads/"} :exp-set - {:host redis-host - :port redis-port} + {:uri redis-url} :png-gen {:bin-path a2png-bin-path} :executor diff --git a/src/asciinema/component/redis_client.clj b/src/asciinema/component/redis_client.clj index 07af0f6..da725a4 100644 --- a/src/asciinema/component/redis_client.clj +++ b/src/asciinema/component/redis_client.clj @@ -5,12 +5,12 @@ [com.stuartsierra.component :as component] [taoensso.carmine :as car])) -(defrecord RedisClient [host port] +(defrecord RedisClient [uri] component/Lifecycle (start [component] (if (:listener component) component - (let [conn {:pool {} :spec {:host host :port port}}] + (let [conn {:pool {} :spec {:uri uri}}] (assoc component :conn conn)))) (stop [component] (if (:conn component) @@ -24,5 +24,5 @@ (contains? [this value] (car/as-bool (car/wcar (:conn this) (car/exists value))))) -(defn redis-client [{:keys [host port]}] - (->RedisClient host port)) +(defn redis-client [{:keys [uri]}] + (->RedisClient uri)) diff --git a/src/asciinema/main.clj b/src/asciinema/main.clj index 7eecb3e..1248443 100644 --- a/src/asciinema/main.clj +++ b/src/asciinema/main.clj @@ -32,8 +32,7 @@ 's3-bucket (:s3-bucket env) 's3-access-key (:s3-access-key env) 's3-secret-key (:s3-secret-key env) - 'redis-host (:redis-host env "localhost") - 'redis-port (Integer/parseInt (:redis-port env "6379")) + 'redis-url (:redis-url env "redis://localhost") 'a2png-bin-path (:a2png-bin-path env "a2png/a2png.sh")} system (->> (load-system [(io/resource "asciinema/system.edn")] bindings) (component/start))] From 155bd3d36a6fa7d7223b3646cfc39b811adaf678 Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Tue, 18 Apr 2017 23:58:41 +0200 Subject: [PATCH 4/7] auto-file-store constructor for auto-detecting store type based on config keys --- dev/resources/dev.edn | 5 +---- resources/asciinema/system.edn | 10 +++++----- src/asciinema/component/auto_file_store.clj | 8 ++++++++ src/asciinema/component/s3_file_store.clj | 4 ++-- 4 files changed, 16 insertions(+), 11 deletions(-) create mode 100644 src/asciinema/component/auto_file_store.clj diff --git a/dev/resources/dev.edn b/dev/resources/dev.edn index cf8c240..0545cb2 100644 --- a/dev/resources/dev.edn +++ b/dev/resources/dev.edn @@ -1,12 +1,9 @@ {:components - {:file-store #var asciinema.component.local-file-store/local-file-store - :exp-set #var asciinema.component.mem-expiring-set/mem-expiring-set} + {:exp-set #var asciinema.component.mem-expiring-set/mem-expiring-set} :config {:http {:port 4000} :db {:uri "jdbc:postgresql://localhost:15432/asciinema_development?user=vagrant"} - :file-store - {:path "uploads/"} :png-gen {:bin-path "a2png/a2png.sh"}}} diff --git a/resources/asciinema/system.edn b/resources/asciinema/system.edn index 5948b61..b7df1cc 100644 --- a/resources/asciinema/system.edn +++ b/resources/asciinema/system.edn @@ -2,7 +2,7 @@ {:http #var asciinema.component.yada-listener/yada-listener :db #var asciinema.component.db/hikaricp :ragtime #var duct.component.ragtime/ragtime - :file-store #var asciinema.component.s3-file-store/s3-file-store + :file-store #var asciinema.component.auto-file-store/auto-file-store :exp-set #var asciinema.component.redis-client/redis-client :png-gen #var asciinema.component.a2png/a2png :executor #var asciinema.component.fixed-thread-executor/fixed-thread-executor} @@ -20,10 +20,10 @@ :ragtime {:resource-path "asciinema/migrations"} :file-store - {:cred {:access-key s3-access-key - :secret-key s3-secret-key} - :bucket s3-bucket - :path-prefix "uploads/"} + {:path "uploads/" + :s3-bucket s3-bucket + :s3-cred {:access-key s3-access-key + :secret-key s3-secret-key}} :exp-set {:uri redis-url} :png-gen diff --git a/src/asciinema/component/auto_file_store.clj b/src/asciinema/component/auto_file_store.clj new file mode 100644 index 0000000..e674537 --- /dev/null +++ b/src/asciinema/component/auto_file_store.clj @@ -0,0 +1,8 @@ +(ns asciinema.component.auto-file-store + (:require [asciinema.component.local-file-store :refer [local-file-store]] + [asciinema.component.s3-file-store :refer [s3-file-store]])) + +(defn auto-file-store [config] + (if (:s3-bucket config) + (s3-file-store config) + (local-file-store config))) diff --git a/src/asciinema/component/s3_file_store.clj b/src/asciinema/component/s3_file_store.clj index 3443dd0..8beec5c 100644 --- a/src/asciinema/component/s3_file_store.clj +++ b/src/asciinema/component/s3_file_store.clj @@ -60,5 +60,5 @@ (assoc :status 302) (update :headers assoc "location" url))))) -(defn s3-file-store [{:keys [cred bucket path-prefix]}] - (->S3FileStore cred bucket path-prefix)) +(defn s3-file-store [{:keys [s3-cred s3-bucket path]}] + (->S3FileStore s3-cred s3-bucket path)) From 41139dcb8b8760111a91ef67998b2a2c92cc2255 Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Tue, 18 Apr 2017 23:59:20 +0200 Subject: [PATCH 5/7] Run Clojure server on port 4000 so it doesn't collide with Rails server --- src/asciinema/main.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/asciinema/main.clj b/src/asciinema/main.clj index 1248443..a283b17 100644 --- a/src/asciinema/main.clj +++ b/src/asciinema/main.clj @@ -27,7 +27,7 @@ (defn -main [& args] (binding [y/*exception-notifier* (create-exception-notifier)] - (let [bindings {'http-port (Integer/parseInt (:port env "3000")) + (let [bindings {'http-port (Integer/parseInt (:port env "4000")) 'db-uri (:database-url env) 's3-bucket (:s3-bucket env) 's3-access-key (:s3-access-key env) From 3e2bb2682eec4e13506f9dd0edc49e39e1f31bf6 Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Wed, 19 Apr 2017 00:00:31 +0200 Subject: [PATCH 6/7] Start Clojure app in Supervisor --- Dockerfile | 5 +++++ docker/start.sh | 8 ++++++++ docker/supervisor/asciinema.conf | 8 ++++++++ 3 files changed, 21 insertions(+) create mode 100644 docker/start.sh diff --git a/Dockerfile b/Dockerfile index 7c68b0e..9549880 100644 --- a/Dockerfile +++ b/Dockerfile @@ -134,6 +134,11 @@ COPY docker/nginx/asciinema.conf /etc/nginx/sites-available/default RUN mkdir -p /var/log/supervisor COPY docker/supervisor/asciinema.conf /etc/supervisor/conf.d/asciinema.conf +# add start script for Clojure app + +COPY docker/start.sh /app/start.sh +RUN chmod a+x /app/start.sh + VOLUME ["/app/log", "/app/uploads"] CMD ["/usr/bin/supervisord"] diff --git a/docker/start.sh b/docker/start.sh new file mode 100644 index 0000000..be59cea --- /dev/null +++ b/docker/start.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +export DATABASE_URL=jdbc:${DATABASE_URL} +export S3_ACCESS_KEY=${AWS_ACCESS_KEY_ID} +export S3_SECRET_KEY=${AWS_SECRET_ACCESS_KEY} +export A2PNG_BIN_PATH="/app/a2png/a2png.sh" + +exec java -server -Xmx3g -jar /app/target/uberjar/asciinema-0.1.0-SNAPSHOT-standalone.jar diff --git a/docker/supervisor/asciinema.conf b/docker/supervisor/asciinema.conf index 0857a41..0dd20d4 100644 --- a/docker/supervisor/asciinema.conf +++ b/docker/supervisor/asciinema.conf @@ -14,4 +14,12 @@ directory=/app stdout_logfile=/dev/stdout stdout_logfile_maxbytes=0 stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 + +[program:clj] +command=/app/start.sh +directory=/app +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr stderr_logfile_maxbytes=0 \ No newline at end of file From b987effc8932ead4f66e5c4315f0f4a61741f4be Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Wed, 19 Apr 2017 00:00:48 +0200 Subject: [PATCH 7/7] Route .json and .png requests to Clojure app --- docker/nginx/asciinema.conf | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docker/nginx/asciinema.conf b/docker/nginx/asciinema.conf index 6e92331..2b8c371 100644 --- a/docker/nginx/asciinema.conf +++ b/docker/nginx/asciinema.conf @@ -2,6 +2,10 @@ upstream rails-server { server 127.0.0.1:3000 fail_timeout=0; } +upstream clj-server { + server 127.0.0.1:4000 fail_timeout=0; +} + server { listen 80 default_server; listen [::]:80 default_server; @@ -12,6 +16,10 @@ server { client_max_body_size 16m; + location ~ ^/a/[^.]+\.(json|png)$ { + try_files $uri $uri/index.html $uri.html @clj; + } + location / { try_files $uri $uri/index.html $uri.html @rails; } @@ -33,4 +41,13 @@ server { proxy_redirect off; error_page 500 502 504 /500.html; # Rails error pages } + + location @clj { + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Host $http_host; + proxy_pass http://clj-server; + proxy_redirect off; + } }