Skip to content

Instantly share code, notes, and snippets.

@achinaou
Last active October 31, 2025 14:00
Show Gist options
  • Select an option

  • Save achinaou/7f72397be84a38a2eb921d2a0827603c to your computer and use it in GitHub Desktop.

Select an option

Save achinaou/7f72397be84a38a2eb921d2a0827603c to your computer and use it in GitHub Desktop.
PostgreSQL Test Container ZIO Layer
import java.sql.Connection
import javax.sql.DataSource
import org.postgresql.ds.PGSimpleDataSource
import org.testcontainers.containers.PostgreSQLContainer as OriginalPostgreSQLContainer
import zio.Scope
import zio.ZIO
import zio.ZLayer
class PostgreSQLContainer(dockerImageName: String)
extends OriginalPostgreSQLContainer[PostgreSQLContainer](dockerImageName)
object PostgreSQLContainer:
val latest: ZLayer[Any, Nothing, DataSource & Connection] =
withTag("latest")
val latestAlpine: ZLayer[Any, Nothing, DataSource & Connection] =
withTag("alpine")
def withTag(tag: String): ZLayer[Any, Nothing, DataSource & Connection] =
ZLayer.scoped(containerResource(tag)) >>> ZLayer(dataSourceResource) >+> ZLayer.scoped(connectionResource)
private def containerResource(tag: String): ZIO[Scope, Nothing, PostgreSQLContainer] =
ZIO
.succeed(PostgreSQLContainer(s"postgres:$tag"))
.withFinalizerAuto
.tap(container => ZIO.attemptBlocking(container.start))
.orDie
private def dataSourceResource: ZIO[PostgreSQLContainer, Nothing, DataSource] =
ZIO
.serviceWithZIO[PostgreSQLContainer]: container =>
ZIO.attemptBlocking:
new PGSimpleDataSource:
setUrl(container.getJdbcUrl)
setUser(container.getUsername)
setPassword(container.getPassword)
.orDie
private def connectionResource: ZIO[Scope & DataSource, Nothing, Connection] =
ZIO.serviceWithZIO[DataSource](dataSource => ZIO.attemptBlocking(dataSource.getConnection)).withFinalizerAuto.orDie
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment