Merge pull request #61 from rr83019/docker

Docker support
This commit is contained in:
hrj 2021-04-01 11:49:52 +05:30 committed by GitHub
commit 7195e1cce8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 162 additions and 46 deletions

38
Dockerfile Normal file
View File

@ -0,0 +1,38 @@
FROM adoptopenjdk/openjdk16:alpine AS base-builder
ARG SBT_VERSION=1.3.13
RUN apk add --no-cache bash
ENV JAVA_HOME="/usr/lib/jvm/default-jvm/"
ENV PATH=$PATH:${JAVA_HOME}/bin
RUN \
wget -O sbt-$SBT_VERSION.tgz https://github.com/sbt/sbt/releases/download/v$SBT_VERSION/sbt-$SBT_VERSION.tgz && \
tar -xzvf sbt-$SBT_VERSION.tgz && \
rm sbt-$SBT_VERSION.tgz
ENV PATH=$PATH:/sbt/bin/
FROM base-builder AS sbt-builder
WORKDIR /build
COPY lib/ lib/
COPY project/plugins.sbt project/
COPY build.sbt .
RUN sbt assembly
FROM sbt-builder as builder
COPY src/ src/
RUN sbt assembly
FROM adoptopenjdk/openjdk16:alpine-jre AS base-core
ENV JAVA_HOME="/usr/lib/jvm/default-jvm/"
RUN apk add --update ttf-dejavu
ENV PATH=$PATH:${JAVA_HOME}/bin
FROM base-core
WORKDIR /lc-core
COPY --from=builder /build/target/scala-2.13/LibreCaptcha.jar .
RUN mkdir data/
EXPOSE 8888
CMD [ "java", "-jar", "LibreCaptcha.jar" ]

View File

@ -22,5 +22,8 @@ scalacOptions ++= List(
) )
javacOptions += "-g:none" javacOptions += "-g:none"
compileOrder := CompileOrder.JavaThenScala compileOrder := CompileOrder.JavaThenScala
mainClass in assembly := Some("lc.LCFramework")
mainClass in (Compile, run) := Some("lc.LCFramework")
assemblyJarName in assembly := "LibreCaptcha.jar"
fork in run := true fork in run := true

View File

@ -1,37 +0,0 @@
{
"randomSeed": 20,
"port": 8888,
"captchaExpiryTimeLimit": 5,
"threadDelay": 2,
"throttle": 10,
"captchas":[
{
"name": "FilterChallenge",
"allowedLevels":["medium", "hard"],
"allowedMedia":["image/png"],
"allowedInputType":["text"],
"config":{}
},
{
"name": "GifCaptcha",
"allowedLevels":["hard"],
"allowedMedia":["image/gif"],
"allowedInputType":["text"],
"config":{}
},
{
"name": "ShadowTextCaptcha",
"allowedLevels":["easy"],
"allowedMedia":["image/png"],
"allowedInputType":["text"],
"config": {}
},
{
"name": "RainDropsCaptcha",
"allowedLevels":["easy","medium"],
"allowedMedia":["image/gif"],
"allowedInputType":["text"],
"config":{}
}
]
}

32
data/config.json Normal file
View File

@ -0,0 +1,32 @@
{
"randomSeed" : 20,
"port" : 8888,
"captchaExpiryTimeLimit" : 5,
"throttle" : 10,
"threadDelay" : 2,
"captchas" : [ {
"name" : "FilterChallenge",
"allowedLevels" : [ "medium", "hard" ],
"allowedMedia" : [ "image/png" ],
"allowedInputType" : [ "text" ],
"config" : { }
}, {
"name" : "GifCaptcha",
"allowedLevels" : [ "hard" ],
"allowedMedia" : [ "image/gif" ],
"allowedInputType" : [ "text" ],
"config" : { }
}, {
"name" : "ShadowTextCaptcha",
"allowedLevels" : [ "easy" ],
"allowedMedia" : [ "image/png" ],
"allowedInputType" : [ "text" ],
"config" : { }
}, {
"name" : "RainDropsCaptcha",
"allowedLevels" : [ "easy", "medium" ],
"allowedMedia" : [ "image/gif" ],
"allowedInputType" : [ "text" ],
"config" : { }
} ]
}

11
docker-compose.yml Normal file
View File

@ -0,0 +1,11 @@
version: "3.8"
services:
lc-core:
container_name: "libre-captcha"
build: ./
image: librecapthca/lc-core:latest
volumes:
- "./docker-data:/lc-core/data"
ports:
- "8888:8888"

View File

@ -1,3 +1,4 @@
addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.25") addSbtPlugin("ch.epfl.scala" % "sbt-scalafix" % "0.9.25")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.0") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.0")
addSbtPlugin("com.lightbend.sbt" % "sbt-java-formatter" % "0.6.0") addSbtPlugin("com.lightbend.sbt" % "sbt-java-formatter" % "0.6.0")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.15.0")

View File

@ -10,6 +10,19 @@ object ParametersEnum extends Enumeration {
val ALLOWEDLEVELS: Value = Value("allowedLevels") val ALLOWEDLEVELS: Value = Value("allowedLevels")
val ALLOWEDMEDIA: Value = Value("allowedMedia") val ALLOWEDMEDIA: Value = Value("allowedMedia")
val ALLOWEDINPUTTYPE: Value = Value("allowedInputType") val ALLOWEDINPUTTYPE: Value = Value("allowedInputType")
}
object AttributesEnum extends Enumeration {
type Attribute = Value
val NAME: Value = Value("name")
val RANDOM_SEED: Value = Value("randomSeed")
val PORT: Value = Value("port")
val CAPTCHA_EXPIRY_TIME_LIMIT: Value = Value("captchaExpiryTimeLimit")
val THROTTLE: Value = Value("throttle")
val THREAD_DELAY: Value = Value("threadDelay")
val CONFIG: Value = Value("config")
} }
object ResultEnum extends Enumeration { object ResultEnum extends Enumeration {

View File

@ -2,23 +2,37 @@ package lc.core
import scala.io.Source.fromFile import scala.io.Source.fromFile
import org.json4s.{DefaultFormats, JValue, JObject, JField, JString} import org.json4s.{DefaultFormats, JValue, JObject, JField, JString}
import org.json4s.jackson.JsonMethods.parse import org.json4s.jackson.JsonMethods.{parse, render, pretty}
import org.json4s.JsonDSL._
import java.io.{FileNotFoundException, File, PrintWriter}
object Config { object Config {
implicit val formats: DefaultFormats.type = DefaultFormats implicit val formats: DefaultFormats.type = DefaultFormats
private val configFile = fromFile("config.json") private val configFilePath = "data/config.json"
private val configString = private val configString =
try configFile.mkString try {
finally configFile.close val configFile = fromFile(configFilePath)
val configFileContent = configFile.mkString
configFile.close
configFileContent
} catch {
case _: FileNotFoundException =>
val configFileContent = getDefaultConfig()
val configFile = new PrintWriter(new File(configFilePath))
configFile.write(configFileContent)
configFile.close
configFileContent
}
private val configJson = parse(configString) private val configJson = parse(configString)
val port: Int = (configJson \ "port").extract[Int] val port: Int = (configJson \ AttributesEnum.PORT.toString).extract[Int]
val throttle: Int = (configJson \ "throttle").extract[Int] val throttle: Int = (configJson \ AttributesEnum.THROTTLE.toString).extract[Int]
val seed: Int = (configJson \ "randomSeed").extract[Int] val seed: Int = (configJson \ AttributesEnum.RANDOM_SEED.toString).extract[Int]
val captchaExpiryTimeLimit: Int = (configJson \ "captchaExpiryTimeLimit").extract[Int] val captchaExpiryTimeLimit: Int = (configJson \ AttributesEnum.CAPTCHA_EXPIRY_TIME_LIMIT.toString).extract[Int]
val threadDelay: Int = (configJson \ "threadDelay").extract[Int] val threadDelay: Int = (configJson \ AttributesEnum.THREAD_DELAY.toString).extract[Int]
private val captchaConfigJson = (configJson \ "captchas") private val captchaConfigJson = (configJson \ "captchas")
val captchaConfigTransform: JValue = captchaConfigJson transformField { val captchaConfigTransform: JValue = captchaConfigJson transformField {
@ -45,4 +59,45 @@ object Config {
valueSet valueSet
} }
private def getDefaultConfig(): String = {
val defaultConfigMap =
(AttributesEnum.RANDOM_SEED.toString -> 20) ~
(AttributesEnum.PORT.toString -> 8888) ~
(AttributesEnum.CAPTCHA_EXPIRY_TIME_LIMIT.toString -> 5) ~
(AttributesEnum.THROTTLE.toString -> 10) ~
(AttributesEnum.THREAD_DELAY.toString -> 2) ~
("captchas" -> List(
(
(AttributesEnum.NAME.toString -> "FilterChallenge") ~
(ParametersEnum.ALLOWEDLEVELS.toString -> List("medium", "hard")) ~
(ParametersEnum.ALLOWEDMEDIA.toString -> List("image/png")) ~
(ParametersEnum.ALLOWEDINPUTTYPE.toString -> List("text")) ~
(AttributesEnum.CONFIG.toString -> JObject())
),
(
(AttributesEnum.NAME.toString -> "GifCaptcha") ~
(ParametersEnum.ALLOWEDLEVELS.toString -> List("hard")) ~
(ParametersEnum.ALLOWEDMEDIA.toString -> List("image/gif")) ~
(ParametersEnum.ALLOWEDINPUTTYPE.toString -> List("text")) ~
(AttributesEnum.CONFIG.toString -> JObject())
),
(
(AttributesEnum.NAME.toString -> "ShadowTextCaptcha") ~
(ParametersEnum.ALLOWEDLEVELS.toString -> List("easy")) ~
(ParametersEnum.ALLOWEDMEDIA.toString -> List("image/png")) ~
(ParametersEnum.ALLOWEDINPUTTYPE.toString -> List("text")) ~
(AttributesEnum.CONFIG.toString -> JObject())
),
(
(AttributesEnum.NAME.toString -> "RainDropsCaptcha") ~
(ParametersEnum.ALLOWEDLEVELS.toString -> List("easy", "medium")) ~
(ParametersEnum.ALLOWEDMEDIA.toString -> List("image/gif")) ~
(ParametersEnum.ALLOWEDINPUTTYPE.toString -> List("text")) ~
(AttributesEnum.CONFIG.toString -> JObject())
)
))
pretty(render(defaultConfigMap))
}
} }