{"id":20738805,"url":"https://github.com/ebean-orm/ebean-test-containers","last_synced_at":"2025-09-15T06:14:12.368Z","repository":{"id":39877033,"uuid":"102172860","full_name":"ebean-orm/ebean-test-containers","owner":"ebean-orm","description":"Ability to control docker containers. e.g. Postgres running as docker container for testing ","archived":false,"fork":false,"pushed_at":"2025-04-14T09:26:07.000Z","size":637,"stargazers_count":5,"open_issues_count":1,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-24T02:08:48.984Z","etag":null,"topics":["clickhouse","cockroachdb","database","db2","docker","hana","java","localdynamodb","localstack","mariadb","mysql","nuodb","oracle","postgres","sqlserver","test","test-containers","yugabyte"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ebean-orm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-09-02T04:36:37.000Z","updated_at":"2025-04-14T09:26:11.000Z","dependencies_parsed_at":"2023-11-06T09:28:06.338Z","dependency_job_id":"8724e715-8457-41df-a623-27d4cbd35efd","html_url":"https://github.com/ebean-orm/ebean-test-containers","commit_stats":null,"previous_names":[],"tags_count":79,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebean-orm%2Febean-test-containers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebean-orm%2Febean-test-containers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebean-orm%2Febean-test-containers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebean-orm%2Febean-test-containers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ebean-orm","download_url":"https://codeload.github.com/ebean-orm/ebean-test-containers/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250546081,"owners_count":21448260,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clickhouse","cockroachdb","database","db2","docker","hana","java","localdynamodb","localstack","mariadb","mysql","nuodb","oracle","postgres","sqlserver","test","test-containers","yugabyte"],"created_at":"2024-11-17T06:20:44.815Z","updated_at":"2025-09-15T06:14:12.356Z","avatar_url":"https://github.com/ebean-orm.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![ebean-test-containers EA](https://github.com/ebean-orm/ebean-test-containers/actions/workflows/jdk-ea.yml/badge.svg)](https://github.com/ebean-orm/ebean-test-containers/actions/workflows/jdk-ea.yml)\n[![Maven Central](https://img.shields.io/maven-central/v/io.ebean/ebean-test-containers.svg?label=Maven%20Central)](https://mvnrepository.com/artifact/io.ebean/ebean-test-containers)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/ebean/ebean-test-containers/blob/master/LICENSE)\n\n# ebean-test-containers\nAbility to start, setup and remove docker containers. e.g. Postgres running as docker container for testing.\n\nThe issues this solves for us is to:\n- Start containers and wait for them to be ready\n- Setup containers, e.g. create databases, users, schemas, run scripts as needed\n- Cleanup containers on JVM shutdown or explicitly (stop, remove containers)\n\n\nThe needs of this project are primarily driven by the needs/desires of using docker\ncontainers to make testing nice for Ebean ORM, see https://ebean.io/docs/testing/\n\n\n## Supported Containers\n\nPostgres, ClickHouse, CockroachDB, DB2, ElasticSearch, Hana, LocalDynamoDB, Localstack, MariaDB, MySql, NuoDB, Oracle, Postgres, Redis, SqlServer, Yugabyte.\n\n## Dependency\n\n```xml\n\n  \u003cdependency\u003e\n    \u003cgroupId\u003eio.ebean\u003c/groupId\u003e\n    \u003cartifactId\u003eebean-test-containers\u003c/artifactId\u003e\n    \u003cversion\u003e7.13\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n  \u003c/dependency\u003e\n\n```\n\nNote: Was previously `io.ebean:ebean-test-docker` and before that `org.avaje.docker:docker-commands`.\n\n## `docker.host` system property\n\nebean-test-container will set a system property for `docker.host` to be either `localhost`,\n`172.17.0.1` or `host.docker.internal` as appropriate depending on if it is running docker-in-docker.\n\nWe can then use this in configuration as necessary, for example in a jdbc url like:\n`jdbc:postgresql://${docker.host}:6432/my_test`\n\n## Designed for fast testing\n\nAs developers, we want testing to be fast, we want to be able to run even a single test and for that to be fast.\n\nFor a CI environment speed is less of a factor, CI doesn't mind waiting for docker containers to start etc.\n\nebean-test-docker is designed such that for developers we keep the docker containers running, and even reuse the same\ndocker container for multiple projects. We do this by:\n\n- Having a unique dbName per project\n- Having a ~/.ebean/ignore-docker-shutdown marker file on our development machines (but not in CI environment)\n\n### Unique dbName\n\nThe `dbName` should be unique across projects. For example, \"my_app1\", \"my_app2\", \"my_app3\".\n\nThis allows us to use the same database container to test multiple applications. We want to do this so that\ntesting is really fast for developers as we no longer drop/create/start/setup containers for each test run.\n\nThe dbName needs to be a valid database name so please just use alpha and underscores and no\nspecial characters. For example, with Postgres it needs to be a valid postgres database name.\n\n```java\n    PostgresContainer container = PostgresContainer.builder(\"17\")\n      .dbName(\"my_app1\") // this needs to be unique, not clash with other projects\n      .start();\n\n```\n\nDatabase containers can create an Ebean DatabaseBuilder and also a DataSourceBuilder.\nFor full programmatic test setup like:\n```java\n  PostgresContainer container = PostgresContainer.builder(\"17\")\n    .dbName(\"my_app1\") // this needs to be unique, not clash with other projects\n    .start();\n\n  DatabaseBuilder ebeanBuilder = container.ebean().builder();\n  Database ebeanDatabase = ebeanBuilder.build();\n```\n\nSome containers like Redis, Localstack, LocalDynamoDB, ElasticSearch, ClickHouse do not have a concept\nlike \"database\" and instead multiple projects share a global namespace.\n\nIn this way, we either need to make sure our resources (DynamoDB tables, queues, topics etc) are\nunique across projects or NOT share containers across projects.\n\n\n### Marker file - `~/.ebean/ignore-docker-shutdown`\n\nThe presence of the marker file tells ebean-test-docker that we are running as a **Developer** and not **CI**.\n\nThis means, please don't stop/remove the containers at the end of testing but instead leave the container running.\nIn this way testing for developers is faster as most frequently ebean-test-dockers only needs to check that the\ncontainer is running and that the database is setup and good to go (database/user/schema).\n\n\n#### For developers running tests\n\nHaving the `~/.ebean/ignore-docker-shutdown` marker file tells ebean-test-docker you are a Developer machine\nand not CI.\n\nFor developers running tests, ebean-test-docker checks if the container is running and only has to start it if\nit is not running. It will then create the database/user/schema in that container if necessary. Typically, this\nmeans that to run a test ebean-test-docker only needs to do a quick check that the container is up and the database\nis setup and ready for testing.\n\nThe `~/.ebean/ignore-docker-shutdown` marker file means that by default it will not stop/remove the container at the\nend of testing. It will leave the container there for the next test run.\n\n\n#### For CI running tests\n\nFor CI running tests, it typically needs to start the container, wait for it to be ready, create the database/user/schema.\nThen hand off to run all tests. Then on JVM shutdown stop the container and remove the container (cleanup).\n\nIn this way, running tests in CI is going to be slower but that is generally expected and OK.\n\nAlso note that CI will often also run as Docker-In-Docker and ebean-test-docker handles that case.\n\n\n\n## Programmatic use\nWe can programmatically create the containers. Typically we need to:\n1. Create the container\n2. Start the container\n\nTypically, we don't need to explicitly stop/remove the container. Instead, the container stop/remove defaults to\noccurring automatically on JVM shutdown.\n\n#### Postgres\n\n```java\n\n    PostgresContainer container = PostgresContainer.builder(\"14\")\n      //.containerName(\"ut_postgres\")\n      //.port(6423)\n      .dbName(\"my_app1\")\n      .extensions(\"hstore,pgcrypto\")\n      .start();\n\n```\n... a more extensive example:\n\n```java\n\n    PostgresContainer container = PostgresContainer.builder(\"14\")\n      .dbName(\"my_app2\")\n      .containerName(\"temp_postgres14\")\n      .port(9823)\n      .extensions(\"hstore,pgcrypto\")\n      .user(\"main_user\")\n      .dbName(\"main_db\")\n      .initSqlFile(\"init-main-database.sql\")\n      .seedSqlFile(\"seed-main-database.sql\")\n      // with a second extra database\n      .extraDb(\"extra\")\n      .extraDbInitSqlFile(\"init-extra-database.sql\")\n      .extraDbSeedSqlFile(\"seed-extra-database.sql\")\n      .start();\n\n```\n\n#### SqlServer\n\n```java\n\n    SqlServerContainer container = SqlServerContainer.builder(SQLSERVER_VER)\n      .dbName(\"my_third_app\")\n      .collation(\"SQL_Latin1_General_CP1_CS_AS\")\n      // .containerName(\"ut_sqlserver\")\n      // .port(1433)\n      .start();\n\n```\n\n\n#### Localstack - `localstack/localstack`\n\n```java\n    LocalstackContainer container = LocalstackContainer.builder(\"0.14\")\n      .services(\"dynamodb,kinesis,sns,sqs\")\n      //.awsRegion(\"ap-southeast-2\")\n      //.port(4566)\n      //.image(\"localstack/localstack:0.14\")\n      .start();\n\n    // obtain what we need ...\n    AmazonDynamoDB amazonDynamoDB = container.dynamoDB();\n    AmazonKinesis kinesis = container.kinesis();\n    AmazonSNS sns = container.sns();\n    AmazonSQS sqs = container.sqs();\n\n    // setup - create dynamoDB tables, queues etc\n\n```\n\n#### LocalDynamoDB - `amazon/dynamodb-local`\n\n```java\n\n    LocalDynamoDBContainer container = LocalDynamoDBContainer.builder(\"1.13.2\")\n      //.port(8001)\n      //.containerName(\"ut_dynamodb\")\n      //.image(\"amazon/dynamodb-local:1.13.2\")\n      .start();\n\n    // obtain the AWS DynamoDB client\n    AmazonDynamoDB amazonDynamoDB = container.dynamoDB();\n    createTable(amazonDynamoDB);\n\n```\n\n#### MySql\n\n```java\n\n    MySqlContainer container = MySqlContainer.builder(MYSQL_VER)\n      //.containerName(\"ut_mysql\")\n      //.port(4306)\n      .dbName(\"my_app4\")\n      .characterSet(\"utf8mb4\")\n      .collation(\"utf8mb4_unicode_ci\")\n      .start();\n\n```\n\n#### MariaDB\n\n```java\n    MariaDBContainer container = MariaDBContainer.builder(\"latest\")\n      .dbName(\"my_app5\")\n      //.port(4306)\n      .start();\n\n```\n\n#### ElasticSearch\n\n```java\n    ElasticContainer container = ElasticContainer.builder(\"5.6.0\")\n      .start();\n\n```\n\n#### Redis\n\n```java\n    RedisContainer container = RedisContainer.builder(\"latest\")\n      .start();\n\n```\n\n#### Oracle\n\n```java\n  OracleContainer container = OracleContainer.builder(\"latest\")\n    .user(\"my_unique_user\")\n    .stopMode(StopMode.NONE)\n    .start();\n\n```\n\n\n#### DB2\n\n```java\n    Db2Container container = Db2Container.builder(\"11.5.4.0\")\n      .dbName(\"my_app6\")\n      .port(50050)\n      .start();\n\n```\n\n#### Hana\n\n```java\n  // TODO ...\n```\n\n\n#### Clickhouse\n\n```java\n  ClickHouseContainer container = ClickHouseContainer.builder(\"latest\")\n    .start();\n\n```\n\n#### Yugabyte\n\n```java\n    YugabyteContainer container = YugabyteContainer.builder(\"2.11.2.0-b89\")\n      //.port(6433)\n      .dbName(\"my_app7\")\n      .extensions(\"pgcrypto\")\n      .start();\n\n```\n\n## Ebean ORM use\n\nRefer to the ebean testing documentation (https://ebean.io/docs/testing/) ...\nwhere we use ebean-test to hook into the Ebean lifecycle and automatically\nstart the docker containers as needed (prior to running tests etc).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Febean-orm%2Febean-test-containers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Febean-orm%2Febean-test-containers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Febean-orm%2Febean-test-containers/lists"}