How to setup Platypus
This is a guide on what to do when Resound guys Sun Valley Broadband and we need to divide the database. So esencially if you must divide Platypus and its users to any degree this is your go to guide!
Step 1
Get yourself a blank Linux Machine you want to build from, must be able to run Docker. You decide if you need a public IP or not but take that into consideration
First there are some pre-requites such as installing docker and updating.
sudo apt update # if on debian don't be stupid, use dnf,pacman,emerge,nala,yay,whatever
sudo apt upgrade -y
# Add Docker's official GPG key:
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Now finish my adding yourself as a docker user
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
# if this works you did it right
docker run hello-worldDocker Compose files
Microsoft SQL Server 2019 Standard
This docker container spins up MSSQL server 2019, the perfect database for a Platypus. Make sure to map your volumes properly! First one is MSSQL server data, and the second is a backup location where you can take backups to anywhere on the host. This can be useful if you need to keep your backups but nuke out your current DB. In that case just rm -rf the /var/opt/mssql host mount location. Then restore from your backups which will still be safe.
docker-compose.yml
services:
mssql:
image: mcr.microsoft.com/mssql/server:2019-latest
container_name: mssql2019
environment:
ACCEPT_EULA: "Y"
SA_PASSWORD: "PASSWORD"
MSSQL_PID: "Standard" # or "Express" / "Standard" if licensed
TZ: "America/Phoenix"
ports:
- "1433:1433"
volumes:
- /home/jason/ResoundPlatMicrosoftSQLDockerContainer/MsSQL-data:/var/opt/mssql
- /home/jason/ResoundPlatMicrosoftSQLDockerContainer/backups:/var/opt/mssql/backup # put your .bak file here
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
volumes:
sqlserver_data:Change your volume mounts as needed, Timezone is needed. This is also expecting you to have a .bak file of your Platypus database. The following command assume you made changes to this file to suite your directory stucture, then made a docker-compose.yml file with this stuff above as the conents, finally assumes you are inside the current directory of that docker-compose.yml
docker compose up -d
# now make sure its okay
docker ps
docker logs -f HASHOFCONTAINERas long as things look good, it's now time to move on to Windows
Windows 11 Docker Image
This is a custom Tiny11 Docker image, Local accounts only, no TPM, no bullshit, just Windows the way god intended.
docker-compose.yml
services:
windows:
image: dockurr/windows
container_name: windows
environment:
VERSION: "11"
DISK_SIZE: "80G"
USERNAME: "Resound"
PASSWORD: "PASSWORD"
devices:
- /dev/kvm
- /dev/net/tun
cap_add:
- NET_ADMIN
ports:
- 8006:8006
- 3390:3389/tcp
- 3390:3389/udp
volumes:
- ./windows:/storage
restart: always
stop_grace_period: 2mpay attention to the RDP Ports, I personally changed them because the host already had RDP enabled, take this into consideration. You are more than welcome to specify a Windows version here or change sizing, Windows 11 minimum is still 60GB.https://github.com/dockur/windows
now do the same thing to bring it up
docker compose up -d Great, now you have Windows and MSSQL running, now let's go back to the SQL sever and log in using SQL server managment studio or DBbeaver on mac or linux.
Now you once logged into the MSSQL server at the Query Command line, run this to First find the logical names of your MDF and LDF files in the .bak
MSSQL
// find the logical file names ( runs this first)
RESTORE FILELISTONLY
FROM DISK = '/var/opt/mssql/backup/plat_backup_2025_09_23_040001_6400102.bak.';
GONow restore
RESTORE DATABASE plat
FROM DISK = '/var/opt/mssql/backup/plat_backup_2025_09_23_040001_6400102.bak'
WITH MOVE 'plat_data' TO '/var/opt/mssql/data/plat_Data.mdf',
MOVE 'plat_Log' TO '/var/opt/mssql/data/plat_Log.ldf',
REPLACE;
GOif you get lucky this works after a few minutes, hope and pray in the mean time :)
Now its time to strip! Use this to combine from other Platypus Companies, into 1 Company, So in this case Resound needs specific customers from our other companies, so we first need to see what storeid each company is, for us storeid=4 is our new main company with customers from all sources specifically the ones we need to keep
update customer set storeid=4 where storeid=1 and active='Y' and id in (COMMA,SEPARATED,ACCOUNT,NUMBERS,)
update iheader set ih_storeid=4 where ih_storeid=1 and customer in (
select id from customer where active='Y' and id in (COMMA,SEPARATED,ACCOUNT,NUMBERS,)
)
update pheader set pmt_storeid=4 where pmt_storeid=1 and pmt_custid in (
select id from customer where active='Y' and id in (COMMA,SEPARATED,ACCOUNT,NUMBERS,)
)Now Change the 1 to a 2,3 and run a total of 3 times per company
Then it is time to do the final cleanse, good luck, this script comes from the Platypus Dev's so trust that for what it is, this will remove previous company data from the new Copy of jsut new Company customers
--Delete customer data not in company 4
delete from customer where storeid<>4
delete from custrate where custid not in (select id from customer)
delete from address where idtype='customer' and idnum not in (select id from customer)
delete from phone where idtype='customer' and idnum not in (select id from customer)
delete from custmsg where custid not in (select id from customer)
delete from email_data where d_custid not in (select id from customer)
delete from domain_item where d_custid not in (select id from customer)
delete from customer_exemption where ce_custid not in (select id from customer)
delete from bonus_act where idtype='customer' and idnum not in (select id from customer)
delete from clog where cl_custid not in (select id from customer)
delete from reason_log where rl_key_id not in (select id from customer)
delete from attachments where at_idtype='customer' and at_idnum not in (select id from customer)
delete from bonus where idtype='customer' and idnum not in (select id from customer)
delete from contract_header where ch_customer_id not in (select id from customer)
delete from contract_detail where cd_ch_id not in (select ch_id from contract_header)
delete from cust_error where ce_custid not in (select id from customer)
delete from notes where custid not in (select id from customer)
delete from username_change where uc_customer_id not in (select id from customer)
go
--Delete invoices, payments, quotes for customers who no longer exist
delete from iheader where guarantor not in (select id from customer) or customer not in (select id from customer)
delete from idetail where invoice not in (select invoice from iheader)
delete from pheader where pmt_id not in (select id from customer)
delete from pdetail where pd_hdr_id not in (select pmt_id from pheader)
delete from qheader where guarantor not in (select id from customer) or customer not in (select id from customer)
delete from qdetail where invoice not in (select invoice from qheader)
delete from bounce where id not in (select pmt_bounceid from pheader where pmt_bounceid is not null)
delete from ar_invoice where ai_invoice not in (select invoice from iheader)
delete from ar_payment where ap_payment not in (select pmt_id from pheader)
go
--Delete Tickets, emails for customers who no longer exist
delete from ticket_tbl where tkt_customer_id not in (select id from customer)
delete from call_tbl where call_idtype='ticket' and call_idnum not in (select tkt_id from ticket_tbl)
delete from email_msg where em_idtype='ticket' and em_idnum not in (select tkt_id from ticket_tbl)
delete from note_tbl where note_idtype='ticket' and note_idnum not in (select tkt_id from ticket_tbl)
delete from history_tbl where hist_idtype='ticket' and hist_idnum not in (select tkt_id from ticket_tbl)
delete from outgoing_email where oe_idtype='ticket' and oe_idnum not in (select tkt_id from ticket_tbl)
delete from outgoing_attachments where oa_email_id not in (select oe_id from outgoing_email)
delete from ticket_statistics_tbl where ts_ticket_id not in (select tkt_id from ticket_tbl)
delete from attachments where at_idtype='ticket' and at_idnum not in (select tkt_id from ticket_tbl)
go
--Remove all scheduling integration data
truncate ticket_schedule
truncate ticket_schedule_position
truncate ticket_schedule_staff
go
--Remove all data
truncate table ar_closeout
truncate table deposit
truncate table ddetail
truncate table echeckdetail
truncate table echeckheader
truncate table echeckstatusdetail
truncate table batchdetail
truncate table batchheader
truncate table batchstatusdetail
truncate table qb_batch
truncate table drawer_txn
truncate table timeclock
truncate table bonus
truncate table bonus_header
truncate table reminder
truncate table email_log
go
--Reset cash drawer amounts
update drawer set d_cash=0
go
--Disable event scheduler and remove logs
update event_group set eg_active='N'
truncate table eventlog
go
--Remove all records of commissions paid
delete from bonus where idtype='staff'
go
--Things not addressed
/*
encryption
rate groups
items
inventory (old and new)
knowledge base
merge wizard
message wizard templates
correspondence settings
options
license key separation
projects
radius config/data
tax config
user manager actions
staff accounts
staff audit logs
virtual companies
service data tables other than Email and Domain
*/Good job, if all goes well go download the Platypus Server .exe file and click next until it asks for MSSQL, in that case proceed with default options becuase it is running on localhost.
wrapping up
You should use this if your company uses Platypus, and you sell off part of your company and they need a Platypus with just their customers. Good luck :)

