Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b843f39
feat: Implements Docker container operations and tests.
gustavofreze Nov 27, 2024
9355f14
feat: Implements Docker container operations and tests.
gustavofreze Nov 27, 2024
322dc6c
feat: Implements Docker container operations and tests.
gustavofreze Nov 27, 2024
ef85987
feat: Implements Docker container operations and tests.
gustavofreze Nov 27, 2024
f4f7d88
feat: Implements Docker container operations and tests.
gustavofreze Nov 27, 2024
34f250d
feat: Implements Docker container operations and tests.
gustavofreze Nov 27, 2024
1e29ac6
feat: Implements Docker container operations and tests.
gustavofreze Nov 28, 2024
aa8bf66
feat: Implements Docker container operations and tests.
gustavofreze Nov 28, 2024
ef061a3
feat: Implements Docker container operations and tests.
gustavofreze Nov 28, 2024
cdac864
feat: Implements Docker container operations and tests.
gustavofreze Nov 28, 2024
159ab43
feat: Implements Docker container operations and tests.
gustavofreze Nov 29, 2024
1a65e65
feat: Implements Docker container operations and tests.
gustavofreze Nov 29, 2024
ac21152
feat: Implements Docker container operations and tests.
gustavofreze Nov 29, 2024
c8f3369
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
22c7f88
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
7af2658
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
9fabf48
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
8cf3eba
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
e3811ba
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
c4a1f7f
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
0202766
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
a97c8af
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
f3053e1
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
cb9cba6
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
dc4ca5b
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
16df6ff
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
cca9677
feat: Implements Docker container operations and tests.
gustavofreze Nov 30, 2024
647e2aa
feat: Implements Docker container operations and tests.
gustavofreze Dec 1, 2024
2b0c94c
feat: Implements Docker container operations and tests.
gustavofreze Dec 1, 2024
aa64e3b
feat: Implements Docker container operations and tests.
gustavofreze Dec 1, 2024
719bad1
feat: Implements Docker container operations and tests.
gustavofreze Dec 1, 2024
8828d2a
feat: Implements Docker container operations and tests.
gustavofreze Dec 1, 2024
35d57a0
feat: Implements Docker container operations and tests.
gustavofreze Dec 1, 2024
b3dd784
feat: Implements Docker container operations and tests.
gustavofreze Dec 1, 2024
c74954e
feat: Implements Docker container operations and tests.
gustavofreze Dec 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/tests export-ignore
/vendor export-ignore

/LICENSE export-ignore
/Makefile export-ignore
/README.md export-ignore
/phpmd.xml export-ignore
/phpunit.xml export-ignore
/phpstan.neon.dist export-ignore
/infection.json.dist export-ignore

/.github export-ignore
/.gitignore export-ignore
/.gitattributes export-ignore
22 changes: 22 additions & 0 deletions .github/workflows/auto-assign.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Auto assign issues

on:
issues:
types:
- opened

jobs:
run:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- name: Assign issues
uses: gustavofreze/auto-assign@1.0.0
with:
assignees: '${{ secrets.ASSIGNEES }}'
github_token: '${{ secrets.GITHUB_TOKEN }}'
allow_self_assign: 'true'
allow_no_assignees: 'true'
assignment_options: 'ISSUE'
62 changes: 62 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: CI

on:
push:
pull_request:

env:
PHP_VERSION: '8.3'

jobs:
auto-review:
name: Auto review
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Configure PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ env.PHP_VERSION }}

- name: Install dependencies
run: composer update --no-progress --optimize-autoloader

- name: Run review
run: composer review

tests:
name: Tests
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Configure PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ env.PHP_VERSION }}

- name: Install dependencies
run: composer update --no-progress --optimize-autoloader

- name: Clean up Docker
run: docker system prune -f

- name: Create Docker network
run: docker network create tiny-blocks

- name: Create Docker volume for migrations
run: docker volume create migrations

- name: Run tests
run: |
docker run --network=tiny-blocks \
-v ${PWD}:/app \
-v ${PWD}/tests/Integration/Database/Migrations:/migrations \
-v /var/run/docker.sock:/var/run/docker.sock \
-w /app \
gustavofreze/php:${{ env.PHP_VERSION }} bash -c "composer tests"
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.idea

/vendor/
/report
*.lock
.phpunit.*
31 changes: 31 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
DOCKER_RUN = docker run -u root --rm -it --network=tiny-blocks --name test-lib -v ${PWD}:/app -v ${PWD}/tests/Integration/Database/Migrations:/migrations -v /var/run/docker.sock:/var/run/docker.sock -w /app gustavofreze/php:8.3

.PHONY: configure test unit-test test-no-coverage create-volume create-network review show-reports clean

configure:
@${DOCKER_RUN} composer update --optimize-autoloader

test: create-volume
@${DOCKER_RUN} composer tests

unit-test:
@${DOCKER_RUN} composer run unit-test

test-no-coverage: create-volume
@${DOCKER_RUN} composer tests-no-coverage

create-network:
@docker network create tiny-blocks

create-volume:
@docker volume create migrations

review:
@${DOCKER_RUN} composer review

show-reports:
@sensible-browser report/coverage/coverage-html/index.html

clean:
@sudo chown -R ${USER}:${USER} ${PWD}
@rm -rf report vendor .phpunit.cache
235 changes: 233 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,233 @@
# docker-container
Manage Docker containers programmatically, simplifying the creation, running, and interaction with containers.
# Docker container

[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)

* [Overview](#overview)
* [Installation](#installation)
* [How to use](#how-to-use)
* [Creating a container](#creating-a-container)
* [Running a container](#running-a-container)
* [Running a container if it doesn't exist](#running-a-container-if-it-doesnt-exist)
* [Setting network](#setting-network)
* [Setting port mappings](#setting-port-mappings)
* [Setting volumes mappings](#setting-volumes-mappings)
* [Setting environment variables](#setting-environment-variables)
* [Disabling auto-remove](#disabling-auto-remove)
* [Copying files to a container](#copying-files-to-a-container)
* [Waiting for a condition](#waiting-for-a-condition)
* [Usage examples](#usage-examples)
* [License](#license)
* [Contributing](#contributing)

<div id='overview'></div>

## Overview

The `DockerContainer` library provides an interface and implementations to manage Docker containers programmatically.
It simplifies the creation, execution, and interaction with containers, such as adding network configurations, mapping
ports, setting environment variables, and executing commands inside containers.
Designed specifically to support **unit tests** and **integration tests**, the library enables developers to simulate
and manage containerized environments with minimal effort, ensuring a seamless testing workflow.

<div id='installation'></div>

## Installation

```bash
composer require tiny-blocks/docker-container
```

<div id='how-to-use'></div>

## How to use

### Creating a container

Creates a container from a specified image and optionally a name.
The `from` method can be used to initialize a new container instance with an image and an optional name for
identification.

```php
$container = GenericDockerContainer::from(image: 'php:8.3-fpm', name: 'my-container');
```

### Running a container

The `run` method starts a container.
Optionally, it allows you to execute commands within the container after it has started and define a condition to wait
for using a `ContainerWaitAfterStarted` instance.

**Example with no commands or conditions:**

```php
$container->run();
```

**Example with commands only:**

```php
$container->run(commands: ['ls', '-la']);
```

**Example with commands and a wait condition:**

```php
$container->run(commands: ['ls', '-la'], waitAfterStarted: ContainerWaitForTime::forSeconds(seconds: 5));
```

### Running a container if it doesn't exist

The `runIfNotExists` method starts a container only if it doesn't already exist.
Optionally, it allows you to execute commands within the container after it has started and define a condition to wait
for using a `ContainerWaitAfterStarted` instance.

```php
$container->runIfNotExists();
```

**Example with commands only:**

```php
$container->runIfNotExists(commands: ['ls', '-la']);
```

**Example with commands and a wait condition:**

```php
$container->runIfNotExists(commands: ['ls', '-la'], waitAfterStarted: ContainerWaitForTime::forSeconds(seconds: 5));
```

### Setting network

The `withNetwork` method connects the container to a specified Docker network by name, allowing you to define the
network configuration the container will use.

```php
$container->withNetwork(name: 'my-network');
```

### Setting port mappings

Maps ports between the host and the container.
The `withPortMapping` method maps a port from the host to a port inside the container.

```php
$container->withPortMapping(portOnHost: 9000, portOnContainer: 9000);
```

### Setting volumes mappings

Maps a volume from the host to the container.
The `withVolumeMapping` method allows you to link a directory from the host to the container.

```php
$container->withVolumeMapping(pathOnHost: '/path/on/host', pathOnContainer: '/path/in/container');
```

### Setting environment variables

Sets environment variables inside the container.
The `withEnvironmentVariable` method allows you to configure environment variables within the container.

```php
$container->withEnvironmentVariable(key: 'XPTO', value: '123');
```

### Disabling auto-remove

Prevents the container from being automatically removed when stopped.
By default, Docker removes containers after they stop.
The `withoutAutoRemove` method disables this feature, keeping the container around even after it finishes its
execution.

```php
$container->withoutAutoRemove();
```

### Copying files to a container

Copies files or directories from the host machine to the container.
The `copyToContainer` method allows you to transfer files from the host system into the container’s file system.

```php
$container->copyToContainer(pathOnHost: '/path/to/files', pathOnContainer: '/path/in/container');
```

### Waiting for a condition

The `withWaitBeforeRun` method allows the container to pause its execution until a specified condition is met before
starting.

```php
$container->withWaitBeforeRun(wait: ContainerWaitForDependency::untilReady(condition: MySQLReady::from(container: $container)));
```

<div id='usage-examples'></div>

## Usage examples

### MySQL and Generic Containers

The MySQL container is configured and started:

```php
$mySQLContainer = MySQLDockerContainer::from(image: 'mysql:8.1', name: 'test-database')
->withNetwork(name: 'tiny-blocks')
->withTimezone(timezone: 'America/Sao_Paulo')
->withUsername(user: 'xpto')
->withPassword(password: '123')
->withDatabase(database: 'test_adm')
->withPortMapping(portOnHost: 3306, portOnContainer: 3306)
->withRootPassword(rootPassword: 'root')
->withVolumeMapping(pathOnHost: '/var/lib/mysql', pathOnContainer: '/var/lib/mysql')
->withoutAutoRemove()
->runIfNotExists();
```

With the MySQL container started, it is possible to retrieve data, such as the address and JDBC connection URL:

```php
$jdbcUrl = $mySQLContainer->getJdbcUrl(options: 'useUnicode=yes&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&useSSL=false');
$database = $environmentVariables->getValueBy(key: 'MYSQL_DATABASE');
$username = $environmentVariables->getValueBy(key: 'MYSQL_USER');
$password = $environmentVariables->getValueBy(key: 'MYSQL_PASSWORD');
```

The Flyway container is configured and only starts and executes migrations after the MySQL container is **ready**:

```php
$flywayContainer = GenericDockerContainer::from(image: 'flyway/flyway:11.0.0')
->withNetwork(name: 'tiny-blocks')
->copyToContainer(pathOnHost: '/migrations', pathOnContainer: '/flyway/sql')
->withVolumeMapping(pathOnHost: '/migrations', pathOnContainer: '/flyway/sql')
->withWaitBeforeRun(
wait: ContainerWaitForDependency::untilReady(
condition: MySQLReady::from(
container: $mySQLContainer
)
)
)
->withEnvironmentVariable(key: 'FLYWAY_URL', value: $jdbcUrl)
->withEnvironmentVariable(key: 'FLYWAY_USER', value: $username)
->withEnvironmentVariable(key: 'FLYWAY_TABLE', value: 'schema_history')
->withEnvironmentVariable(key: 'FLYWAY_SCHEMAS', value: $database)
->withEnvironmentVariable(key: 'FLYWAY_EDITION', value: 'community')
->withEnvironmentVariable(key: 'FLYWAY_PASSWORD', value: $password)
->withEnvironmentVariable(key: 'FLYWAY_LOCATIONS', value: 'filesystem:/flyway/sql')
->withEnvironmentVariable(key: 'FLYWAY_CLEAN_DISABLED', value: 'false')
->withEnvironmentVariable(key: 'FLYWAY_VALIDATE_MIGRATION_NAMING', value: 'true')
->run(commands: ['-connectRetries=15', 'clean', 'migrate']);
```

<div id='license'></div>

## License

Docker container is licensed under [MIT](LICENSE).

<div id='contributing'></div>

## Contributing

Please follow the [contributing guidelines](https://github.com/tiny-blocks/tiny-blocks/blob/main/CONTRIBUTING.md) to
contribute to the project.
Loading