Skip to content

Commit

Permalink
Merge pull request #5 from redirectionio/castor-version
Browse files Browse the repository at this point in the history
Fix subsplit
  • Loading branch information
pyrech authored May 22, 2024
2 parents ab56eee + d42ed1f commit 56617d8
Show file tree
Hide file tree
Showing 42 changed files with 760 additions and 107 deletions.
2 changes: 2 additions & 0 deletions .castor/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.castor.stub.php
.env
151 changes: 151 additions & 0 deletions .castor/castor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?php

use Castor\Attribute\AsArgument;
use Castor\Attribute\AsTask;
use function Castor\context;
use function Castor\finder;
use function Castor\fs;
use function Castor\request;
use function Castor\io;
use function Castor\run;

#[AsTask(name: 'run', description: 'Build, start and ensure examples are working as expected')]
function _run(
#[AsArgument(description: 'The name of the specific example to run', autocomplete: 'get_examples')]
?string $example = null,
): void
{
if (!fs()->exists('.env')) {
io()->error('No .env file found. Please create one by copying the .env.dist file and filling in the required values.');
return;
}

stop();

if ($example) {
io()->title("Building and running example: $example");

example($example);

return;
}

io()->title('Building and running all examples');

foreach (get_examples() as $example) {
example($example);
}
}

#[AsTask(description: 'Build the given example')]
function build(
#[AsArgument(description: 'The name of the specific example to run', autocomplete: 'get_examples')]
?string $example = null,
): void
{
if (!$example) {
foreach (get_examples() as $example) {
build($example);
}
return;
}

io()->title("Building example: $example");

run('docker compose build', workingDirectory: $example);
}

#[AsTask(description: 'Start the given example')]
function start(
#[AsArgument(description: 'The name of the specific example to run', autocomplete: 'get_examples')]
string $example,
): void
{
io()->title("Starting example: $example");

run('docker compose up -d', workingDirectory: $example);

sleep(2);
}

#[AsTask(description: 'Test the given example')]
function test(
#[AsArgument(description: 'The name of the specific example to run', autocomplete: 'get_examples')]
string $example,
): void
{
io()->title("Testing example: $example");

$fails = 0;
!assertResponse('/', 200) && $fails++;
!assertResponse('/example/301-rio.html', 301) && $fails++;
!assertResponse('/example/302-rio.html', 302) && $fails++;
!assertResponse('/example/404-nginx.html', 404) && $fails++;
!assertResponse('/example/404-rio.html', 404) && $fails++;
!assertResponse('/example/410-rio.html', 410) && $fails++;

if ($fails > 0) {
throw new \RuntimeException("Some tests were not successful for example \"$example\"");
}

io()->writeln('');
}

#[AsTask(description: 'Stop the given example')]
function stop(
#[AsArgument(description: 'The name of the specific example to run', autocomplete: 'get_examples')]
?string $example = null,
): void
{
if (!$example) {
foreach (get_examples() as $example) {
stop($example);
}
return;
}

io()->title("Stopping example: $example");

run('docker compose stop', workingDirectory: $example, allowFailure: true);
}

function get_examples(): iterable
{
/** @var Symfony\Component\Finder\Finder $examples */
$examples = finder()
->in(context()->workingDirectory)
->notName('app')
->directories()
->depth(0)
->sortByName()
;

foreach ($examples as $example) {
yield $example->getBasename();
}
}

function example(string $example): void
{
if (!fs()->exists("$example/docker-compose.yml")) {
throw new \RuntimeException("The example directory \"$example\" does not exist or does not contain a docker-compose.yml file");
}

build($example);
start($example);
test($example);
stop($example);
}

function assertResponse(string $url, int $expectedStatusCode): bool
{
$response = request('GET', 'http://127.0.0.1:8080' . $url, [
'max_redirects' => 0,
]);

$result = $response->getStatusCode() === $expectedStatusCode ? '✔️' : '';

io()->text("Asserting response for $url is status $expectedStatusCode: $result");

return $response->getStatusCode() === $expectedStatusCode;
}
1 change: 1 addition & 0 deletions .env.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
REDIRECTIONIO_PROJECT_KEY=PASTE HERE YOUR REDIRECTION.IO PROJECT KEY
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Continuous Integration

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
schedule:
- cron: "0 0 * * MON"

jobs:
run-examples:
name: Run all examples
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.3
tools: castor

- name: Setup .env
run: "echo 'REDIRECTIONIO_PROJECT_KEY=${{ secrets.REDIRECTIONIO_PROJECT_KEY }}' > $GITHUB_WORKSPACE/.env"

- name: Build and run all examples
run: castor run
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.env
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright (c) 2021 redirection.io
Copyright (c) 2021-present redirection.io

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
Expand Down
79 changes: 20 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# redirection.io nginx module Docker example
# redirection.io Docker examples

It is quite common to use Docker in development or production environments. As
this has been requested by several of our users, we have set up a short example
of a Docker stack for the redirection.io agent and nginx module.
this has been requested by several of our users, we have set up different examples
to show how to integrate redirection.io in various Docker setups.

## Usage

Expand All @@ -11,71 +11,32 @@ of a Docker stack for the redirection.io agent and nginx module.
git clone https://github.com/redirectionio/docker-example.git
cd docker-example
```
* create an account and a project on [redirection.io](https://redirection.io), retrieve your `project key` in [redirection.io's manager](https://redirection.io/manager) and copy it in the nginx configuration file:
* [for the apt-installed nginx module version](./services/nginx/etc/nginx/sites-enabled/default#L9)
* [for the compiled nginx module version](./services/nginx-compiled/etc/nginx/nginx.conf#L35)
```nginx
redirectionio_project_key PUT HERE YOUR PROJECT KEY;
* create an account and a project on [redirection.io](https://redirection.io), retrieve your `project key` in [redirection.io's manager](https://redirection.io/manager) and copy it
* copy the `.env.dist` file to `.env` and paste your `project key` in it:
```sh
cp .env.dist .env
```
* choose one of the docker layouts (see below), and:
```sh
cd <your choice>
```
The `project key` can be found on the "Instances" screen of your project:
simply click on "Setup on your infrastructure".
* build the infrastructure:
```sh
docker-compose build
docker compose build
```
* run it:
```sh
docker-compose up -d
docker compose up -d
```
* open your browser and go to [http://localhost:8080/](http://localhost:8080/)
Head to:
* [http://localhost:8080/](http://localhost:8080/) to use a nginx module installed from our packages repository.
* [http://localhost:8081/](http://localhost:8081/) to use a nginx module compiled during the install.
## Explanations
The `service` directory contains three services:
* **redirectionio-agent**: a simple Dockerfile to get the agent running
* **nginx**: a nginx Dockerfile based on the Ubuntu 20.04 image, with nginx and
the redirection.io nginx module installed from our apt repository
* **nginx-compiled**: a nginx Dockerfile based on the official nginx image,
with all the directives to get the redirection.io nginx module built and
loaded
Depending on your install requirements, the version of nginx that you are using
and other specific nginx modules that you want to use, you can either use the
`nginx` or the `nginx-compiled` services as examples.
### redirectionio-agent
The agent is installed using our [manual installation](https://redirection.io/documentation/developer-documentation/installation-of-the-agent#manual-installation) instructions. Note that we have enabled a `/var/lib/redirectionio` volume, used to store [redirection.io agent's cache data](https://redirection.io/documentation/developer-documentation/agent-configuration-reference#datadir).

### nginx

This is a standard Ubuntu 20.04 image, with the distribution-provided nginx package, and [libnginx-mod-redirectionio installed from our deb repository, as explained in our documentation](https://redirection.io/documentation/developer-documentation/nginx-module#debian-and-apt-based-distributions).

It defines a single VirtualHost, [for which redirection is enabled](./services/nginx/etc/nginx/sites-enabled/default#L8-L9).

### nginx-compiled

Nginx dynamic modules require binary compatibility to be properly loaded, which
means that they have to be compiled with the exact same configuration directives
like your `nginx` binary.

redirection.io offers APT and RPM repositories, with many versions of
`libnginx-mod-redirectionio` to match classical distribution nginx packages.
However, should your nginx install vary from these traditional layouts, you will
be forced to compile our nginx module yourself, to match your own nginx version.
## Available Docker layouts
This is what the [nginx Dockerfile](./services/nginx-compiled/Dockerfile) achieves. Basically:
* it downloads the nginx sources in the same version like the installed `nginx` binary
* it downloads and build the libredirectionio
* it downloads the redirection.io nginx module
* it builds this module with the same configure arguments the installed `nginx` binary was configured
* it moves the build module in the right folder
* it [loads the module](./services/nginx-compiled/etc/nginx/nginx.conf#L7) in the nginx configuration
* it [enables redirection.io for the server](./services/nginx-compiled/etc/nginx/nginx.conf#L34-L35)
* [**agent-as-reverse-proxy**](./agent-as-reverse-proxy/README.md): the redirection.io agent, installed from our repository, is used as a reverse proxy. This is the most simple and recommended setup.
* [**apache-module**](./apache-module/README.md): a simple Apache setup, with redirection.io module installed from our apt repository
* [**apache-module-custom**](./apache-module-custom/README.md): an Apache setup with the redirection.io module compiled from sources
* [**nginx-module**](./nginx-module/README.md): a simple nginx setup, with redirection.io module installed from our apt repository
* [**nginx-module-custom**](./nginx-module-custom/README.md): a nginx setup with the redirection.io module compiled from sources
## Help and troubleshooting
Expand Down
18 changes: 18 additions & 0 deletions agent-as-reverse-proxy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Using the redirection.io agent as a reverse proxy in a Docker environment

This example shows how to use the redirection.io agent as a reverse proxy in a Docker environment. It is the most simple and versatile way to install redirection.io in your Docker stack, as it can be used with any backend service. The redirection.io agent act as a very fast reverse proxy, intercepting requests and responses between the client and the backend service.

> [!TIP]
> You can read more about [the redirection.io agent as a reverse proxy in our documentation](https://redirection.io/documentation/developer-documentation/the-agent-as-a-reverse-proxy).
## Description

The `service` directory contains the **redirectionio-agent** service: a simple Dockerfile to get the agent running. The [`/etc/redirectionio/agent.yml`](./services/redirectionio-agent/etc/redirectionio/agent.yml) file is used to configure the agent and proxify the traffic to a backend service.

The `docker-compose.yml` file also mentions a `nginx` service, which is a simple Nginx server used as a backend service. You can replace it with your own backend service.

![The redirection.io agent as a reverse proxy](../app/agent-as-reverse-proxy.png)

### redirectionio-agent

The agent is installed using our [manual installation](https://redirection.io/documentation/developer-documentation/installation-of-the-agent#manual-installation) instructions. Note that we have enabled a `/var/lib/redirectionio` volume, used to store [redirection.io agent's cache data](https://redirection.io/documentation/developer-documentation/agent-configuration-reference#datadir).
22 changes: 22 additions & 0 deletions agent-as-reverse-proxy/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
version: '3'

volumes:
redirectionio-agent-data: {}

services:
redirectionio-agent:
build: services/redirectionio-agent
env_file: "../.env"
environment:
- INSTANCE_NAME=docker-reverse-proxy
ports:
- "8080:80"
volumes:
- redirectionio-agent-data:/var/lib/redirectionio

# this is the application backend service
# it can be any other HTTP service
nginx:
image: nginx
volumes:
- ../app:/usr/share/nginx/html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM alpine:3.12 as alpine
FROM alpine:3.19 as alpine

WORKDIR /tmp

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
instance_name: "${INSTANCE_NAME}"

proxies:
-
listen: 0.0.0.0:80
forward: http://nginx:80
project_key: "${REDIRECTIONIO_PROJECT_KEY}"
33 changes: 33 additions & 0 deletions apache-module-custom/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Compiling the redirection.io Apache module in a Docker environment

It may happen that your hosting provider or provisioning solution installs a custom version of Apache, in non-standard paths or with incompatible dependencies. In this case, you may need to compile the redirection.io Apache module [from the sources](https://github.com/redirectionio/libapache2-mod-redirectionio).

This example shows how to compile the redirection.io Apache module and load it in the latest release of the Apache image.

## Description

The `service` directory contains two services:

* **apache**: an Apache Dockerfile based on the [`httpd`](https://hub.docker.com/_/httpd/) image, with redirection.io Apache module compiled from the sources.
* **redirectionio-agent**: a simple Dockerfile to get the agent running

![The redirection.io apache module](../app/apache-module.png)

### apache

redirection.io offers APT and RPM repositories, with many versions of
`libapache2-mod-redirectionio` to match classical distribution apache packages.
However, should your apache2 install vary from these traditional layouts, you will
be forced to compile our apache module yourself, to match your own apache version.

This is what the [apache Dockerfile](./services/apache/Dockerfile) achieves. Basically:
* it downloads and builds the libredirectionio
* it downloads the redirection.io apache2 module
* it builds this module
* it moves the built module in the right folder
* it [loads the module](./services/apache/Dockerfile#L61) in the Apache configuration
* it [enables redirection.io for the server](./services/apache/usr/local/apache2/conf/extra/httpd-vhosts.conf#L4-L5)

### redirectionio-agent

The agent is installed using our [manual installation](https://redirection.io/documentation/developer-documentation/installation-of-the-agent#manual-installation) instructions. Note that we have enabled a `/var/lib/redirectionio` volume, used to store [redirection.io agent's cache data](https://redirection.io/documentation/developer-documentation/agent-configuration-reference#datadir).
Loading

0 comments on commit 56617d8

Please sign in to comment.