English | Español
A Docker image for running MetaTrader 5 with remote access via web browser, based on KasmVNC and the LinuxServer base image.
Inspired by: gmag11/MetaTrader5-Docker-Image — this project starts from the same base idea but uses a different approach: a pre-configured WINEPREFIX (seed prefix) baked into the image instead of installing MT5, Mono, and Python at runtime.
| Aspect | Original | This project |
|---|---|---|
| MT5 installation | At runtime (download + installer) | Pre-configured seed prefix at build |
| Wine Mono / Gecko | Installed at runtime | Disabled (WINEDLLOVERRIDES) |
| Python + mt5linux | Included (port 8001) | Removed — MQL5 only |
| VNC resolution | Auto-detected (~1695x1038) | Configurable, default 1920x1080 |
| First-boot time | 3-5 min (installation) | Instant (seed copy) |
| Image size | ~4 GB | ~3.5 GB unpruned · ~2.5 GB pruned (see Seed prefix pruning) |
- Docker installed
- x86_64 / amd64 architecture
mt5-base-prefixmust exist before building (see the Build section). If you already have a prefix generated on your host, you can migrate it with migrate-prefix-user.sh.
docker run -d \
--name mt5 \
-p 3000:3000 \
-v ./mt5_data:/config \
--restart unless-stopped \
mt5-docker:latestAccess MetaTrader 5 at http://localhost:3000.
The repo includes a single docker-compose.yaml that covers both the
single-account and multi-account cases. By default it starts one account
on port 3000:
docker compose up -dFor multi-account, uncomment the mt5-account1,
mt5-account2, ... services inside the compose file and start the ones you
need:
docker compose up -d mt5-account1 # only account1 on :3001
docker compose up -d mt5 mt5-account1 # default + account1Each service mounts its own volume (./mt5_data, ./mt5_accounts/N)
and its own VNC port, so the accounts stay isolated. The repo's
docker-compose.yaml ships with MT5_CLEAN_DEFAULT_ACCOUNT=1 by default
so production is safe; set it to 0 if you want the demo account
pre-connected for testing. See
Default account sanitization on first boot.
The compose contents (summary):
x-common: &common
image: mt5-docker:latest
build: .
restart: unless-stopped
environment:
DISPLAY_RESOLUTION: 1920x1080
MT5_CLEAN_DEFAULT_ACCOUNT: "1"
services:
mt5:
<<: *common
container_name: mt5
volumes: [./mt5_data:/config]
ports: ["3000:3000"]
# Uncomment for multi-account:
# mt5-account1:
# <<: *common
# container_name: mt5-account1
# volumes: [./mt5_accounts/account1:/config]
# ports: ["3001:3000"]Access MetaTrader 5 at http://localhost:3000 (single account) or
http://localhost:300N (account N in multi-account mode).
Bind mount vs named volume: the compose file uses relative bind mounts (
./mt5_data:/config) so the data lives in a visible host path and you can inspect/copy EA configs directly. If you prefer Docker to manage the storage (useful when you don't need direct filesystem access), replace the bind mount with a named volume in the service and declare it at the end of the file:services: mt5: volumes: - mt5-config:/config # instead of ./mt5_data:/config volumes: mt5-config:This works the same on Linux and Windows.
| Variable | Default | Description |
|---|---|---|
DISPLAY_RESOLUTION |
1920x1080 |
VNC resolution (e.g.: 1280x720, 1920x1080, 1920x1200) |
MT5_CMD_OPTIONS |
(empty) | Additional CLI arguments for MT5 (e.g.: /config:my_config.ini). Appended after /portable /skipupdate. |
MT5_CLEAN_DEFAULT_ACCOUNT |
(empty) | If it takes exactly the value 1, sanitizes the demo account inherited from the seed prefix on first boot. See Default account sanitization on first boot. |
When initializing a new WINEPREFIX, Wine runs wineboot -u, which calls
DllRegisterServer for mscoree. If the Mono runtime is not installed,
Wine launches control.exe appwiz.cpl install_mono — a graphical dialog
asking to install Wine Mono (and similarly Wine Gecko for mshtml). In
an unattended deployment, this dialog blocks startup until the user
manually dismisses it.
start.sh exports WINEDLLOVERRIDES="mscoree=;mshtml=" before launching
MT5. But the processes that trigger the prompt (winedevice.exe,
control.exe) are launched by wineserver during wineboot, before
start.sh starts MT5, and they inherit the X session environment
(openbox), not the environment of start.sh. That is why the environment
variable does not propagate to those processes.
scripts/prune-prefix.sh persists the overrides in the seed prefix's
user.reg, inside the [Software\\Wine\\DllOverrides] block:
"mscoree"=""
"mshtml"=""
An empty value suppresses the install prompt but keeps the DLLs available for any app that needs them in the future. This is the approach recommended by the Wine community (VasyaNovikov, SuperUser #1903388) when the goal is to silence the dialog without closing the door to Mono.
If you need .NET/Mono in the future: change the value to
native,builtinand drop the Mono runtime into the container. Thedisabledvalue would block the prompt but break any .NET/HTML feature. Thenative,builtinvalue does not suppress the prompt — it only controls load order, and the prompt fires earlier, during prefix initialization.
The environment variable in start.sh remains as defense-in-depth for
the processes that do inherit the start.sh environment.
MetaQuotes officially states that the auto-update system "cannot be
disabled" — there is no checkbox in the UI or supported option for
that. This image passes /skipupdate on the command line, but does
not block updates at the filesystem level.
start.sh passes this flag to terminal64.exe:
$wine_executable "$mt5file" /portable /skipupdate $MT5_CMD_OPTIONS &/skipupdate prevents MT5 from checking for and downloading updates
when connecting to the trading server.
Caveat: /skipupdate is not 100% reliable. MetaQuotes states
that the update system cannot be disabled; the flag may be ignored in
certain builds or by certain brokers, and the update prompt may still
appear.
This image does not block updates at the filesystem level. Previous attempts were ineffective:
- Empty
liveupdatefile: on modern MT5 builds (4000+), MT5 deletes the empty file and recreates the directory. chmod a-won the hash dir: Wine rewrites the hash dir owner to the runtime user (abc, UID 911) on every boot, andabccan revert anychmod a-wapplied at build time because it is the owner.
If automatic updates are a problem for your deployment, consider:
- Blocking the MetaQuotes IP at the firewall level (container network or host).
- Restoring the original
.exefiles after an update from the clean installer, regenerating the prefix withgenerate-prefix.sh.
Updates should be a conscious decision, not something that happens in the background during a trading session. To update:
- Download the latest MT5 installer from mql5.com.
- Regenerate the prefix:
./scripts/generate-prefix.sh(uses the new installer). - Rebuild the image:
docker build -t mt5-trimmed:latest . - Recreate the container with a fresh volume (or preserve the account
configuration by copying
MQL5/andconfig/from the previous volume).
Important: in an unattended multi-account deployment, an automatic update can break running EAs (MQL5 API changes), change terminal behavior without warning, or restart MT5 in the middle of an operation. Keeping updates under conscious control is the safe choice for production.
The mt5-base-prefix is a pre-configured WINEPREFIX with MT5 installed,
vcrun2019, and win10 mode. It is not included in the repo (1.5–3.0 GB
depending on whether pruning is applied) and must be generated once.
This process is INTERACTIVE. The MT5 installer is a GUI application that cannot run unattended. The script launches a temporary container with KasmVNC (web-based VNC) and opens a browser window so you can click through the MT5 installer wizard. You need a desktop browser — you cannot run this on a headless server without port forwarding.
The LinuxServer base image (baseimage-kasmvnc:debianbookworm) uses the
abc user (UID 911) at runtime. If you generate the prefix on your host
with your local user (e.g.: guillermo, UID 1000), the prefix is
configured for C:\users\guillermo\, but the container runs Wine as
abc. This produces a dual profile: Wine creates C:\users\abc\ at
runtime and the seed prefix has hardcoded paths to
C:\users\guillermo\ in the registry.
To avoid this, the prefix must be generated inside a container that uses
the same abc user as the runtime. The scripts/generate-prefix.sh
script does this automatically.
./scripts/generate-prefix.shThe script follows the official MetaQuotes installation procedure and does the following:
- Launches a temporary container from
baseimage-kasmvnc:debianbookwormwith KasmVNC active on port 3000. - Installs winehq-staging as root (NOT
winehq-stable— Wine 11 stable triggers MT5's anti-debugger check, which blocks the installer with "A debugger has been found running in your system". The official MetaQuotesmt5linux.shscript useswinehq-staging, which has Wine 10.x available and does not trigger this check). - Prepares the WINEPREFIX as user
abc(the same user the container will use at runtime):- Pre-seeds
user.regwithDllOverrides(mscoree="",mshtml="") to suppress future Wine Mono/Gecko install prompts. - Runs
wineboot -u(initializes the prefix — requires the KasmVNC display to create the registry hives and user profile). - Sets win10 mode with
reg add. - Installs
vcrun2019viawinetricks. - Downloads the MT5 installer.
- Pre-seeds
- Pauses and prompts you to open
http://localhost:3000in your browser. You click through the MT5 installer GUI (accept EULA → Install → Finish). When done, return to the terminal and press ENTER. - Verifies that
terminal64.exeexists and that the user profile isabc. - Runs
scripts/prune-prefix.shautomatically (optional reversible pruning, see Seed prefix pruning). Use--no-pruneto skip it.
# Without pruning (full prefix, ~3.0 GB):
./scripts/generate-prefix.sh --no-prune
# With pruning (trimmed prefix, ~1.5 GB):
./scripts/generate-prefix.shThe result is an mt5-base-prefix/ with profile C:\users\abc\, aligned
with the container runtime.
Wine Mono/Gecko dialogs: During
wineboot -u, two dialogs may appear requesting to install Wine Mono and Wine Gecko. Cancel both — MT5 needs neither. The pre-seededDllOverridessuppress future prompts, but the firstwinebootmay still show them.
sudorequired for pruning: The prefix files are owned byabc(UID 911), soprune-prefix.shneedssudoto modify them:sudo ./scripts/prune-prefix.sh.
If you prefer to do it step by step, the equivalent commands are below. Run them in this exact order — skipping steps produces an inconsistent prefix. This is an interactive process: step 4 requires a VNC display to run the MT5 installer GUI.
# 1. Launch a temporary container with KasmVNC active
docker run -d --name mt5-prefix-builder \
-p 3000:3000 \
-v $(pwd)/mt5-base-prefix:/config/.wine \
-e VNC_PASSWORD=mt5builder \
ghcr.io/linuxserver/baseimage-kasmvnc:debianbookworm
# 2. Fix /config ownership so abc can write
docker exec -u 0 mt5-prefix-builder bash -c '
mkdir -p /config && chown abc:abc /config && chmod 755 /config
'
# 3. Install winehq-staging as root (NOT stable — Wine 11 stable triggers
# MT5's anti-debugger check)
docker exec -u 0 mt5-prefix-builder bash -c '
apt-get update
apt-get install -y --no-install-recommends wget gnupg2 software-properties-common ca-certificates winetricks cabextract
mkdir -pm755 /etc/apt/keyrings
wget -O /etc/apt/keyrings/winehq-archive.key https://dl.winehq.org/wine-builds/winehq.key
wget -NP /etc/apt/sources.list.d/ https://dl.winehq.org/wine-builds/debian/dists/bookworm/winehq-bookworm.sources
dpkg --add-architecture i386
apt-get update
apt-get install -y --install-recommends winehq-staging wine-mono
apt-get clean && rm -rf /var/lib/apt/lists/*
'
# 4. Prepare the prefix as user abc (pre-seed DllOverrides, wineboot,
# win10, vcrun2019, download MT5 installer)
docker exec -u abc mt5-prefix-builder bash -c '
export WINEPREFIX=/config/.wine USER=abc USERNAME=abc
export WINEDLLOVERRIDES="mscoree,mshtml=n,b" WINEDEBUG=-all
export XDG_CACHE_HOME=/config/.cache XDG_DATA_HOME=/config/.local/share
export XDG_RUNTIME_DIR=/config/.runtime
mkdir -p $XDG_CACHE_HOME $XDG_DATA_HOME $XDG_RUNTIME_DIR
chmod 700 $XDG_RUNTIME_DIR
# Pre-seed user.reg with DllOverrides BEFORE wineboot
mkdir -p $WINEPREFIX
cat > $WINEPREFIX/user.reg <<EOF
WINE REGISTRY Version 2
;; All keys relative to \\User
[Software\\Wine\\DllOverrides]
"mscoree"=""
"mshtml"=""
EOF
# wineboot may show Mono/Gecko dialogs — CANCEL both
wineboot -u
wineserver -w 2>/dev/null || true
wine reg add "HKLM\\Software\\Wine" /v Version /t REG_SZ /d win10 /f
winetricks -q vcrun2019
wget -qO /tmp/mt5setup.exe https://download.mql5.com/cdn/web/metaquotes.software.corp/mt5/mt5setup.exe
'
# 5. Open http://localhost:3000 in your browser (VNC password: mt5builder)
# Open a terminal in the VNC desktop and run:
# export WINEPREFIX=/config/.wine USER=abc USERNAME=abc DISPLAY=:1
# wine /tmp/mt5setup.exe
# Click through the MT5 installer: Accept EULA → Install → Finish
# 6. Verify MT5 was installed
ls "mt5-base-prefix/drive_c/Program Files/MetaTrader 5/terminal64.exe"
# 7. Remove the temporary container
docker rm -f mt5-prefix-builder
# 8. (Optional) Prune the prefix (requires sudo — files are owned by abc UID 911)
sudo ./scripts/prune-prefix.shWhen running wineboot -u, Wine may display dialogs requesting to
install Wine Mono and Wine Gecko. Cancel both — MT5 needs
neither. MT5 is a native 64-bit application that does not require .NET
or an HTML engine.
The generate-prefix.sh script pre-seeds user.reg with
DllOverrides ("mscoree"="", "mshtml"="") before wineboot, which
suppresses these prompts on future Wine invocations. However, the first
wineboot may still show the dialogs because wineserver-launched
processes (winedevice.exe, control.exe) run before the registry
override takes full effect.
The same DllOverrides are persisted by prune-prefix.sh and loaded
by start.sh at runtime, so the prompts do not reappear when the
container boots.
The MT5 installer also downloads and installs Microsoft Edge WebView2 (~1.9 GB) as part of the process. It is not required to run MT5: it only feeds the embedded "Community/News" panel in the terminal. See the Seed prefix pruning section to remove it and save ~1 GB in the image and in every account volume.
docker build -t mt5-docker:latest .The MT5 installer pulled during prefix generation includes components that are not necessary for trading and consume space both in the image and in every account volume (they are copied on first boot). The following table summarizes what can be safely removed:
Path inside mt5-base-prefix/ |
Size | Can be removed | Notes |
|---|---|---|---|
drive_c/Program Files (x86)/Microsoft/ |
~1.9 GB | ✅ Yes | Microsoft Edge WebView2 + EdgeCore + duplicated installer. Only feeds the embedded "Community/News" panel. Without it, that tab is blank but the rest of the terminal works normally. |
drive_c/Program Files/msedge_installer.log |
~100 KB | ✅ Yes | Edge installer log. Orphan. |
drive_c/ProgramData/MetaQuotes/ML/ |
~216 MB | ONNX engine (ML models). Only remove this if your EAs do not use OnnxRun or .onnx models. If you do algorithmic trading with ML, leave it. |
|
drive_c/users/<user>/AppData/Roaming/MetaQuotes/WebInstall/ |
~124 MB | ✅ Yes | LiveUpdate packages (the .png files are disguised compressed blobs). They are re-downloaded if MT5 needs to update. |
drive_c/users/<user>/AppData/Roaming/MetaQuotes/Terminal/Help/ |
~28 MB | ✅ Yes | Offline help (mt5terminal_spanish.help). You lose F1 inside MT5. |
Safe total without touching ONNX: ~2.05 GB → 3.0 GB prefix becomes ~1.1 GB. Total with ONNX removed: ~2.27 GB → prefix becomes ~0.9 GB.
When removing Program Files (x86)/Microsoft/, the Edge registry keys in
mt5-base-prefix/user.reg become orphaned. They do not break startup,
but it is a good idea to clean them to avoid Wine warnings. The blocks
to remove are:
[Software\\Microsoft\\Edge][Software\\Microsoft\\EdgeUpdate\\ClientState\\{F3017226-...}][Software\\Microsoft\\EdgeWebView]and all its subblocks (BLBeacon,PreferenceMACs,StabilityMetrics)[Software\\Wine\\AppDefaults\\msedgewebview2.exe]
Each block includes its [...] header with timestamp and the
#time=... line that follows it.
# From the repo root, with mt5-base-prefix/ generated:
./scripts/prune-prefix.shThe script moves the removable components to .prefix-backup/
(reversible rollback) and cleans the user.reg registry keys. Verify
the resulting size with:
du -sh mt5-base-prefixIf MT5 does not start after pruning, restore the backup:
mv .prefix-backup/Microsoft.x86 "mt5-base-prefix/drive_c/Program Files (x86)/Microsoft"
git checkout -- mt5-base-prefix/user.reg # if you were tracking the prefix
docker build -t mt5-docker:latest .If you generated the prefix on your host machine (with your local user,
e.g.: guillermo) instead of inside a container (with the abc user),
the prefix will have a dual user profile: C:\users\<your_user>\ in the
registry and C:\users\abc\ created by Wine at runtime. This does not
break MT5, but it is dirty state that can be confusing.
The scripts/migrate-prefix-user.sh script fixes this without needing
to regenerate the prefix from scratch:
# See what the script would do (without modifying anything):
./scripts/migrate-prefix-user.sh --dry-run
# Apply the migration:
./scripts/migrate-prefix-user.shThe script:
- Removes the non-
abcuser directories underdrive_c/users/(e.g.:users/guillermo/). In portable mode, the functional data (account, EAs, configs) lives inProgram Files/MetaTrader 5/, not in the user profile — so nothing operational is lost. - Replaces
C:\users\<old_user>withC:\users\abcin the.regfiles (system.reg,user.reg,userdef.reg) so Wine correctly resolves%AppData%,%TEMP%, etc. for the active user. - Removes the
PackagePathregistry entry (it points to the host filesystem, e.g.:Z:\home\guillermo\Descargas\).
MT5 will recreate users/abc/AppData/Roaming/MetaQuotes/Terminal/D0E8.../
with portable.txt and origin.txt automatically on first boot, thanks
to the /portable flag that start.sh passes to terminal64.exe.
Note: This migration is a fast alternative to
generate-prefix.shwhen you already have a working prefix generated on the host. If you generate the prefix from scratch withgenerate-prefix.sh, you do not need this step.
MT5 has two data storage modes:
| Mode | Where it stores account data, configs, and EAs | Activated by |
|---|---|---|
| Normal | AppData/Roaming/MetaQuotes/Terminal/<hash>/ (Windows user profile) |
Default behavior on real Windows |
| Portable | Next to the executable, in Program Files/MetaTrader 5/ |
/portable flag on the command line, or the existence of an empty portable.txt file in <hash>/ |
In this container, start.sh forces portable mode by passing /portable
to terminal64.exe explicitly (see the next section).
Portable mode is forced explicitly in start.sh by passing the
/portable flag to terminal64.exe:
$wine_executable "$mt5file" /portable $MT5_CMD_OPTIONS &This guarantees that MT5 saves account data, configs, and EAs next to the
executable in Program Files/MetaTrader 5/, regardless of whether a
portable.txt file exists in the user profile. We do not depend on the
MetaQuotes installer's automatic behavior (which may or may not create
portable.txt under Wine depending on the version).
You can confirm it by inspecting the volume after the first boot:
ls mt5_data/.wine/drive_c/users/<user>/AppData/Roaming/MetaQuotes/Terminal/D0E8209F77C8CF37AD8BF550E51FF075/
# origin.txt → contains the installation path (C:\Program Files\MetaTrader 5)
# portable.txt → empty file, portable mode flag (pre-exists in the seed)
# liveupdate/ → directory created by MT5 at runtime (see MT5 automatic updates)The hash D0E8209F77C8CF37AD8BF550E51FF075 is the identifier MT5
computes from the installation path (C:\Program Files\MetaTrader 5).
It is stable across restarts of the same container (the path does not
change) and across containers (the internal path is always the same).
In portable mode, account data (login, history, symbols, terminal
configuration, loaded EAs) lives next to the executable in
Program Files/MetaTrader 5/, not in AppData/Roaming/. Since each
container mounts its own volume at /config, each account stays
isolated:
/config/.wine/drive_c/Program Files/MetaTrader 5/
├── MQL5/
│ ├── Experts/ # EAs for this account
│ ├── Indicators/
│ ├── Scripts/
│ └── Libraries/
├── config/ # terminal configs for this account
├── logs/ # logs for this account
├── Tester/ # strategy tester data
└── terminal64.exe # binary (shared, immutable from the EA)
The AppData/Roaming/MetaQuotes/Terminal/<hash>/ folder still exists,
but in portable mode it only stores installation metadata (origin.txt,
portable.txt, liveupdate) — not the functional account data.
- EAs and config per account: each container has its own
MQL5/Experts/folder. An EA loaded in one account is not visible in another. - No shared state between accounts: to share an EA between accounts,
copy the
.ex5to each container (see the next section). - Persistence: when you stop and start the container (
docker stop/docker start), the account, login, EAs, and configuration are preserved because they live in the/configvolume, not inside the image. - When recreating the container (
docker rm+docker run) with the same volume, the state is also preserved: the container is stateless, the volume is the source of truth.
The seed prefix (mt5-base-prefix) is generated with a MetaQuotes demo
account logged in (Login=5053564303, Server=MetaQuotes-Demo). This
is deliberate: it lets you start a new container, open VNC, and find MT5
already connected, without having to log in manually — very convenient
for testing and development.
The problem is that, in portable mode, account data lives in
Program Files/MetaTrader 5/Config/ (next to the executable), which is
exactly where the seed prefix leaves it. Without sanitization, every
new container would try to reconnect to the same MetaQuotes demo
account on startup. MetaQuotes limits concurrent connections per
account, so in a real multi-account deployment this produces temporary
locks, disconnects, and never connects to the intended broker account.
The MT5_CLEAN_DEFAULT_ACCOUNT environment variable controls
sanitization. The gate is strict: only the exact value 1 activates
it. Any other value (empty, 0, true, yes, false...) disables
it and leaves the seed's demo account in place.
environment:
- MT5_CLEAN_DEFAULT_ACCOUNT=1 # sanitization enabled
- MT5_CLEAN_DEFAULT_ACCOUNT=0 # sanitization disabled (demo account stays)
- MT5_CLEAN_DEFAULT_ACCOUNT= # sanitization disabledWhen active, start.sh — on the first boot, right after copying the
seed prefix to the volume — deletes the cached accounts.dat and empties
the Login= and Server= lines in common.ini. The result is an MT5
that starts clean, with no preconfigured account, ready for the user to
enter their own.
Sanitization lives inside the seeding branch of start.sh:
if [ ! -d "/config/.wine/drive_c" ]; then
# First boot: copy seed prefix + optional sanitization
...
fiOnce the first boot creates /config/.wine/drive_c/, that branch does
not run again — neither on restarts (docker stop/docker start), nor
when recreating the container (docker rm + docker run) on the same
volume. The account the user configures manually after sanitization is
persisted in the volume and preserved across restarts.
| Event | Seeding? | Sanitization? |
|---|---|---|
First boot with MT5_CLEAN_DEFAULT_ACCOUNT=1 |
Yes | Yes (once) |
| Later restarts | No | No |
docker rm + docker run on the same volume |
No | No |
New volume with MT5_CLEAN_DEFAULT_ACCOUNT=1 |
Yes | Yes (again, once) |
New volume without the variable (or with =0, =) |
Yes | No (current behavior, useful for testing) |
Important: changing the value of
MT5_CLEAN_DEFAULT_ACCOUNTbetween boots on the same volume has no effect — the seeding branch no longer runs. To sanitize again you must start with a fresh volume.
| File | Action | Why |
|---|---|---|
Program Files/MetaTrader 5/Config/accounts.dat |
Deleted | Contains the cached demo account session (obfuscated binary). MT5 recreates it empty on startup if it does not exist. |
Program Files/MetaTrader 5/Config/common.ini |
Login= and Server= lines emptied |
It is UTF-16LE with BOM and CRLF; start.sh uses iconv for the byte-exact roundtrip and sed to empty only those two lines. The rest of the file (Environment, Proxy, Charts, Trades, Experts...) is preserved intact. |
After the first boot with MT5_CLEAN_DEFAULT_ACCOUNT=1, you can
confirm that sanitization was applied by inspecting the volume:
# common.ini should have empty Login= and Server=
iconv -f UTF-16 -t UTF-8 \
"mt5_data/.wine/drive_c/Program Files/MetaTrader 5/Config/common.ini" \
| grep -E "^(Login|Server)="
# Expected:
# Login=
# Server=
# accounts.dat should not exist
ls "mt5_data/.wine/drive_c/Program Files/MetaTrader 5/Config/accounts.dat" 2>&1
# Expected: No such file or directory- Testing / development: leave
MT5_CLEAN_DEFAULT_ACCOUNTunset (or set it to0). You start with the demo connected and save the login. - Real multi-account deployment: set
MT5_CLEAN_DEFAULT_ACCOUNT=1in the production compose file. Each container starts clean and the user enters their broker login once; from then on it is persisted in the volume. The repo'sdocker-compose.yamlalready shipsMT5_CLEAN_DEFAULT_ACCOUNT=1by default so the sanitized behavior is the safe one for production; remove it (or set it to0) if you want the demo-connected behavior for testing.
The MQL5 structure is at:
mt5_data/.wine/drive_c/Program Files/MetaTrader 5/MQL5/
├── Experts/ # Expert Advisors
├── Indicators/ # Custom indicators
├── Scripts/ # Scripts
└── Libraries/ # Libraries
You can copy files with docker cp:
docker cp my_ea.ex5 mt5:"/config/.wine/drive_c/Program Files/MetaTrader 5/MQL5/Experts/"Or directly to the volume if you use a bind mount:
cp my_ea.ex5 "mt5_data/.wine/drive_c/Program Files/MetaTrader 5/MQL5/Experts/"You do not need to restart the container — MT5 detects the changes when the Navigator is reloaded.
┌─────────────────────────────────────────┐
│ Docker Container │
│ ┌──────────────┐ ┌─────────────────┐ │
│ │ KasmVNC │ │ WineHQ 11.0 │ │
│ │ (port │──│ + MT5 (win64) │ │
│ │ 3000) │ │ │ │
│ └──────────────┘ └─────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────────────────────────────┐ │
│ │ /config (VOLUME) │ │
│ │ └── .wine/ (seeded on 1st boot) │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────┘
The seed prefix (/mt5-base-prefix) is copied to /config/.wine on the
first boot if the volume is empty. This allows MT5 configuration,
accounts, and EAs to persist across restarts.
MIT — see LICENSE.md.
KasmVNC is under GPLv2 and the LinuxServer base image under GPLv3.