# Multi-Containers Docker Deployment

## Overview
This guide outlines the procedure for deploying a clustered Apidog environment using Docker. This architecture employs Nginx as a reverse proxy and load balancer to distribute traffic across multiple Apidog application nodes, ensuring higher availability and horizontal scalability.

:::tip[Prerequisite]
Before proceeding, ensure you are familiar with the standard Running Apidog on Docker. Refer to the documentation [Standalone Docker Deployment](https://self-hosting.apidog.com/standalone-docker-deployment-1804764m0.md) and [Hybrid Docker Deployment](https://self-hosting.apidog.com/hybrid-docker-deployment-1832305m0.md).
:::

## Requirements & Prerequisites

To successfully deploy a multi-node cluster, your infrastructure must meet the following requirements:
### System Requirements

    - **[Docker](https://docs.docker.com/engine/install/)** Version 20.10.0 or higher is required. We recommend the latest stable release (e.g., 26.x).
        - Verify version: `docker --version`

    - **Hardware & Software:** For hardware and software requirement, please refer to the [System Requirements](https://self-hosting.apidog.com/system-requirements-1048815m0.md) documentation.

### External Dependencies
    - **Database:** A PostgreSQL or MySQL instance. See [Database Configuration](https://self-hosting.apidog.com/database-configuration-405309m0.md).
    - **Storage**: An S3-compatible object storage service. See [Storage Services Configuration](https://self-hosting.apidog.com/storage-services-configuration-405310m0.md)
    - **Docker Registry Access:** Ensure you have the Access Token (received via email) to pull the private image.
    
    
## Preparation: Image Pull

Authenticate with Docker Hub using the credentials provided by the Apidog support team to access the private enterprise image. 

 1.  **Log in to Docker Hub manually to verify credentials**

    ```bash
    docker login --username=apidog docker.io
    ```
 2. **Pull the Image**
 Enter your Access Token (password) when prompted for the password and pull the specific image tag:
 ```bash
  docker pull docker.io/apidog/apidog-ee:<image_tag>
 ```
 
## Database Initialization
:::info[]
**This guide utilizes a MySQL database. If you are using PostgreSQL, please refer to the [PostgreSQL Guidelines](https://self-hosting.apidog.com/database-configuration-405309m0.md##postgresql)**
:::
Apidog does not automatically create the database. You must manually connect to your database instance to initialize the database. Once connected, execute:

```sql
CREATE DATABASE IF NOT EXISTS apidog CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
exit;
```

## Apidog Node Setup

### Deployment Script

**Step 1:** Create the startup script `run-apidog.sh`.
```bash
vi run-apidog.sh
```

**Step 2:** Press `i` to enter insert mode and paste the following content, ensuring you populate the environment variables with your external database credentials. For more information on the environment variables and how to configure them, please refer to the [Environment Variables](https://self-hosting.apidog.com/environment-variables-405300m0.md) guide. Save and exit (`:wq`).

```bash run-apidog.sh
#!/bin/sh -l

set -e

docker run \
	--restart unless-stopped \
	--name=apidog \
  --user=root \
	-e MYSQL_HOST=192.168.10.166 \
	-e MYSQL_PORT=3306 \
	-e MYSQL_DATABASE=apidog \
	-e MYSQL_USER_NAME=apidog \
	-e MYSQL_PASSWORD='mysql_example_password' \
	-e REDIS_HOST=192.168.10.166 \
	-e REDIS_PORT=6379 \
	-e REDIS_PASSWORD='redis_example_password' \
	-e REDIS_DB=0 \
	-e JWT_SECRET='example' \
	-e MAILER_HOST=smtp.exmail.qq.com \
	-e MAILER_PORT=465 \
	-e MAILER_SECURE=true \
	-e MAILER_USER=example@qq.com \
	-e MAILER_PASSWORD='example_password' \
	-e LICENSE='' \
	-e ADMIN_USERNAME=admin \
	-e ADMIN_PASSWORD='admin_example_password' \
	-e RTM_QUEUE_ENABLE=true \
	-e RTS_ENABLE=true \
	-e RTM_REDIS_HOST=192.168.10.166 \
	-e RTM_REDIS_PORT=6379 \
	-e RTM_REDIS_PASSWORD='redis_example_password' \
	-e RTM_REDIS_DB=1 \
	-v $PWD/appdata/logs:/usr/src/app/logs \
	-v $PWD/appdata/static-upload:/usr/src/app/app/public/static-upload \
	-e BASE_URL='https://apidog.example.com' \
	-p 80:80 \
	-d apidog/apidog-ee:<image_tag>
```
**Step 3:** Execute the script to start the application node.
```bash
sh run-apidog.sh
```

## Gateway & Load Balancer Setup (Nginx)

This section configures an Nginx container to handle SSL termination and distribute traffic to the backend nodes configured in Section 2.

### Nginx Gateway Setup

**Step 1:** Create an initialization script `init-nginx.sh`. 

```bash
vi init-nginx.sh
```

**Step 2:** Press `i` to enter insert mode and paste the following contents, then save and exit (`:wq`).
```bash init-nginx.sh
#!/bin/sh -l

version='1.26.2-alpine3.20'

docker rm -f nginx

docker run --name=nginx -d \
	--restart always \
	-v $PWD/appdata/logs:/var/log/nginx \
	-p 80:80 \
	-p 443:443 \
	nginx:$version
```
**Step 3:** Execute the script.
```bash
sh init-nginx.sh
```
**Step 4:** Copy the configuration files to your host.
```bash
docker cp nginx:/etc/nginx/nginx.conf $PWD/appdata/
docker cp nginx:/etc/nginx/conf.d $PWD/appdata/
```

### SSL Configuration
Prepare your SSL certificates for secure HTTPS access.

**Step 1:** Create the certificate directory:
```bash
mkdir -p $PWD/appdata/conf.d/certs/
```

**Step 2:** Add your certificate and key files:
```bash
# paste certificate body into this file
vi $PWD/appdata/conf.d/certs/pem  

# paste private key into this file
vi $PWD/appdata/conf.d/certs/key 
```
### Load Balancer Configuration

Modify the Nginx `default.conf` to define the upstream backend pool.
```bash
vi $PWD/appdata/conf.d/default.conf
```
Press `i` to enter insert mode, and replace the file content with the configuration below. Ensure the upstream backend block contains the IP addresses and ports of the Apidog nodes.

```bash
# Define the cluster of Apidog Application Nodes
upstream backend {
  # Replace with the actual IPs of your Docker hosts
  server 192.168.10.128:5638;
  server 192.168.10.129:5638;
}

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name apidog.example.com;

    # Force HTTPS redirect
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name apidog.example.com;

    # SSL Parameters
    ssl_certificate     /etc/nginx/conf.d/certs/pem;
    ssl_certificate_key /etc/nginx/conf.d/certs/key;
    ssl_session_timeout 5m;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;

    location / {
      proxy_pass http://backend;
      proxy_read_timeout 180s;
      proxy_connect_timeout 180s;
      proxy_send_timeout 180s;

      # Enable WebSocket proxying (Required for Real-time features)
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
```

### Start the Gateway

Create the production startup script for Nginx using the mounted configurations.
```bash
vi run-nginx.sh
```
Press `i` to enter insert mode and paste the following contents. Save and exit (`:wq`)

```bash
#!/bin/sh -l
version='1.26.2-alpine3.20'

docker rm -f nginx || true

docker run --name=nginx -d \
    --restart always \
    -v $PWD/appdata/nginx.conf:/etc/nginx/nginx.conf \
    -v $PWD/appdata/conf.d:/etc/nginx/conf.d \
    -v $PWD/appdata/logs:/var/log/nginx \
    -p 80:80 \
    -p 443:443 \
    nginx:$version
```

Finally, execute the script:
```bash
sh run-nginx.sh
```


## Updating Apidog

:::danger[Concurrency Warning]
Initial deployments, along with subsequent system upgrades, may necessitate modifications to the database schema or involve data migration procedures. It is critical to note that these migration tasks are not designed to be executed concurrently.
:::

:::check[Deployment Strategy]
To mitigate potential issues, it is advisable to deploy a dedicated container specifically for performing the upgrade operations. Once the migration is successfully completed, the containers responsible for handling live traffic can be updated accordingly.
:::


## Run the application


To run the application, refer to the documentations:

[Accessing Apidog Web Interface](https://self-hosting.apidog.com/accessing-apidog-web-interface-405307m0.md)
[Accessing Apidog Admin Panel](https://self-hosting.apidog.com/accessing-apidog-admin-panel-700382m0.md)
[Installing Apidog On-Premises Client](https://self-hosting.apidog.com/installing-apidog-on-premises-client-700348m0.md)
 

## Other Resources

[Using LDAP for Authentication](https://self-hosting.apidog.com/using-ldap-for-authentication-405303m0.md)
[Using OKTA for Authentication](https://self-hosting.apidog.com/using-okta-for-authentication-405304m0.md)
[Using OAuth2.0 for Authentication](https://self-hosting.apidog.com/using-oauth2-0-for-authentication-481407m0.md)
[Troubleshooting Guide](doc-405314)
[Configuration Guide](doc-405300)
[Updating Apidog](https://self-hosting.apidog.com/updating-apidog-405312m0.md)
[Backing up Apidog](https://self-hosting.apidog.com/backing-up-apidog-405313m0.md)
[License Renewal](https://self-hosting.apidog.com/license-renewal-703533m0.md)
