
Run the Python game server locally first, then make the verified web service available remotely
This guide covers the source-based setup of a Doudizhu HTML5 game server backed by Python, Tornado, and MySQL. We will prepare the database, install the Python dependencies, configure the database connection, start the application, and verify it at its documented local address. After the local server works, we will connect it to an HTTP tunnel with Localtonet so authorized remote players can reach it without inbound router port forwarding, firewall changes, VPN setup, or a public IP address. The repository identity discrepancy described below must be resolved by a human editor before the commands are published or used in a production environment.
Understand the Doudizhu server architecture

The Doudizhu project covered here is not one of the simpler single-file browser implementations that can be opened directly from a local folder. Its documented architecture includes a Python backend built with Tornado, a MySQL database, and an HTML5 frontend using the Phaser engine. The repository contains separate client and server directories, a Python dependency file named requirements.txt, and a database initialization file named schema.sql. The server templates include browser-facing pages, so the running application provides an HTTP endpoint rather than requiring players to interact with Python directly.
This distinction matters when planning a self-hosted installation. The browser frontend depends on the running application, and the application depends on a working database connection. Opening a template file directly is therefore not an adequate verification test. A successful setup requires the schema to be imported, the Python packages to be installed, the database connection variable to be set correctly, and the Tornado application to remain running.
app.py with Python 3 from the server directory.
schema.sql to initialize the database structure.
http://127.0.0.1:8080.
The reviewed repository is identified as svzdev/doudizhu, but its README clone command points to mailgyc/doudizhu. That mismatch could indicate a fork, an ownership change, or outdated documentation. Do not blindly run the published clone command. Before installation, a human reviewer should confirm which repository and revision are intended, inspect the files, and ensure that schema.sql, requirements.txt, and the server directory belong to the same trusted checkout. This draft intentionally does not provide a clone URL because the available evidence does not resolve the discrepancy.
Prepare the host and database
Use a machine on which you can install Python packages and administer MySQL. The project documentation specifies Python 3.8 or newer and MySQL 5.7 or newer. It does not establish a particular operating system, package manager, virtual-environment tool, or production process manager, so this guide does not invent platform-specific installation commands. Install those prerequisites using the supported procedure for your operating system, then confirm that the relevant Python 3, pip3, and MySQL client commands are available.
Create or select a dedicated MySQL account with only the permissions the game actually needs. Avoid using an administrative database account for normal application operation. The README example embeds a database password directly in the connection URI, but copying a sample password is unsafe. Use a unique password, keep it out of shell history and screenshots where possible, and never commit the resulting connection string to a public repository.
| Requirement | Documented expectation | What to verify |
|---|---|---|
| Python | Python 3.8 or newer | The selected Python 3 interpreter satisfies the project requirement. |
| MySQL | MySQL 5.7 or newer | The database service is running and reachable from the game host. |
| Project checkout | Contains requirements.txt, schema.sql, and server |
The repository identity and revision have been reviewed before executing files. |
| Local HTTP port | 127.0.0.1:8080 |
The application responds locally before any public tunnel is created. |
Install and start the Doudizhu server
The following sequence preserves the installation order documented by the project. It begins after you have obtained and entered a verified checkout. If the reviewed revision changes its README, dependency layout, schema name, or startup procedure, follow that revision’s own documentation instead of assuming these instructions remain compatible.
Obtain and inspect the verified project checkout
Confirm the canonical repository with a human reviewer, clone or download that approved revision, and enter its root directory. Check that schema.sql, requirements.txt, and the server directory are present. Review scripts and dependencies before executing them.
Import the supplied MySQL schema
From the project root, use the documented MySQL import command. The -p option prompts for the database password instead of placing it directly in the command.
mysql --user=root -p < schema.sql
The command uses the administrative account shown in the project documentation for schema import. For an enduring deployment, review the schema and provision a separate least-privilege application account rather than running the game continuously with broad administrative access.
Install the documented Python dependencies
Install the packages listed by the checked-out revision. Review requirements.txt first and use an isolated environment if that is part of your organization’s Python workflow.
pip3 install -r requirements.txt
Enter the server directory
Change into the directory containing the documented application entry point.
cd server
Configure the database connection
Set the documented DATABASE_URI environment variable with the actual least-privilege database username and password created for your installation. The documented URI structure uses the mysql+aiomysql scheme, a MySQL service on 127.0.0.1:3306, and the ddz database. Replace the placeholders locally and do not publish the completed value.
export DATABASE_URI='mysql+aiomysql://DB_USER:DB_PASSWORD@127.0.0.1:3306/ddz'
Start the application with Python 3
Run the documented entry point from the server directory. Keep this process active while testing because the HTTP service is available only while the application is running.
python3 app.py
Remote browser access requires the game’s HTTP service, not direct public access to MySQL. Keep MySQL restricted to the application host or a controlled private network. Do not create a public tunnel to port 3306, and never share the value of DATABASE_URI, database passwords, Localtonet device tokens, or private administrative endpoints.
Verify the game locally before adding remote access

With app.py running, open http://127.0.0.1:8080 in a browser on the same machine. A successful local response confirms that the application process is listening and that the browser can reach the documented endpoint. Continue beyond the first page load: verify that required assets load, inspect the application terminal for errors, and exercise the game flow far enough to detect obvious database or server failures.
If the page does not load locally, stop and troubleshoot the application before configuring Localtonet. Check that the Python process remained running, that port 8080 is not already occupied, that dependencies were installed for the Python interpreter you actually launched, and that the database URI points to an accessible MySQL instance with the imported schema. Localtonet provides connectivity to a working local target, but it cannot repair an application that is not listening or a backend that cannot connect to its database.
Test the exact target 127.0.0.1:8080 from the device that will run our client. If local access works but remote access does not, investigate the tunnel configuration and client state. If local access already fails, resolve the Doudizhu process, dependencies, port, or database connection first.
Add remote HTTP access with Localtonet

Once the Doudizhu service works locally, an HTTP tunnel is the appropriate Localtonet tunnel family because the application presents a browser-facing HTTP endpoint. Our client establishes an outbound connection to a Localtonet relay server, so the host does not need inbound router port forwarding, firewall changes, VPN setup, or a public IP address. The tunnel provides a public address that forwards requests to the selected local IP address and port.
Available relay servers, regions, process types, and plan-dependent options can change. Select current values from the Localtonet dashboard rather than copying a server code or assuming that every option is included with every subscription. For the current interface and field names, consult our HTTP tunnel documentation.
Install and run the Localtonet client
Run our client on the Doudizhu host or on another device that can reach 127.0.0.1:8080. If the client runs on a different device, 127.0.0.1 would refer to that client device, so use a reachable local address for the game host instead.
Authenticate or select the client device
Select the device by its Localtonet authentication token. Tokens are device-specific secrets. Do not paste them into documentation, screenshots, source code, support posts, or game configuration files.
Select an available relay server
Choose a currently available relay server or region in the dashboard. Do not hardcode a server code from an old tutorial because availability can vary.
Create an HTTP tunnel to the local service
Configure the HTTP tunnel with the local target that the client device can reach. For a client running on the same host as this documented Doudizhu setup, the target is IP address 127.0.0.1 and port 8080.
Start the tunnel
Creating a tunnel does not start it. Use the Start button and confirm that the selected client is connected and the tunnel is running. The assigned public address becomes usable only while both the client and tunnel remain active.
Test the assigned public address
Open the assigned public URL from a separate network or authorized remote browser. Confirm that the game loads and functions as expected, then stop or delete the tunnel when remote access is no longer required.
Operate the public game responsibly
A reachable URL changes the risk profile of a development-oriented game server. Before sharing it, inspect the project for authentication behavior, administrative routes, debug output, dependency vulnerabilities, and assumptions that were safe only on localhost. The supplied project evidence does not establish its current maintenance status, recent releases, production hardening, or suitability for untrusted public traffic. Treat those points as unresolved until a maintainer or editor verifies them.
Share the public address only with intended players, apply available access controls, and use least-privilege credentials throughout the stack. Monitor both the Python process and MySQL service while testing. When a session ends, stop the tunnel rather than leaving an unnecessary public endpoint active. Remember that stopping Doudizhu, closing our client, or stopping the tunnel will make the public game unavailable.
Frequently asked questions
What software does this Doudizhu server require?
Its documentation specifies Python 3.8 or newer and MySQL 5.7 or newer. Python dependencies are installed from requirements.txt, and the supplied schema.sql initializes the database structure.
Why does this guide not include a Git clone URL?
The reviewed repository is named svzdev/doudizhu, while its README tells readers to clone mailgyc/doudizhu. Because the evidence does not resolve that discrepancy, providing one URL as canonical would be a guess. Verify the intended upstream and revision before publishing or executing the installation.
What local address should work after startup?
The project documents http://127.0.0.1:8080. Verify that address on the application host before creating a tunnel. If the Localtonet client runs on another device, configure a local target address that is reachable from that device rather than using its loopback address.
Should I expose MySQL through Localtonet for remote players?
No. Players need the game’s HTTP service, not direct access to MySQL. Keep the database private and point the Localtonet HTTP tunnel only to the working Doudizhu web target.
Does creating a Localtonet tunnel immediately make it available?
No. A created tunnel must also be started. It remains available only while the selected client device is connected, the tunnel is running, and the Doudizhu service is listening at the configured local target.
Do I need router port forwarding or a public IP address?
No. Our client establishes an outbound connection to a Localtonet relay server. This allows the local HTTP service to receive remote traffic without inbound router port forwarding, firewall changes, VPN setup, or a public IP address.
Connect your verified Doudizhu server with Localtonet
After the game responds correctly on its local HTTP endpoint, run our client, create an HTTP tunnel to the verified target, and share the assigned public address only with authorized players.
Get Started Free →