# Standalone Docker Deployment

## Overview
This guide details the process of deploying the **Apidog Enterprise On-Premises** using a Standalone Docker Architecture. In this configuration, the entire technology stack is containerized and hosted within a single environment. The Apidog application runs alongside its required dependencies i.e., MySQL database and Redis on the same host machine. This setup ensures a self-sufficient ecosystem without reliance on external cloud-managed services.

In this guide we will cover two deployment approaches. Before deployment, we need to authenticate and pull the image from Docker Hub.

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

This approach involves manually executing Docker commands to create the network and launch each container individually.

### **Step 1: Network Configuration**

Create a dedicated bridge network. This allows the standalone containers to communicate securely by name (e.g., the app can reach the database at `mysql-container-name`).

```bash
docker network create apidog-network
```

### **Step 2: Deploy Dependencies (MySQL/PostgreSQL & Redis)**


:::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)**
:::

    **Deploy [MySQL](https://hub.docker.com/_/mysql):**

The minimum recommended version of MySQL is `8.0.17`. To deploy MySQL, run the following command (replace `<mysql-container-name>` with your desired container name)
    
    ```bash
    docker run \
      --restart always \
      --name '<mysql-container-name>' \
      --network 'apidog-network' \
      -e MYSQL_ROOT_PASSWORD='<mysql_password>' \
      -v mysql_data:/var/lib/mysql \
      -d mysql:<image_tag>
    ```

    Apidog does not automatically create the required database. You must manually create the database after the MySQL container is running.

    - **Access the MySQL Container:**
    ```bash
    docker exec -it <mysql-container-name> mysql -u <mysql_username> -p
    ```
    Enter the password defined in your setup (e.g., `<mysql_password>`)

    - **Execute Initialization SQL:** 
    Inside the MySQL prompt, run the following command to create the database:

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

    **Deploy [Redis](https://hub.docker.com/_/redis):**
    
    The minimum recommended version of Redis is `6.0.5`. Redis will be used by Apidog for caching and other functionalities. To deploy Redis, run the following command (be sure to replace `<redis-container-name>` with your preferred container name):
    
    ```bash
    docker run \
      --restart always \
      --name '<redis-container-name>' \
      --network 'apidog-network' \
      -v redis_data:/data \
      -d redis:<image_tag>
    ```
**Note:** Replace `<image_tag>` with the specific image tag you wish to use.

### **Step 3: Deploy Apidog Application**

To deploy the Apidog application, you can use the following Docker command. This example includes all the necessary environment variables for connecting to your MySQL and Redis containers, as well as other configurations required for the application to function properly. 

:::caution[Important]
Make sure to replace all placeholder values (e.g., `<mysql-container-name>`, `<mysql_username>`, `<mysql_password>`, `<redis-container-name>`, `<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='<mysql-container-name>' \
    -e MYSQL_PORT=3306 \
    -e MYSQL_USER_NAME='<mysql_username>' \
    -e MYSQL_PASSWORD='<mysql_password>' \
    -e REDIS_HOST='<redis-container-name>' \
    -e REDIS_PORT=6379 \
    -e REDIS_PASSWORD='<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='<Your BASE_URL>' \
    -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='<postgres_host>' \
     -e PG_PORT='<postgres_port>' \
     -e PG_USERNAME='<postgres_username>' \
     -e PG_PASSWORD='<postgres_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

Running Apidog with Docker Compose is an alternative to using the `docker run` command. This approach automates the Standalone deployment using a single configuration file (`compose.yml`), which defines the services, networks, and volumes in one place. This method requires that `docker compose` is installed on the host machine. 


:::tip[]
Deploying via the docker compose approach, you do not need to create the database for Apidog, as the `compose.yaml` file is already configured to create the database.
:::

### Install Docker Compose (If Necessary):

If the `docker-compose --version` command yields a 'command not found' error, it indicates that the Docker Compose executable is not present or properlty linked. Please refer to the official [Docker Compose Installation Guide](https://docs.docker.com/compose/install/).


### Step 1: Prepare the configuration
Save the following configuration file as `compose.yaml`, and modify the environment variables in the `compose.yaml` file match your specific configuration (License Key, Base URL, SMTP settings, etc.).


```bash
version: '3'
services:
  mysql:
    image: mysql:8.0.38
    container_name: apidog-mysql
    environment:
      MYSQL_ROOT_PASSWORD: '<root-password>'
      MYSQL_DATABASE: apidog
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
    command: mysqld --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    restart: unless-stopped
    ports:
      - '3306:3306'
    volumes:
      - mysql_data:/var/lib/mysql
    networks:
        - apidog-network
  redis:
    image: redis:6.0.5-alpine
    container_name: apidog-mysql
    restart: unless-stopped
    ports:
      - '6379:6379'
    volumes:
      - redis_data:/data
    networks:
        - apidog-network
  apidog:
    image: apidog/apidog-ee:2.7.38
    container_name: apidog-app
    environment:
      MYSQL_HOST: apidog-mysql
      MYSQL_PORT: 3306
      MYSQL_USER_NAME: 'root'
      MYSQL_PASSWORD: '<password>'
      MYSQL_DATABASE: apidog
      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: apidog-redis
      REDIS_PORT: 6379
      REDIS_PASSWORD: '<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
    depends_on:
      - mysql
      - redis
    ports:
      - 80:80
    networks:
        - apidog-network
    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:
  mysql_data:
    driver: local
  redis_data:
    driver: local
  apidog_logs:
    driver: local
  apidog_uploads:
    driver: local
networks:
    apidog-network:
```

### Step 2: Execute Deployment
Run the following command in the directory containing your `compose.yaml` file. This will automatically create the network, database and start all defined services in the correct order.

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

Verify that the application components are successfully connected within the standalone environment using Apidog's built-in diagnostic tool.

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