docusealco / docuseal

Open source DocuSign alternative. Create, fill, and sign digital documents ✍️
https://www.docuseal.co
GNU Affero General Public License v3.0
5.7k stars 378 forks source link

Installation Method - Docker using localhost mysql database #309

Closed compumatter closed 1 week ago

compumatter commented 1 week ago

Can you provide proper docs on using docker-compose.yml using the localhost mysql database as well as the proper nginx vhosts config file to support reverse proxy. I am weak in docker but I think those two things will be a common need.
Thanks in advance.

compumatter commented 1 week ago

I have resolved this. Though I have implemented my solution in ansible, I used ChatGPT to generate this bash translation:

The bash installation script

#!/bin/bash

# Define variables
mysql_root_password="your_mysql_root_password"
docuseal_db_user="your_docuseal_db_user"
docuseal_db_password="your_docuseal_db_password"
docuseal_db_name="your_docuseal_db_name"
docuseal_host_dir="your_docuseal_host_directory"
sm_server_ip_address="your_server_ip_address"
docuseal_db_host="your_docuseal_db_host"
public_domain_name="your_public_domain_name"

# These tasks retrieve the subnet that Docker is using, e.g., 172.17.*.*

# Get Docker network details
docker_network_details=$(docker network inspect bridge --format "{{ '{{json .}}' }}")

# Set Docker subnet
docker_subnet=$(echo "$docker_network_details" | jq -r '.[0].IPAM.Config[0].Subnet')

# Extract first two octets of Docker subnet
docker_subnet_first_two_octets=$(echo "$docker_subnet" | grep -oP '^\d+\.\d+')

# Print Docker subnet first two octets
echo "The first two octets of the Docker subnet are $docker_subnet_first_two_octets"

# Ensure that Docker can reach the host database

# Create user with password, all database privileges and 'WITH GRANT OPTION' in Nextcloud
mysql -u root -p"${mysql_root_password}" -e "
CREATE USER '${docuseal_db_user}'@'localhost' IDENTIFIED BY '${docuseal_db_password}';
GRANT ALL PRIVILEGES ON ${docuseal_db_name}.* TO '${docuseal_db_user}'@'localhost' WITH GRANT OPTION;
CREATE USER '${docuseal_db_user}'@'${docker_subnet_first_two_octets}.%.%' IDENTIFIED BY '${docuseal_db_password}';
GRANT ALL PRIVILEGES ON ${docuseal_db_name}.* TO '${docuseal_db_user}'@'${docker_subnet_first_two_octets}.%.%' WITH GRANT OPTION;
FLUSH PRIVILEGES;"

# Task to set up Docuseal

# Create Docuseal data directory and subdirectory
mkdir -p "${docuseal_host_dir}" "${docuseal_host_dir}/data"
chmod 0755 "${docuseal_host_dir}" "${docuseal_host_dir}/data"

# Create a new database to hold Docuseal
mysql -u root -p"${mysql_root_password}" -e "
CREATE DATABASE IF NOT EXISTS ${docuseal_db_name};"

# Create user with password, all database privileges and 'WITH GRANT OPTION' in Docuseal
mysql -u root -p"${mysql_root_password}" -e "
CREATE USER '${docuseal_db_user}'@'%' IDENTIFIED BY '${docuseal_db_password}';
GRANT ALL PRIVILEGES ON ${docuseal_db_name}.* TO '${docuseal_db_user}'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;"

# Example of MySQL debug line
echo "mysql://${docuseal_db_user}:${docuseal_db_password}@host.docker.internal:3306/${docuseal_db_name}"

# URL encode the database password
url_encoded_db_password=$(python3 -c "import urllib.parse; print(urllib.parse.quote('${docuseal_db_password}'))")

# Debug message of the Docuseal volume mapping
echo "Docuseal volume mapping is /SM_DATA/web_signhere/data:/data"

# Generate admin token for Docuseal
admin_token=$(openssl rand -base64 48)

# Deploy Docuseal Docker container
docker run -d \
  --name docuseal \
  --restart always \
  -v "${docuseal_host_dir}/data:/data" \
  -p 3000:3000 \
  -e DATABASE_URL="mysql2://${docuseal_db_user}:${url_encoded_db_password}@${sm_server_ip_address}:3306/${docuseal_db_name}" \
  -e DB_HOST="${docuseal_db_host}" \
  -e DB_PORT="3306" \
  -e DB_NAME="${docuseal_db_name}" \
  -e DB_USER="${docuseal_db_user}" \
  -e DB_PASS="${docuseal_db_password}" \
  -e HOST="signhere.${public_domain_name}" \
  -e FORCE_SSL="https://signhere.${public_domain_name}" \
  docuseal/docuseal:latest

And this NGINX reverse proxy info:

server {
    listen 80;
    server_name signhere.compumatter.biz;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name signhere.compumatter.biz;
    include sm-snippets/wildcard_ssl_certs;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_set_header Accept-Encoding "";
    }
    # without this we receive websocket errors in the browser
    location /notifications {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $http_connection;
   }
}