Skip to content

Commit

Permalink
📝 added README
Browse files Browse the repository at this point in the history
  • Loading branch information
mrfullset committed Feb 16, 2023
1 parent 0948bfa commit 3d13804
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 0 deletions.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ node_modules
Dockerfile
.gitignore
docker-compose.yml
README.md
190 changes: 190 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# Billy Gin 🍶

Seamless blue/green deployment based on Nginx Proxy Manager.

## Blue/Green deployment

🤔 How to roll a new version of an app without any
downtime? **Blue/Green deployment** is a deployment
workflow where you have 2 independent app containers.

💭 Imagine you have an API `api.example.com`. With
Blue/Green workflow you start with the following
configuration:

| 🟢 | 🔵 |
|-----------------|-----------------------|
| api.example.com | api-stage.example.com |
| `v1.0.0` | `v1.0.0` |
| Container `A` | Container `B` |

Your production uses `api.example.com` so it
must have 0 downtime. Otherwise, `api-stage.example.com`
is only for internal usage, so it doesn't matter
if there is any downtime.

You roll out an update (`v1.0.1`) to the container `B`.
If it's required, it's safe to restart it, shut down etc.
Your current configuration looks like this:

| 🟢 | 🔵 |
|-----------------|-----------------------|
| api.example.com | api-stage.example.com |
| `v1.0.0` | `v1.0.1` |
| Container `A` | Container `B` |

After you spin up and tested a new version
(remember, you can still access it via `api-stage.example.com`) just swap gateways of Green and Blue
hosts:

| 🟢 | 🔵 |
|-----------------|-----------------------|
| api.example.com | api-stage.example.com |
| `v1.0.1` | `v1.0.0` |
| Container `B` | Container `A` |


🎉 Done. You have deployed a new udpate with 0 downtime.

## Usage

Do a `POST /toggle` request with following body:
```json
{
"secret": "supersecret"
}
```
That's it. You have seamlessly swapped two
containers.

## Setup

**❗️ Before start:**

This is an "add-on" for the [Nginx Proxy Manager](https://github.com/NginxProxyManager/nginx-proxy-manager). If you do not use it this project isn't suitable for you.

I really recommend you to see the original project. It's a handy tool which makes DevOps much easier ✨

### 📝 Service account

BillyGin needs a **service account** to work.
You can create it under **Users > Add users** in the
Nginx Proxy Manager UI.

If you don't want to give admin rights, select `Manage`
role for all **Proxy hosts**.

Then, set a password for the created user (_three dots, Change password_).

### 🟢🔵 Green and Blue containers

To make possible for BillyGin to operate with proxy hosts
it's required to create those hosts first.

Do it as usual under **Proxy hosts**. Create records
for *green* and *blue* hosts.

Example:

- Green host:
- Domain: `api.example.com`
- Forward hostname: `api_a`

- Blue host:
- Domain: `api-stage.example.com`
- Forward hostname: `api_b`


### 🌲 Environment variables

BillyGin is using environment variables to configure
itself. You can pass them via `.env` file.

```env
PORT=3000
HOST="0.0.0.0"
NGINX_PROXY_MANAGER_URL=http://proxy:81
NGINX_PROXY_MANAGER_SA_EMAIL="[email protected]"
NGINX_PROXY_MANAGER_SA_SECRET="somesecret"
GREEN_DOMAIN=api.example.com
BLUE_DOMAIN=api-stage.example.com
A_FORWARD_HOST=api_a
B_FORWARD_HOST=api_b
SECRET="anothersecret"
```

- `NGINX_PROXY_MANAGER_URL` - instance of Nginx Proxy
Manager
- `NGINX_PROXY_MANAGER_SA_EMAIL` - email of created
service account (user)
- `NGINX_PROXY_MANAGER_SA_SECRET` - password of
created service account
- `GREEN_DOMAIN` - "production" domain (without
protocol or slashes)
- `BLUE_DOMAIN` - "staging" domain (same rules)
- `A_FORWARD_HOST` - `A` container host (without port, protocol]
or slashes)
- `B_FORWARD_HOST` - `B` container host (same rules)
- `SECRET` - service key to sign
requests (any string you want)

**All listed variables are required.**


### 🖥️ Run natively
**Prerequisites**

- 🚀 NodeJS v18

Clone this repo. Create `.env` file with
configurations. Run following commands:

```console
npm i
npm run build
npm start
```

### 🐳 Docker compose
**Prerequisites**

- 🐳 Docker (compose)

Create a `docker-compose.yml` file with
the following contents:

```yaml
version: "3"
services:
billy-gin:
container_name: billy-gin
image: "mrfullset/billy-gin:latest"
env_file:
- .env
```
Put `.env` file near to `docker-compose.yml`. Run:

```console
docker compose up -d
```

### ☝️ Recomendations

If you use a proxy host to Nginx Proxy Manager
itself, it's a good idea to add BillyGin as
`Custom location` to its record, so you don't need
to register a separate domain for it or expose ports
from Docker. Example settings:

- Location: `/billy-gin/`
- Forward hostname: `billy-gin/`.

**Preserve slashes as they are in the example**



0 comments on commit 3d13804

Please sign in to comment.