All Projects → j5ik2o → docker-controller-scala

j5ik2o / docker-controller-scala

Licence: MIT license
No description or website provided.

Programming Languages

scala
5932 projects

Projects that are alternatives of or similar to docker-controller-scala

hot-reload
Hot reload development for Go
Stars: ✭ 72 (+500%)
Mutual labels:  docker-container
irsync
rsync on interval, via command line binary or docker container. Server and IOT builds for pull or push based device content management.
Stars: ✭ 19 (+58.33%)
Mutual labels:  docker-container
nftables-example
A playground ruleset to get to know nftables syntax
Stars: ✭ 19 (+58.33%)
Mutual labels:  docker-container
dockermutillidae
Docker container for OWASP Mutillidae II Web Pen-Test Practice Application
Stars: ✭ 64 (+433.33%)
Mutual labels:  docker-container
knime-docker
KNIME Analytics Platform & SDK with Docker Container in X11 desktop
Stars: ✭ 19 (+58.33%)
Mutual labels:  docker-container
pycroft
The new AG DSN management system
Stars: ✭ 16 (+33.33%)
Mutual labels:  docker-container
essex
Essex - Boilerplate for Docker Based Projects
Stars: ✭ 32 (+166.67%)
Mutual labels:  docker-container
ssh-agent-inject
[Note: Not needed with VS Code anymore.] Forwards the host's ssh-agent into a Docker container on Windows and macOS hosts.
Stars: ✭ 20 (+66.67%)
Mutual labels:  docker-container
docker-elk-stack
The ELK stack Docker containerization (Elasticsearch, Logstash and Kibana)
Stars: ✭ 20 (+66.67%)
Mutual labels:  docker-container
dockerfiles
A collection of Docker recipes.
Stars: ✭ 31 (+158.33%)
Mutual labels:  docker-container
graphsense-dashboard
A web dashboard for interactive cryptocurrency analysis.
Stars: ✭ 84 (+600%)
Mutual labels:  docker-container
techno-broadlink
A Docker container for BroadLink devices with a REST API and React UI
Stars: ✭ 57 (+375%)
Mutual labels:  docker-container
multi-site-docker
A multi-site-docker configuration featuring nginx, php and mysql
Stars: ✭ 85 (+608.33%)
Mutual labels:  docker-container
docker-tcp-switchboard
Launch a fresh docker container per SSH connection
Stars: ✭ 44 (+266.67%)
Mutual labels:  docker-container
yupe-docker
Yupe! CMF in Docker containers
Stars: ✭ 15 (+25%)
Mutual labels:  docker-container
docker-phpdev
Easy to use php docker development environment setup with vhost/multi version support
Stars: ✭ 75 (+525%)
Mutual labels:  docker-container
scan-cli-plugin
Docker Scan is a Command Line Interface to run vulnerability detection on your Dockerfiles and Docker images
Stars: ✭ 135 (+1025%)
Mutual labels:  docker-container
docker-lidarr-lad
Official docker for LAD bash enhancement script
Stars: ✭ 22 (+83.33%)
Mutual labels:  docker-container
network-tools
Network Tools
Stars: ✭ 27 (+125%)
Mutual labels:  docker-container
strider-docker-runner
Strider runner that uses Docker
Stars: ✭ 33 (+175%)
Mutual labels:  docker-container

docker-controller-scala

Actions Status: CI Scala Steward badge Maven Central License FOSSA Status

This library provides an easy and simple way to handle Docker Container or Docker Compose on ScalaTest, based on docker-java. The implementation of this library is thin, and if you know docker-java, your learning cost will be negligible.

Installation

Add the following to your sbt build (2.12.x, 2.13.x, 3.0.x):

val version = "..."

libraryDependencies += Seq(
  "com.github.j5ik2o" %% "docker-controller-scala-core" % version,
  "com.github.j5ik2o" %% "docker-controller-scala-scalatest" % version, // for scalatest
  // RDB
  "com.github.j5ik2o" %% "docker-controller-scala-mysql" % version, // optional
  "com.github.j5ik2o" %% "docker-controller-scala-postgresql" % version, // optional
  "com.github.j5ik2o" %% "docker-controller-scala-flyway" % version, // optional
  // NoSQL
  "com.github.j5ik2o" %% "docker-controller-scala-memcached" % version, // optional
  "com.github.j5ik2o" %% "docker-controller-scala-redis" % version, // optional
  "com.github.j5ik2o" %% "docker-controller-scala-elasticsearch" % version, // optional
  // Kafka
  "com.github.j5ik2o" %% "docker-controller-scala-zookeeper" % version, // optional
  "com.github.j5ik2o" %% "docker-controller-scala-kafka" % version, // optional
  // AWS Services
  "com.github.j5ik2o" %% "docker-controller-scala-dynamodb-local" % version, // optional
  "com.github.j5ik2o" %% "docker-controller-scala-minio" % version, // optional
  "com.github.j5ik2o" %% "docker-controller-scala-localstack" % version, // optional
  "com.github.j5ik2o" %% "docker-controller-scala-elasticmq" % version, // optional
)

In most cases, you can just select the scalatest module and the module you need.

libraryDependencies += Seq(
  "com.github.j5ik2o" %% "docker-controller-scala-scalatest" % version,
  "com.github.j5ik2o" %% "docker-controller-scala-mysql" % version,
)

Usage

DockerController that the thin wrapper for docker-java controls Docker Image and Docker Container for testing.

How to test with preset DockerController

The DockerController for the corresponding preset is as follows. Please see the corresponding **Spec for specific usage.

class MySQLControllerSpec extends AnyFreeSpec with DockerControllerSpecSupport {

  val hostPort: Int               = temporaryServerPort()
  val rootPassword: String        = "test"
  val dbName                      = "test"
  
  // MySQL
  val controller: MySQLController = MySQLController(dockerClient)(hostPort, rootPassword, databaseName = Some(dbName))

  // Specify DockerControllers to be launched.
  override protected val dockerControllers: Vector[DockerController] = Vector(controller)

  // Set the condition to wait for the container to be started.
  override protected val waitPredicatesSettings: Map[DockerController, WaitPredicateSetting] =
    Map(
      controller -> WaitPredicateSetting(
        Duration.Inf,
        WaitPredicates.forListeningHostTcpPort(
          dockerHost,
          hostPort,
          1.seconds,
          Some(3.seconds)
        )
      )
    )

  "MySQLController" - {
    "run" in {
      var conn: Connection     = null
      var stmt: Statement      = null
      var resultSet: ResultSet = null
      try {
        Class.forName("com.mysql.cj.jdbc.Driver")
        conn = DriverManager.getConnection(
          s"jdbc:mysql://$dockerHost:$hostPort/$dbName?user=root&password=$rootPassword"
        )
        stmt = conn.createStatement
        resultSet = stmt.executeQuery("SELECT 1 FROM DUAL")
        while (resultSet.next())
          assert(resultSet.getInt(1) == 1)
      } catch {
        case NonFatal(ex) =>
          fail("occurred error", ex)
      } finally {
        if (resultSet != null)
          resultSet.close()
        if (stmt != null)
          stmt.close()
        if (conn != null)
          conn.close()
      }
    }
  }
}

Use Flyway Migrate Command on MySQL/PostgreSQL

If you'd like to use flyway module, you can use docker-controller-scala-flyway.

libraryDependencies += Seq(
  "com.github.j5ik2o" %% "docker-controller-scala-scalatest" % version,
  "com.github.j5ik2o" %% "docker-controller-scala-mysql" % version,
  "com.github.j5ik2o" %% "docker-controller-scala-flyway" % version, // for flyway
)

Mix-in FlywaySpecSupport then, put the sql files in src/reosources/flyway(src/reosources/** can be set to any string.), run flywayContext.flyway.migrate() in afterStartContainers method.

class MySQLControllerSpec extends AnyFreeSpec with DockerControllerSpecSupport with FlywaySpecSupport {
  val testTimeFactor: Int = sys.env.getOrElse("TEST_TIME_FACTOR", "1").toInt
  logger.debug(s"testTimeFactor = $testTimeFactor")

  val hostPort: Int        = temporaryServerPort()
  val dbName: String.      = "test"
  val rootUserName: String = "root"
  val rootPassword: String = "test"

  override protected def flywayDriverClassName: String = classOf[com.mysql.cj.jdbc.Driver].getName
  override protected def flywayDbHost: String          = dockerHost
  override protected def flywayDbHostPort: Int         = hostPort
  override protected def flywayDbName: String          = dbName
  override protected def flywayDbUserName: String      = rootUserName
  override protected def flywayDbPassword: String      = rootPassword

  override protected def flywayJDBCUrl: String =
    s"jdbc:mysql://$flywayDbHost:$flywayDbHostPort/$flywayDbName?useSSL=false&user=$flywayDbUserName&password=$flywayDbPassword"

  val controller: MySQLController = MySQLController(dockerClient)(hostPort, rootPassword, databaseName = Some(dbName))
  
  override protected val dockerControllers: Vector[DockerController] = Vector(controller)

  override protected val waitPredicatesSettings: Map[DockerController, WaitPredicateSetting] =
    Map(
      controller -> WaitPredicateSetting(
        Duration.Inf,
        WaitPredicates.forListeningHostTcpPort(
          dockerHost,
          hostPort,
          (1 * testTimeFactor).seconds,
          Some((5 * testTimeFactor).seconds)
        )
      )
    )
  
  override protected def afterStartContainers(): Unit = {
    // Configure the sql files in `src/reosources/flyway`.
    val flywayContext = createFlywayContext(FlywayConfig(Seq("flyway")))
    // Execute flywayMigrate command
    flywayContext.flyway.migrate()
  }

  "MySQLController" - {
    "run" in {
      var conn: Connection     = null
      var stmt: Statement      = null
      var resultSet: ResultSet = null
      try {
        Class.forName(flywayDriverClassName)
        conn = DriverManager.getConnection(flywayJDBCUrl)
        stmt = conn.createStatement
        val result = stmt.executeUpdate("INSERT INTO users VALUES(1, 'kato')")
        assert(result == 1)
        resultSet = stmt.executeQuery("SELECT * FROM users")
        while (resultSet.next()) {
          val id   = resultSet.getInt("id")
          val name = resultSet.getString("name")
          println(s"id = $id, name = $name")
        }
      } catch {
        case NonFatal(ex) =>
          ex.printStackTrace()
          fail("occurred error", ex)
      } finally {
        if (resultSet != null)
          resultSet.close()
        if (stmt != null)
          stmt.close()
        if (conn != null)
          conn.close()
      }
    }
  }

}

How to test with DockerController your customized

To launch a docker container for testing

// In ScalaTest, please mix-in DockerControllerSpecSupport.
class NginxSpec extends AnyFreeSpec with DockerControllerSpecSupport {
  
  // choose whether to create and destroy containers per test class (ForAllTest) or per test (ForEachTest).
  override def createRemoveLifecycle: DockerContainerCreateRemoveLifecycle.Value =
    DockerContainerCreateRemoveLifecycle.ForEachTest

  // choose whether to start and stop containers per test class (ForAllTest) or per test (ForEachTest).
  override def startStopLifecycle: DockerContainerStartStopLifecycle.Value =
    DockerContainerStartStopLifecycle.ForEachTest
    
  val nginx: DockerController = DockerController(dockerClient)(
    imageName = "nginx",
    tag = Some("latest")
  ).configureCreateContainerCmd { cmd =>
    // if customize the container generation, please do the following.
    // In this example, a random host port is specified.
    val hostPort: Int              = temporaryServerPort()
    val containerPort: ExposedPort = ExposedPort.tcp(80)
    val portBinding: Ports         = new Ports()
    portBinding.bind(containerPort, Ports.Binding.bindPort(hostPort))
    logger.debug(s"hostPort = $hostPort, containerPort = $containerPort")
    cmd
      .withExposedPorts(containerPort)
      .withHostConfig(newHostConfig().withPortBindings(portBinding))
  }

  // Specify DockerControllers to be launched.
  override protected val dockerControllers: Vector[DockerController] = {
    Vector(nginx)
  }

  // Set the condition to wait for the container to be started.
  override protected val waitPredicatesSettings: Map[DockerController, WaitPredicateSetting] =
    Map(
      nginx -> WaitPredicateSetting(
        Duration.Inf,
        WaitPredicates.forLogMessageContained("Configuration complete; ready for start up")
      )
    )

  "nginx" - {
    "run-1" in {
      val hostPort = nginx.inspectContainer().getNetworkSettings.bindingHostPort(ExposedPort.tcp(80)).get
      val url      = new URL(s"http://$dockerHost:$hostPort")
      HttpRequestUtil.wget(url)
    }
    "run-2" in {
      val hostPort = nginx.inspectContainer().getNetworkSettings.bindingHostPort(ExposedPort.tcp(80)).get
      val url      = new URL(s"http://$dockerHost:$hostPort")
      HttpRequestUtil.wget(url)
    }
  }
}

How to use Docker Compose

  • Place the docker-compose.yml.ftl(ftl is Freemarker template) in src/test/resources. docker-compose.yml.ftl can be renamed to anything you want.
  • The variables in the ftl can be freely determined.
version: '3'
services:
  nginx:
    image: nginx
    ports:
      - ${nginxHostPort}:80
  • Use DockerComposeController, which is a subtype of DockerController. Other than this, it is the same as the test method above.
  • Pass the context containing the values of the variables to be used in the FTL to the constructor of DockerComposeController.
class NginxSpec extends AnyFreeSpec with DockerControllerSpecSupport {
// ...
  val buildDir: File                = ResourceUtil.getBuildDir(getClass)
  val dockerComposeWorkingDir: File = new File(buildDir, "docker-compose")
  val dockerController = DockerComposeController(dockerClient)(
    dockerComposeWorkingDir,
    "docker-compose.yml.ftl",
    Map("nginxHostPort" -> hostPort.toString)
  )

  override val dockerControllers: Vector[DockerController] = {
    Vector(dockerController)
  }
// ...
}     

License

FOSSA Status

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].