Skip to content

Commit 172ed65

Browse files
authored
Feature/initial (#1)
* feat: Implements Docker container operations and tests.
1 parent 4c4a091 commit 172ed65

File tree

84 files changed

+3331
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+3331
-2
lines changed

.gitattributes

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/tests export-ignore
2+
/vendor export-ignore
3+
4+
/LICENSE export-ignore
5+
/Makefile export-ignore
6+
/README.md export-ignore
7+
/phpmd.xml export-ignore
8+
/phpunit.xml export-ignore
9+
/phpstan.neon.dist export-ignore
10+
/infection.json.dist export-ignore
11+
12+
/.github export-ignore
13+
/.gitignore export-ignore
14+
/.gitattributes export-ignore

.github/workflows/auto-assign.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: Auto assign issues
2+
3+
on:
4+
issues:
5+
types:
6+
- opened
7+
8+
jobs:
9+
run:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
issues: write
13+
pull-requests: write
14+
steps:
15+
- name: Assign issues
16+
uses: gustavofreze/[email protected]
17+
with:
18+
assignees: '${{ secrets.ASSIGNEES }}'
19+
github_token: '${{ secrets.GITHUB_TOKEN }}'
20+
allow_self_assign: 'true'
21+
allow_no_assignees: 'true'
22+
assignment_options: 'ISSUE'

.github/workflows/ci.yml

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
pull_request:
6+
7+
env:
8+
PHP_VERSION: '8.3'
9+
10+
jobs:
11+
auto-review:
12+
name: Auto review
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@v4
18+
19+
- name: Configure PHP
20+
uses: shivammathur/setup-php@v2
21+
with:
22+
php-version: ${{ env.PHP_VERSION }}
23+
24+
- name: Install dependencies
25+
run: composer update --no-progress --optimize-autoloader
26+
27+
- name: Run review
28+
run: composer review
29+
30+
tests:
31+
name: Tests
32+
runs-on: ubuntu-latest
33+
34+
steps:
35+
- name: Checkout
36+
uses: actions/checkout@v4
37+
38+
- name: Configure PHP
39+
uses: shivammathur/setup-php@v2
40+
with:
41+
php-version: ${{ env.PHP_VERSION }}
42+
43+
- name: Install dependencies
44+
run: composer update --no-progress --optimize-autoloader
45+
46+
- name: Clean up Docker
47+
run: docker system prune -f
48+
49+
- name: Create Docker network
50+
run: docker network create tiny-blocks
51+
52+
- name: Create Docker volume for migrations
53+
run: docker volume create migrations
54+
55+
- name: Run tests
56+
run: |
57+
docker run --network=tiny-blocks \
58+
-v ${PWD}:/app \
59+
-v ${PWD}/tests/Integration/Database/Migrations:/migrations \
60+
-v /var/run/docker.sock:/var/run/docker.sock \
61+
-w /app \
62+
gustavofreze/php:${{ env.PHP_VERSION }} bash -c "composer tests"

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.idea
2+
3+
/vendor/
4+
/report
5+
*.lock
6+
.phpunit.*

Makefile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
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
2+
3+
.PHONY: configure test unit-test test-no-coverage create-volume create-network review show-reports clean
4+
5+
configure:
6+
@${DOCKER_RUN} composer update --optimize-autoloader
7+
8+
test: create-volume
9+
@${DOCKER_RUN} composer tests
10+
11+
unit-test:
12+
@${DOCKER_RUN} composer run unit-test
13+
14+
test-no-coverage: create-volume
15+
@${DOCKER_RUN} composer tests-no-coverage
16+
17+
create-network:
18+
@docker network create tiny-blocks
19+
20+
create-volume:
21+
@docker volume create migrations
22+
23+
review:
24+
@${DOCKER_RUN} composer review
25+
26+
show-reports:
27+
@sensible-browser report/coverage/coverage-html/index.html
28+
29+
clean:
30+
@sudo chown -R ${USER}:${USER} ${PWD}
31+
@rm -rf report vendor .phpunit.cache

README.md

Lines changed: 233 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,233 @@
1-
# docker-container
2-
Manage Docker containers programmatically, simplifying the creation, running, and interaction with containers.
1+
# Docker container
2+
3+
[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)
4+
5+
* [Overview](#overview)
6+
* [Installation](#installation)
7+
* [How to use](#how-to-use)
8+
* [Creating a container](#creating-a-container)
9+
* [Running a container](#running-a-container)
10+
* [Running a container if it doesn't exist](#running-a-container-if-it-doesnt-exist)
11+
* [Setting network](#setting-network)
12+
* [Setting port mappings](#setting-port-mappings)
13+
* [Setting volumes mappings](#setting-volumes-mappings)
14+
* [Setting environment variables](#setting-environment-variables)
15+
* [Disabling auto-remove](#disabling-auto-remove)
16+
* [Copying files to a container](#copying-files-to-a-container)
17+
* [Waiting for a condition](#waiting-for-a-condition)
18+
* [Usage examples](#usage-examples)
19+
* [License](#license)
20+
* [Contributing](#contributing)
21+
22+
<div id='overview'></div>
23+
24+
## Overview
25+
26+
The `DockerContainer` library provides an interface and implementations to manage Docker containers programmatically.
27+
It simplifies the creation, execution, and interaction with containers, such as adding network configurations, mapping
28+
ports, setting environment variables, and executing commands inside containers.
29+
Designed specifically to support **unit tests** and **integration tests**, the library enables developers to simulate
30+
and manage containerized environments with minimal effort, ensuring a seamless testing workflow.
31+
32+
<div id='installation'></div>
33+
34+
## Installation
35+
36+
```bash
37+
composer require tiny-blocks/docker-container
38+
```
39+
40+
<div id='how-to-use'></div>
41+
42+
## How to use
43+
44+
### Creating a container
45+
46+
Creates a container from a specified image and optionally a name.
47+
The `from` method can be used to initialize a new container instance with an image and an optional name for
48+
identification.
49+
50+
```php
51+
$container = GenericDockerContainer::from(image: 'php:8.3-fpm', name: 'my-container');
52+
```
53+
54+
### Running a container
55+
56+
The `run` method starts a container.
57+
Optionally, it allows you to execute commands within the container after it has started and define a condition to wait
58+
for using a `ContainerWaitAfterStarted` instance.
59+
60+
**Example with no commands or conditions:**
61+
62+
```php
63+
$container->run();
64+
```
65+
66+
**Example with commands only:**
67+
68+
```php
69+
$container->run(commands: ['ls', '-la']);
70+
```
71+
72+
**Example with commands and a wait condition:**
73+
74+
```php
75+
$container->run(commands: ['ls', '-la'], waitAfterStarted: ContainerWaitForTime::forSeconds(seconds: 5));
76+
```
77+
78+
### Running a container if it doesn't exist
79+
80+
The `runIfNotExists` method starts a container only if it doesn't already exist.
81+
Optionally, it allows you to execute commands within the container after it has started and define a condition to wait
82+
for using a `ContainerWaitAfterStarted` instance.
83+
84+
```php
85+
$container->runIfNotExists();
86+
```
87+
88+
**Example with commands only:**
89+
90+
```php
91+
$container->runIfNotExists(commands: ['ls', '-la']);
92+
```
93+
94+
**Example with commands and a wait condition:**
95+
96+
```php
97+
$container->runIfNotExists(commands: ['ls', '-la'], waitAfterStarted: ContainerWaitForTime::forSeconds(seconds: 5));
98+
```
99+
100+
### Setting network
101+
102+
The `withNetwork` method connects the container to a specified Docker network by name, allowing you to define the
103+
network configuration the container will use.
104+
105+
```php
106+
$container->withNetwork(name: 'my-network');
107+
```
108+
109+
### Setting port mappings
110+
111+
Maps ports between the host and the container.
112+
The `withPortMapping` method maps a port from the host to a port inside the container.
113+
114+
```php
115+
$container->withPortMapping(portOnHost: 9000, portOnContainer: 9000);
116+
```
117+
118+
### Setting volumes mappings
119+
120+
Maps a volume from the host to the container.
121+
The `withVolumeMapping` method allows you to link a directory from the host to the container.
122+
123+
```php
124+
$container->withVolumeMapping(pathOnHost: '/path/on/host', pathOnContainer: '/path/in/container');
125+
```
126+
127+
### Setting environment variables
128+
129+
Sets environment variables inside the container.
130+
The `withEnvironmentVariable` method allows you to configure environment variables within the container.
131+
132+
```php
133+
$container->withEnvironmentVariable(key: 'XPTO', value: '123');
134+
```
135+
136+
### Disabling auto-remove
137+
138+
Prevents the container from being automatically removed when stopped.
139+
By default, Docker removes containers after they stop.
140+
The `withoutAutoRemove` method disables this feature, keeping the container around even after it finishes its
141+
execution.
142+
143+
```php
144+
$container->withoutAutoRemove();
145+
```
146+
147+
### Copying files to a container
148+
149+
Copies files or directories from the host machine to the container.
150+
The `copyToContainer` method allows you to transfer files from the host system into the container’s file system.
151+
152+
```php
153+
$container->copyToContainer(pathOnHost: '/path/to/files', pathOnContainer: '/path/in/container');
154+
```
155+
156+
### Waiting for a condition
157+
158+
The `withWaitBeforeRun` method allows the container to pause its execution until a specified condition is met before
159+
starting.
160+
161+
```php
162+
$container->withWaitBeforeRun(wait: ContainerWaitForDependency::untilReady(condition: MySQLReady::from(container: $container)));
163+
```
164+
165+
<div id='usage-examples'></div>
166+
167+
## Usage examples
168+
169+
### MySQL and Generic Containers
170+
171+
The MySQL container is configured and started:
172+
173+
```php
174+
$mySQLContainer = MySQLDockerContainer::from(image: 'mysql:8.1', name: 'test-database')
175+
->withNetwork(name: 'tiny-blocks')
176+
->withTimezone(timezone: 'America/Sao_Paulo')
177+
->withUsername(user: 'xpto')
178+
->withPassword(password: '123')
179+
->withDatabase(database: 'test_adm')
180+
->withPortMapping(portOnHost: 3306, portOnContainer: 3306)
181+
->withRootPassword(rootPassword: 'root')
182+
->withVolumeMapping(pathOnHost: '/var/lib/mysql', pathOnContainer: '/var/lib/mysql')
183+
->withoutAutoRemove()
184+
->runIfNotExists();
185+
```
186+
187+
With the MySQL container started, it is possible to retrieve data, such as the address and JDBC connection URL:
188+
189+
```php
190+
$jdbcUrl = $mySQLContainer->getJdbcUrl(options: 'useUnicode=yes&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&useSSL=false');
191+
$database = $environmentVariables->getValueBy(key: 'MYSQL_DATABASE');
192+
$username = $environmentVariables->getValueBy(key: 'MYSQL_USER');
193+
$password = $environmentVariables->getValueBy(key: 'MYSQL_PASSWORD');
194+
```
195+
196+
The Flyway container is configured and only starts and executes migrations after the MySQL container is **ready**:
197+
198+
```php
199+
$flywayContainer = GenericDockerContainer::from(image: 'flyway/flyway:11.0.0')
200+
->withNetwork(name: 'tiny-blocks')
201+
->copyToContainer(pathOnHost: '/migrations', pathOnContainer: '/flyway/sql')
202+
->withVolumeMapping(pathOnHost: '/migrations', pathOnContainer: '/flyway/sql')
203+
->withWaitBeforeRun(
204+
wait: ContainerWaitForDependency::untilReady(
205+
condition: MySQLReady::from(
206+
container: $mySQLContainer
207+
)
208+
)
209+
)
210+
->withEnvironmentVariable(key: 'FLYWAY_URL', value: $jdbcUrl)
211+
->withEnvironmentVariable(key: 'FLYWAY_USER', value: $username)
212+
->withEnvironmentVariable(key: 'FLYWAY_TABLE', value: 'schema_history')
213+
->withEnvironmentVariable(key: 'FLYWAY_SCHEMAS', value: $database)
214+
->withEnvironmentVariable(key: 'FLYWAY_EDITION', value: 'community')
215+
->withEnvironmentVariable(key: 'FLYWAY_PASSWORD', value: $password)
216+
->withEnvironmentVariable(key: 'FLYWAY_LOCATIONS', value: 'filesystem:/flyway/sql')
217+
->withEnvironmentVariable(key: 'FLYWAY_CLEAN_DISABLED', value: 'false')
218+
->withEnvironmentVariable(key: 'FLYWAY_VALIDATE_MIGRATION_NAMING', value: 'true')
219+
->run(commands: ['-connectRetries=15', 'clean', 'migrate']);
220+
```
221+
222+
<div id='license'></div>
223+
224+
## License
225+
226+
Docker container is licensed under [MIT](LICENSE).
227+
228+
<div id='contributing'></div>
229+
230+
## Contributing
231+
232+
Please follow the [contributing guidelines](https://github.com/tiny-blocks/tiny-blocks/blob/main/CONTRIBUTING.md) to
233+
contribute to the project.

0 commit comments

Comments
 (0)