# Hybrid Docker Deployment

## Overview
This guide details the process of deploying the Apidog Enterprise On-Premises using a Hybrid Docker Architecture.

In a hybrid configuration, the Apidog Application runs in a Docker container within self-hosted environment (e.g., a local Linux server or EC2 instance), while the Database (MySQL) and Cache (Redis) are offloaded to managed cloud services (such as AWS RDS, Google Cloud SQL, Azure Database for MySQL, or Amazon ElastiCache).

This approach combines the control of self-hosting the application with the scalability, automated backups, and high availability provided by managed cloud infrastructure.

## Requirements & Prerequisites

### 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>
 ```

## Deployment Approach 1: Docker Run (CLI)

In this approach, we deploy only the Apidog application container. We do not need to create a custom bridge network or deploy database containers locally. 


### Step 1: 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)**
:::

Even though the database is in the cloud, Apidog does not automatically create the database. You must manually connect to your Cloud database instance to initialize the database. Once connected, execute:

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

### Step 2: Deploy Apidog Application

Execute the following command.

:::caution[Important]
Replace the `MYSQL_HOST` and `REDIS_HOST` variables with your specific Cloud Endpoint URLs and also all placeholder values (e.g., `<JWT secret>`, `<Apaidog On-Premises License>`, `<Your BASE_URL>`, `<image_tag>` etc.) with your actual configuration details.

For more information on the environment variables and how to configure them, please refer to the [Configuration Guide](doc-405300)
:::

```bash
docker run \
    --restart unless-stopped \
    --name=apidog \
    -e DB_DIALECT='mysql' \
    -e MYSQL_DATABASE=apidog \
    -e MYSQL_HOST='<YOUR_CLOUD_MYSQL_ENDPOINT>' \
    -e MYSQL_PORT=3306 \
    -e MYSQL_USER_NAME='<YOUR_CLOUD_DB_USER>' \
    -e MYSQL_PASSWORD='<YOUR_CLOUD_DB_PASSWORD>' \
    -e REDIS_HOST='<YOUR_CLOUD_REDIS_ENDPOINT>' \
    -e REDIS_PORT=6379 \
    -e REDIS_PASSWORD='<YOUR_CLOUD_REDIS_PASSWORD>' \
    -e REDIS_DB=0 \
    -e REDIS_TLS_ENABLED='false' \
    -e JWT_SECRET='<JWT secret>' \
    -e LICENSE='<Apaidog On-Premises License>' \
    -e BASE_URL='<http://your-base-url.com>' \
    -e ADMIN_USERNAME='admin' \
    -e ADMIN_PASSWORD='<admin_password>' \
    -e REPLACE_PORT_NUMBER_80='80' \
    -e REPLACE_PORT_NUMBER_443='443' \
    -e STORAGE_DRIVER='file' \
    -e STORAGE_ACCESS_KEY='<storage_access_key_required_when_using_s3>' \
    -e STORAGE_ACCESS_SECRET='<storage_access_secret_required_when_using_s3>' \
    -e STORAGE_BUCKET='<bucket_name_required_when_using_s3>' \
    -e STORAGE_BASE_URL='<storage_base_url_required_when_using_s3>' \
    -e MAILER_HOST='smtp.gmail.com' \
    -e MAILER_PORT='465' \
    -e MAILER_SECURE='true' \
    -e MAILER_USER='service@email.example.com' \
    -e MAILER_PASSWORD='<mailer_password>' \
    -v ~/apidog/logs:/usr/src/app/logs \
    -v ~/apidog/data:/usr/src/app/app/public/static-upload \
    -p 80:80 \
    -d apidog/apidog-ee:<image_tag>
  ```
  :::highlight red 💡
  **Configuration Notes:**

1. **Database configuration**: 
   - If you prefer to use PostgreSQL instead of MySQL, you can set up a PostgreSQL instance and update the relevant environment variables accordingly:
     ```shell
     -e DB_DIALECT='postgresql' \
     -e PG_DATABASE=apidog \
     -e PG_HOST='<YOUR_CLOUD_POSTGRESQL_ENDPOINT>' \
     -e PG_PORT='<PORT>' \
     -e PG_USERNAME='<YOUR_CLOUD_DB_USER>' \
     -e PG_PASSWORD='<YOUR_CLOUD_DB_PASSWORD>' \
     -e PG_TLS_REJECT_UNAUTHORIZED='false' \
     ```
    - For more details, please refere to [Configuration Guide](doc-405309).

2. **Storage configuration**: 
   - The `s3` storage configuration is required for Kubernetes deployments and is also recommended for Docker based deployment
   - For non-AWS S3-compatible storage solutions (e.g., MinIO), additional environment variables may be required. These include:
     ```shell
     -e STORAGE_CUSTOM_ENDPOINT='<custom_endpoint>' \
     -e STORAGE_BUCKET_PATH_STYLE='true' \
     -e STORAGE_IS_ARN_REGION='false' \
     -e STORAGE_SIGNATURE_VERSION='v2' \
     ```
   - For more details, please refere to [Configuration Guide](doc-405300).
:::

## Deployment Approach 2: Docker Compose

This approach defines the application service in a streamlined configuration file.
### Step 1: Database Initialization
Unlike the Standalone deployment, this Compose file does not include a command instruction to initialize the database (e.g., mysqld --default-authentication...). Since the database is managed by an external cloud provider (like AWS RDS or Azure SQL), the server process and character set configurations are handled directly within your cloud provider's console, not through the Docker container. Consequently, the database must be created manually before starting the application.

Once connected to the cloud database instance, execute the following SQL command to create the database with the required character set:

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

### Step 2: Prepare the Configuration

Unlike the Standalone version, this file will not contain services for mysql or redis. It will define a single service: `apidog`. Save the following `compose.yaml` file and modify the environment variables in the `compose.yaml` file that match your specific configuration (License Key, Base URL, SMTP settings, etc.).

```bash
version: '3'
  apidog:
    image: apidog/apidog-ee:2.7.38
    container_name: apidog-app
    environment:
      MYSQL_HOST: '<YOUR_CLOUD_MYSQL_ENDPOINT>'
      MYSQL_PORT: 3306
      MYSQL_USER_NAME: '<YOUR_CLOUD_DB_USER>'
      MYSQL_PASSWORD: '<YOUR_CLOUD_DB_PASSWORD>'
      MYSQL_DATABASE: '<DATABASE_NAME>'
      MAILER_HOST: 'smtp.gmail.com'
      MAILER_PORT: '465'
      MAILER_SECURE: 'true'
      MAILER_USER: 'apidoglabs@gmail.com'
      MAILER_PASSWORD: '<mailer password>'
      PASSWORD_ERROR_RATE_LIMIT_MAX: 30
      REDIS_HOST: '<YOUR_CLOUD_REDIS_ENDPOINT>'
      REDIS_PORT: 6379
      REDIS_PASSWORD: '<YOUR_CLOUD_REDIS_PASSWORD>'
      REDIS_DB: 0
      JWT_SECRET: '<JWT secret>'
      LICENSE: '<License token>'
      BASE_URL: 'This specifies the protocol (http/https), IP address, or domain name required to access the API service. For example, it might be "https://api.example.com" or "http://192.168.0.13:80".'
      ADMIN_USERNAME: 'replace with admin dashboard account'
      ADMIN_PASSWORD: 'replace with admin dashboard password'
    tty: true
    volumes:
      - apidog_logs:/usr/src/app/logs
      - apidog_uploads:/usr/src/app/app/public/static-upload
    ports:
      - 80:80
    deploy:
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
    healthcheck:
      test: ["CMD-SHELL", "wget --tries=1 --spider http://127.0.0.1:5636/api/v1/ping && wget --tries=1 --spider http://127.0.0.1:3000/api/v1/ping && wget --tries=1 --spider http://127.0.0.1/api/v1/configs/client && wget --tries=1 --spider http://127.0.0.1/api/v1/ping"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

volumes:
  apidog_logs:
    driver: local
  apidog_uploads:
    driver: local

```

### Step 3: Execute Deployment
Run the following command in the directory containing your `compose.yaml` file.

```bash
docker compose -f compose.yaml up -d
```

### Restart Commands
```bash
docker compose -f compose.yaml down
docker compose -f compose.yaml up -d
```

## Verify System Health Check

Run the internal health check to confirm the application container can reach the external cloud endpoints.

```bash
docker exec -ti apidog-app ./doctor
```

The application has started successfully if the output includes lines similar to the following:

```
...
[WARN] This Redis server's `default` user does not require a password, but a password was supplied
connect succeeded! value is  null
Executing (default): SELECT 1+1 AS result
...
Connecting to 127.0.0.1:3000 (127.0.0.1:3000)
remote file exists
Connecting to 127.0.0.1 (127.0.0.1:80)
remote file exists
Connecting to 127.0.0.1 (127.0.0.1:80)
remote file exists
Checking BASE_URL: https://your-base-url.com
API base URL matches expected BASE_URL
```

:::info[]
If the output differs from the above, the application has either not started successfully or is still in the process of starting. A typical graceful startup time is around 30 seconds, though this may vary depending on hardware performance.
:::

## 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)
