{"id":199189,"date":"2025-09-25T07:42:11","date_gmt":"2025-09-25T05:42:11","guid":{"rendered":"https:\/\/fivemx.com\/?p=199189"},"modified":"2026-08-09T12:56:18","modified_gmt":"2026-08-09T10:56:18","slug":"how-to-run-a-fivem-server-using-docker","status":"publish","type":"post","link":"https:\/\/fivemx.com\/es\/how-to-run-a-fivem-server-using-docker\/","title":{"rendered":"C\u00f3mo ejecutar un servidor FiveM usando Docker"},"content":{"rendered":"<!-- fivemx-wave1-seo-start -->\n<section class=\"fivemx-wave1-seo\" aria-label=\"FiveM Docker setup quick checklist\">\n<h2>FiveM Docker setup quick checklist<\/h2>\n<p>A useful Docker setup keeps txAdmin data persistent, exposes the right ports, and makes updates reversible.<\/p>\n<ul>\n<li>Use Docker Compose v2 and bind-mount txData or your server data directory.<\/li>\n<li>Expose 30120 TCP\/UDP for FiveM and 40120 only where txAdmin access is intended.<\/li>\n<li>Back up server.cfg, resources, txData, and database data before changing artifacts or images.<\/li>\n<\/ul>\n<p><strong>Related shop paths:<\/strong> <a href=\"https:\/\/fivemx.com\/fivem-servers\/\" data-fivemx-shop-bridge=\"1\" data-fivemx-bridge-label=\"Server Packs\" data-fivemx-bridge-target=\"server_packs\">Server Packs<\/a> | <a href=\"https:\/\/fivemx.com\/\" data-fivemx-shop-bridge=\"1\" data-fivemx-bridge-label=\"FiveM Scripts\" data-fivemx-bridge-target=\"fivem_scripts\">FiveM Scripts<\/a> | <a href=\"https:\/\/fivemx.com\/admin-tools\/\" data-fivemx-shop-bridge=\"1\" data-fivemx-bridge-label=\"Admin Tools\" data-fivemx-bridge-target=\"admin_tools\">Admin Tools<\/a><\/p>\n<\/section>\n<!-- fivemx-wave1-seo-end -->\n\n\n<p class=\"wp-block-paragraph\">Run a FiveM server (FXServer) in Docker with this copy-paste guide: a minimal <code data-no-translation=\"\">compose.yaml<\/code> using the <code data-no-translation=\"\">spritsail\/fivem<\/code> image, correct port mapping for 30120 (TCP+UDP) and 40120 (txAdmin), persistent bind mounts for <code data-no-translation=\"\">server.cfg<\/code>, resources, and txAdmin data, license-key handling, and safe update and rollback steps.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">TL;DR<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Install Docker Engine + Docker Compose v2 on Ubuntu. (<a href=\"https:\/\/docs.docker.com\/engine\/install\/ubuntu\/\" target=\"_blank\" rel=\"noopener\">Docker Documentation<\/a>)<\/li>\n\n\n\n<li>Create a project folder, add <code data-no-translation=\"\">.env<\/code> (set <code data-no-translation=\"\">LICENSE_KEY<\/code>, <code data-no-translation=\"\">SERVER_NAME<\/code>, ports) and a minimal <code data-no-translation=\"\">compose.yaml<\/code>.<\/li>\n\n\n\n<li>Start with <code data-no-translation=\"\">docker compose up -d<\/code>; watch logs with <code data-no-translation=\"\">docker compose logs -f<\/code>.<\/li>\n\n\n\n<li>Edit <code data-no-translation=\"\">data\/server.cfg<\/code> (hostname, endpoints, resources); restart the container.<\/li>\n\n\n\n<li>Open firewall for <strong>30120\/TCP+UDP<\/strong> and <strong>40120\/TCP<\/strong> (txAdmin). txAdmin\u2019s default port is 40120. (<a href=\"https:\/\/docs.fivem.net\/docs\/resources\/txAdmin\/\" target=\"_blank\" rel=\"noopener\">Cfx.re Docs<\/a>)<\/li>\n\n\n\n<li>Always run the container with <strong>stdin\/tty<\/strong> enabled to avoid crashes. (<a rel=\"nofollow noopener\" href=\"https:\/\/github.com\/spritsail\/fivem\" target=\"_blank\">GitHub<\/a>)<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a rel=\"nofollow noopener\" class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/github.com\/spritsail\/fivem\" target=\"_blank\">Docker File (Github)<\/a><\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>OS<\/strong>: Linux <strong>Ubuntu 22.04+<\/strong> (notes for macOS\/Windows below).<\/li>\n\n\n\n<li><strong>Hardware<\/strong>: 2+ vCPU, <strong>4\u20138 GB RAM<\/strong> (more for heavy resources), <strong>SSD<\/strong> recommended.<\/li>\n\n\n\n<li><strong>Docker<\/strong>: Install <strong>Docker Engine<\/strong> and <strong>Compose v2<\/strong> from official docs. (<a href=\"https:\/\/docs.docker.com\/engine\/install\/ubuntu\/\" target=\"_blank\" rel=\"noopener\">Docker Documentation<\/a>)<\/li>\n\n\n\n<li><strong>FiveM License Key<\/strong>: Generate in the Cfx.re portal (Keymaster). Keep it secret. (<a href=\"https:\/\/support.cfx.re\/hc\/en-us\/articles\/16539369935900-How-to-create-a-registration-key\" target=\"_blank\" rel=\"noopener\">support.cfx.re<\/a>)<\/li>\n\n\n\n<li><strong>Firewall\/NAT<\/strong>: Ability to open\/forward ports 30120 (TCP+UDP) and optionally 40120 (TCP). (<a href=\"https:\/\/docs.fivem.net\/docs\/resources\/txAdmin\/\" target=\"_blank\" rel=\"noopener\">Cfx.re Docs<\/a>)<\/li>\n\n\n\n<li><strong>(Optional)<\/strong> A domain\/subdomain for txAdmin.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Architecture overview<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">One container runs <strong>FXServer<\/strong> using the <code data-no-translation=\"\">spritsail\/fivem<\/code> image. Data is <strong>bind-mounted<\/strong> to persist <code data-no-translation=\"\">server.cfg<\/code>, resources, and logs. Ports <strong>30120\/TCP+UDP<\/strong> are exposed to players; <strong>40120\/TCP<\/strong> exposes txAdmin when enabled. A <strong>healthcheck<\/strong> can probe <code data-no-translation=\"\">http:\/\/127.0.0.1:30120\/info.json<\/code>. (<a rel=\"nofollow noopener\" href=\"https:\/\/github.com\/spritsail\/fivem\" target=\"_blank\">GitHub<\/a>)<\/p>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">+-------------------- Docker Host (Ubuntu) --------------------+\n| \/home\/fivem\/data --&gt; \/config (in container) |\n| \/home\/fivem\/txData --&gt; \/txData (txAdmin data) |\n| |\n| Exposed: 30120\/tcp+udp [FXServer] | 40120\/tcp [txAdmin] |\n| Healthcheck: GET 127.0.0.1:30120\/info.json |\n+-------------------------------------------------------------+\n<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Quick Start (copy-paste)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">1) Create a project folder<\/h3>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Optional: dedicated system user and directories\nsudo useradd -r -m -d \/home\/fivem -s \/usr\/sbin\/nologin fivem || true\nsudo mkdir -p \/home\/fivem\/{data,txData}\nsudo chown -R \"$USER\":\"$USER\" \/home\/fivem\ncd \/home\/fivem\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">2) Create <code data-no-translation=\"\">.env<\/code><\/h3>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">cat &gt; .env &lt;&lt;'EOF'\n# === REQUIRED ===\nLICENSE_KEY=REPLACE_WITH_YOUR_CFX_KEY\n\n# Convenience (used by ports mapping below)\nFXSERVER_PORT=30120\nTXADMIN_PORT=40120\n\n# Not read by the image directly; use it when editing server.cfg\nSERVER_NAME=\"My Docker FiveM\"\n\n# Optional: if omitted, default config generation sets a random RCON password\nRCON_PASSWORD=\nEOF\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">3) Minimal <code data-no-translation=\"\">compose.yaml<\/code> (pin a tag)<\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Smallest working setup using the upstream image. Uses <strong>tty+stdin<\/strong> to prevent crash. (<a rel=\"nofollow noopener\" href=\"https:\/\/github.com\/spritsail\/fivem\" target=\"_blank\">GitHub<\/a>)<\/p>\n<\/blockquote>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># compose.yaml\nservices:\n fivem:\n image: spritsail\/fivem:stable\n container_name: fivem\n environment:\n - LICENSE_KEY=${LICENSE_KEY}\n # Optional toggles (see table below):\n # - NO_DEFAULT_CONFIG=1 # required if you want to use txAdmin\n # - NO_LICENSE_KEY=1 # if you put the key in server.cfg instead\n # - NO_ONESYNC=1 # disable OneSync in default config\n # - RCON_PASSWORD=${RCON_PASSWORD}\n volumes:\n - .\/data:\/config # server.cfg, resources, logs\n ports:\n - \"${FXSERVER_PORT}:30120\/tcp\"\n - \"${FXSERVER_PORT}:30120\/udp\"\n tty: true # prevent startup crash (equiv. to -t)\n stdin_open: true # prevent startup crash (equiv. to -i)\n restart: unless-stopped\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Start it:<\/p>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker compose up -d\ndocker compose logs -f\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">4) Extended variant (txAdmin, healthcheck, limits)<\/h3>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># compose.extended.yaml\nservices:\n fivem:\n image: spritsail\/fivem:stable\n container_name: fivem\n environment:\n - LICENSE_KEY=${LICENSE_KEY}\n - NO_DEFAULT_CONFIG=1 # enable txAdmin (no default +exec)\n # - NO_LICENSE_KEY=1 # if storing key in server.cfg\n # - RCON_PASSWORD=${RCON_PASSWORD}\n volumes:\n - .\/data:\/config\n - .\/txData:\/txData # persist txAdmin data\n ports:\n - \"${FXSERVER_PORT}:30120\/tcp\"\n - \"${FXSERVER_PORT}:30120\/udp\"\n - \"${TXADMIN_PORT}:40120\/tcp\" # txAdmin Web UI (default 40120)\n tty: true\n stdin_open: true\n healthcheck:\n test: [\"CMD-SHELL\", \"wget -qO- http:\/\/127.0.0.1:30120\/info.json &gt;\/dev\/null 2&gt;&amp;1\"]\n interval: 30s\n timeout: 5s\n retries: 5\n start_period: 30s\n # Basic resource knobs for standalone Compose (not Swarm 'deploy')\n cpus: 2\n mem_limit: \"6g\"\n ulimits:\n nofile:\n soft: 1048576\n hard: 1048576\n restart: unless-stopped\n<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">If <code data-no-translation=\"\">wget<\/code> is unavailable in the image, remove the healthcheck or replace with a TCP probe. txAdmin persists under <code data-no-translation=\"\">\/txData<\/code>, port <strong>40120<\/strong> is its default. (<a rel=\"nofollow noopener\" href=\"https:\/\/github.com\/spritsail\/fivem\" target=\"_blank\">GitHub<\/a>)<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Configuration &amp; Persistence<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>On first run, defaults are written to the bind mount <code data-no-translation=\"\">.\/data<\/code> (container path <code data-no-translation=\"\">\/config<\/code>). Edit <strong><code data-no-translation=\"\">.\/data\/server.cfg<\/code><\/strong> and restart the container. (<a rel=\"nofollow noopener\" href=\"https:\/\/github.com\/spritsail\/fivem\" target=\"_blank\">GitHub<\/a>)<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Typical <code data-no-translation=\"\">server.cfg<\/code> bits<\/strong>:<\/p>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># data\/server.cfg\n# Network endpoints (leave 0.0.0.0 to listen on all interfaces)\nendpoint_add_tcp \"0.0.0.0:30120\"\nendpoint_add_udp \"0.0.0.0:30120\"\n\n# Server name\nset sv_hostname \"My Docker FiveM\"\n\n# License key (use this only if NOT using LICENSE_KEY env)\n# sv_licenseKey \"REPLACE_WITH_YOUR_CFX_KEY\"\n\n# Example: ensure a basic resource\n# ensure chat\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Directory layout<\/strong> (host):<\/p>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/home\/fivem\n\u251c\u2500 data\/ -&gt; \/config (server.cfg, resources\/, logs\/)\n\u2514\u2500 txData\/ -&gt; \/txData (txAdmin profiles &amp; DB)\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Backups<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Bind-mount backup:<\/li>\n<\/ul>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">tar -C \/home\/fivem -czf fivem-backup_$(date +%F).tgz data txData\n<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>If you switch to <strong>named volumes<\/strong>, back up like:<\/li>\n<\/ul>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker run --rm -v fivem_data:\/data -v \"$PWD\":\/backup busybox \n sh -c 'tar -czf \/backup\/fivem_data_$(date +%F).tgz -C \/ data'\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Environment variables (from <code data-no-translation=\"\">spritsail\/fivem<\/code>)<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Name<\/th><th>Purpose<\/th><th>Example<\/th><\/tr><\/thead><tbody><tr><td><code data-no-translation=\"\">LICENSE_KEY<\/code><\/td><td><strong>Required<\/strong> FiveM server license key to start FXServer<\/td><td><code data-no-translation=\"\">LICENSE_KEY=xxxxx<\/code><\/td><\/tr><tr><td><code data-no-translation=\"\">RCON_PASSWORD<\/code><\/td><td>RCON password used when creating default configs; random 16-char if unset<\/td><td><code data-no-translation=\"\">RCON_PASSWORD=strongpass<\/code><\/td><\/tr><tr><td><code data-no-translation=\"\">NO_DEFAULT_CONFIG<\/code><\/td><td>Disable default <code data-no-translation=\"\">+exec<\/code> so txAdmin can manage the server<\/td><td><code data-no-translation=\"\">1<\/code><\/td><\/tr><tr><td><code data-no-translation=\"\">NO_LICENSE_KEY<\/code><\/td><td>Don\u2019t read key from env; keep it in <code data-no-translation=\"\">server.cfg<\/code><\/td><td><code data-no-translation=\"\">1<\/code><\/td><\/tr><tr><td><code data-no-translation=\"\">NO_ONESYNC<\/code><\/td><td>Disable OneSync in default configs<\/td><td><code data-no-translation=\"\">1<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">These env vars and paths <code data-no-translation=\"\">\/config<\/code>, <code data-no-translation=\"\">\/txData<\/code>, plus the need for <code data-no-translation=\"\">-ti<\/code> are defined by the upstream image. (<a rel=\"nofollow noopener\" href=\"https:\/\/github.com\/spritsail\/fivem\" target=\"_blank\">GitHub<\/a>)<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Secret <a class=\"wpil_keyword_link\" href=\"https:\/\/fivemx.com\/how-to-change-vehicle-handling\/\" title=\"FiveM Vehicle Handling Editor\" data-wpil-keyword-link=\"linked\" data-wpil-monitor-id=\"1808\">handling<\/a><\/strong>: Prefer <code data-no-translation=\"\">NO_LICENSE_KEY=1<\/code> and put <code data-no-translation=\"\">sv_licenseKey<\/code> in <code data-no-translation=\"\">server.cfg<\/code> with correct file permissions if you don\u2019t want the key in the container env. (<a rel=\"nofollow noopener\" href=\"https:\/\/github.com\/spritsail\/fivem\" target=\"_blank\">GitHub<\/a>)<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Networking &amp; Security<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Required ports<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Purpose<\/th><th>Port<\/th><th>Proto<\/th><\/tr><\/thead><tbody><tr><td>Player connections \/ API<\/td><td>30120<\/td><td>TCP+UDP<\/td><\/tr><tr><td>txAdmin Web UI (optional)<\/td><td>40120<\/td><td>TCP<\/td><\/tr><tr><td>Legacy master (rarely needed)<\/td><td>30110<\/td><td>UDP<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">FiveM defaults to 30120; txAdmin\u2019s default is 40120. (<a rel=\"nofollow noopener\" href=\"https:\/\/github.com\/spritsail\/fivem\" target=\"_blank\">GitHub<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>UFW examples (Ubuntu)<\/strong><\/p>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">sudo ufw allow 30120\/tcp\nsudo ufw allow 30120\/udp\nsudo ufw allow 40120\/tcp # only if you enable txAdmin\nsudo ufw reload\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>nftables (example ruleset extract)<\/strong><\/p>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">sudo nft add table inet filter\nsudo nft add chain inet filter input '{ type filter hook input priority 0; policy drop; }'\nsudo nft add rule inet filter input ct state established,related accept\nsudo nft add rule inet filter input iif lo accept\nsudo nft add rule inet filter input tcp dport {30120,40120} accept\nsudo nft add rule inet filter input udp dport 30120 accept\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Least privilege &amp; secrets<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Run on a hardened host; avoid mapping extra capabilities; don\u2019t run Docker as <code data-no-translation=\"\">root<\/code> user on the host.<\/li>\n\n\n\n<li>Keep <strong>RCON<\/strong> enabled only if needed; protect txAdmin with strong credentials and restrict access at the firewall.<\/li>\n\n\n\n<li>If you use SELinux-based distros (not Ubuntu), add <code data-no-translation=\"\">:Z<\/code>\/<code data-no-translation=\"\">:z<\/code> to bind mounts to fix context issues.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Updates &amp; Rollbacks<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Update to latest pinned tag<\/strong><\/p>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">docker compose pull\ndocker compose up -d\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Pin by digest (immutable)<\/strong><\/p>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Pull and discover the digest of the current tag\ndocker pull spritsail\/fivem:stable\ndocker inspect --format='{{index .RepoDigests 0}}' spritsail\/fivem:stable\n# Use the printed value in compose, e.g.:\n# image: spritsail\/fivem@sha256:abcdef...\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Rollback<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Change the image reference back to the previous tag\/digest and <code data-no-translation=\"\">docker compose up -d<\/code>.<\/li>\n\n\n\n<li>Keep recent image digests with <code data-no-translation=\"\">docker image ls --digests<\/code>.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The image provides <code data-no-translation=\"\">stable<\/code> and <code data-no-translation=\"\">latest<\/code> tags; prefer <code data-no-translation=\"\">stable<\/code> for fewer surprises. (<a rel=\"nofollow noopener\" href=\"https:\/\/github.com\/spritsail\/fivem\" target=\"_blank\">GitHub<\/a>)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Monitoring &amp; Maintenance<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Status<\/strong>: <code data-no-translation=\"\">docker ps<\/code>, <code data-no-translation=\"\">docker compose ps<\/code><\/li>\n\n\n\n<li><strong>Logs<\/strong>: <code data-no-translation=\"\">docker compose logs -f<\/code><\/li>\n\n\n\n<li><strong>Stats<\/strong>: <code data-no-translation=\"\">docker stats fivem<\/code><\/li>\n\n\n\n<li><strong>Healthcheck<\/strong>: Polls <code data-no-translation=\"\">info.json<\/code>; remove\/adjust if tooling missing. (<a href=\"https:\/\/docs.fivem.net\/docs\/server-manual\/proxy-setup\/\" target=\"_blank\" rel=\"noopener\">Cfx.re Docs<\/a>)<\/li>\n\n\n\n<li><strong>Disk<\/strong>: <code data-no-translation=\"\">docker system df<\/code>, prune old images if needed.<\/li>\n\n\n\n<li><strong>Backups<\/strong>: Cron the tar command in \u201cConfiguration &amp; Persistence\u201d.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Invalid license key<\/strong>: Verify in Cfx.re portal and ensure only one server is using the key. (<a href=\"https:\/\/support.cfx.re\/hc\/en-us\/articles\/16539369935900-How-to-create-a-registration-key\" target=\"_blank\" rel=\"noopener\">support.cfx.re<\/a>)<\/li>\n\n\n\n<li><strong>Ports already in use<\/strong>: <code data-no-translation=\"\">sudo ss -lntup | grep 30120<\/code>; stop conflicting service or change <code data-no-translation=\"\">FXSERVER_PORT<\/code>.<\/li>\n\n\n\n<li><strong>Can\u2019t reach txAdmin<\/strong>: Open <strong>40120\/TCP<\/strong> or change port; confirm <code data-no-translation=\"\">NO_DEFAULT_CONFIG=1<\/code>. (<a href=\"https:\/\/docs.fivem.net\/docs\/resources\/txAdmin\/\" target=\"_blank\" rel=\"noopener\">Cfx.re Docs<\/a>)<\/li>\n\n\n\n<li><strong>Container exits on start<\/strong>: Ensure <code data-no-translation=\"\">tty: true<\/code> and <code data-no-translation=\"\">stdin_open: true<\/code> are set. (<a rel=\"nofollow noopener\" href=\"https:\/\/github.com\/spritsail\/fivem\" target=\"_blank\">GitHub<\/a>)<\/li>\n\n\n\n<li><strong>Time\/DNS issues<\/strong>: Ensure host time sync (systemd-timesyncd\/chrony) and working DNS (<code data-no-translation=\"\">\/etc\/resolv.conf<\/code>).<\/li>\n\n\n\n<li><strong>SELinux denials (non-Ubuntu)<\/strong>: Use <code data-no-translation=\"\">:Z<\/code>\/<code data-no-translation=\"\">:z<\/code> on bind mounts or adjust contexts.<\/li>\n\n\n\n<li><strong>info.json\/players.json blocked<\/strong>: Some convars or proxies can affect these endpoints; confirm server responds on <code data-no-translation=\"\">GET \/info.json<\/code>. (<a href=\"https:\/\/docs.fivem.net\/docs\/server-manual\/proxy-setup\/\" target=\"_blank\" rel=\"noopener\">Cfx.re Docs<\/a>)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Performance Tips<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>CPU\/Memory<\/strong>: Pin CPUs and set memory limits (see extended compose).<\/li>\n\n\n\n<li><strong>Storage<\/strong>: Use SSD\/NVMe; keep resource packs optimized; avoid huge, uncompressed assets.<\/li>\n\n\n\n<li><strong>Networking<\/strong>: Keep latency low; ensure host isn\u2019t CPU throttled; prioritize UDP 30120.<\/li>\n\n\n\n<li><strong>Host kernel<\/strong>: Reasonable defaults work; advanced sysctls (<code data-no-translation=\"\">net.core.*mem_max<\/code>) can be tuned if you know your workload.<\/li>\n\n\n\n<li><strong>Logs<\/strong>: Use log rotation (as in extended example).<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">macOS \/ Windows notes<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>macOS (Docker Desktop)<\/strong>: Bind-mounted file I\/O is slower than native Linux; consider Docker Desktop\u2019s <strong>Synchronized file shares<\/strong> for better performance and ensure the folder is shared in settings. (<a href=\"https:\/\/docs.docker.com\/desktop\/features\/synchronized-file-sharing\/\" target=\"_blank\" rel=\"noopener\">Docker Documentation<\/a>)<\/li>\n\n\n\n<li><strong>Windows (WSL2)<\/strong>: Published ports are reachable via <strong>localhost<\/strong> on Windows; exposing to LAN can require extra configuration depending on mode. Prefer hosting on Linux for public servers. (<a href=\"https:\/\/docs.docker.com\/desktop\/features\/networking\/\" target=\"_blank\" rel=\"noopener\">Docker Documentation<\/a>)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Clean Uninstall<\/h2>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Stop and remove the container (keep data)\ndocker compose down\n\n# Remove container + anonymous networks + images (keeps bind-mounted data)\ndocker compose down --rmi local --remove-orphans\n\n# If you used named volumes (not in this guide), list and remove explicitly:\n# docker volume ls\n# docker volume rm &lt;volume_name&gt;\n<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">To delete <strong>all<\/strong> data, remove the bind-mounted directories:<\/p>\n\n\n\n<pre data-no-translation=\"\" class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">sudo rm -rf \/home\/fivem\/data \/home\/fivem\/txData\n<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Can I host multiple servers on one host?<\/strong><br>Yes. Use separate project directories, different <code data-no-translation=\"\">FXSERVER_PORT<\/code>\/<code data-no-translation=\"\">TXADMIN_PORT<\/code>, and distinct bind mounts. txAdmin supports per-profile data in <code data-no-translation=\"\">\/txData<\/code>. (<a href=\"https:\/\/docs.fivem.net\/docs\/resources\/txAdmin\/\" target=\"_blank\" rel=\"noopener\">Cfx.re Docs<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How do I change the server name\/IP shown in the list?<\/strong><br>Edit <code data-no-translation=\"\">sv_hostname<\/code> in <code data-no-translation=\"\">data\/server.cfg<\/code>. The IP\/port comes from your published ports and NAT config.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Can I restart automatically on crash?<\/strong><br>Yes. <code data-no-translation=\"\">restart: unless-stopped<\/code> in Compose; also consider systemd timers for watchdogs.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Where are backups located?<\/strong><br>Where you create them\u2014e.g., <code data-no-translation=\"\">fivem-backup_YYYY-MM-DD.tgz<\/code> in your working directory. See the backup commands above.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How do I enable txAdmin?<\/strong><br>Set <code data-no-translation=\"\">NO_DEFAULT_CONFIG=1<\/code>, bind-mount <code data-no-translation=\"\">\/txData<\/code>, and open <strong>40120\/TCP<\/strong>. (<a rel=\"nofollow noopener\" href=\"https:\/\/github.com\/spritsail\/fivem\" target=\"_blank\">GitHub<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Do I need 30110 open?<\/strong><br>Rarely. It was used for legacy listing; modern setups typically only need 30120 and txAdmin\u2019s 40120 if used. (<a href=\"https:\/\/forum.cfx.re\/t\/issues-with-port-forwarding-30110-on-a-home-hosted-server\/965036\" target=\"_blank\" rel=\"noopener\">Cfx.re Community<\/a>)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>How do I move the server to another machine?<\/strong><br>Copy <code data-no-translation=\"\">data\/<\/code> and <code data-no-translation=\"\">txData\/<\/code> to the new host, recreate the same Compose file, and start.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\">Links &amp; Credits<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Upstream image<\/strong>: <code data-no-translation=\"\">spritsail\/fivem<\/code> (env vars, paths, usage, txAdmin notes, <code data-no-translation=\"\">-ti<\/code> requirement). (<a rel=\"nofollow noopener\" href=\"https:\/\/github.com\/spritsail\/fivem\" target=\"_blank\">GitHub<\/a>)<\/li>\n\n\n\n<li><strong>Docker<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Install Docker Engine on Ubuntu. (<a href=\"https:\/\/docs.docker.com\/engine\/install\/ubuntu\/\" target=\"_blank\" rel=\"noopener\">Docker Documentation<\/a>)<\/li>\n\n\n\n<li>Install Docker Compose v2 (Linux plugin). (<a href=\"https:\/\/docs.docker.com\/compose\/install\/linux\/\" target=\"_blank\" rel=\"noopener\">Docker Documentation<\/a>)<\/li>\n\n\n\n<li>Sharing local files with containers (volumes vs bind mounts). (<a href=\"https:\/\/docs.docker.com\/get-started\/docker-concepts\/running-containers\/sharing-local-files\/\" target=\"_blank\" rel=\"noopener\">Docker Documentation<\/a>)<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Cfx.re \/ FiveM<\/strong>:\n<ul class=\"wp-block-list\">\n<li>Create a server registration (license) key. (<a href=\"https:\/\/support.cfx.re\/hc\/en-us\/articles\/16539369935900-How-to-create-a-registration-key\" target=\"_blank\" rel=\"noopener\">support.cfx.re<\/a>)<\/li>\n\n\n\n<li>txAdmin docs (default port 40120; data path). (<a href=\"https:\/\/docs.fivem.net\/docs\/resources\/txAdmin\/\" target=\"_blank\" rel=\"noopener\">Cfx.re Docs<\/a>)<\/li>\n\n\n\n<li>Proxy\/connection flow (<code data-no-translation=\"\">\/info.json<\/code>). (<a href=\"https:\/\/docs.fivem.net\/docs\/server-manual\/proxy-setup\/\" target=\"_blank\" rel=\"noopener\">Cfx.re Docs<\/a>)<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n<!-- fivemx-blog-portfolio-wave2:2026-08-09:how-to-run-a-fivem-server-using-docker -->\n<h2>Editorial review and source policy<\/h2>\n<p>The Docker guide distinguishes container restart policy from application recovery. Pin images, persist server data outside the writable container layer, protect secrets, and validate backup\/restore on the exact compose definition.<\/p>\n<p>This page was technically reviewed on 9 August 2026. Commands and configuration must be checked against the linked primary documentation and the exact resource version installed on the server. Test changes on staging, record the baseline, and keep a rollback copy before changing production.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>FiveM Docker setup quick checklist A useful Docker setup keeps txAdmin data persistent, exposes the right ports, and makes updates reversible. Use Docker Compose v2 and bind-mount txData or your server data directory. Expose 30120 TCP\/UDP for FiveM and 40120 only where txAdmin access is intended. Back up server.cfg, resources, txData, and database data before [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":199191,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1899,1902],"tags":[],"class_list":["post-199189","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","category-fivem-related"],"_links":{"self":[{"href":"https:\/\/fivemx.com\/es\/wp-json\/wp\/v2\/posts\/199189","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fivemx.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fivemx.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fivemx.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fivemx.com\/es\/wp-json\/wp\/v2\/comments?post=199189"}],"version-history":[{"count":5,"href":"https:\/\/fivemx.com\/es\/wp-json\/wp\/v2\/posts\/199189\/revisions"}],"predecessor-version":[{"id":214137,"href":"https:\/\/fivemx.com\/es\/wp-json\/wp\/v2\/posts\/199189\/revisions\/214137"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fivemx.com\/es\/wp-json\/wp\/v2\/media\/199191"}],"wp:attachment":[{"href":"https:\/\/fivemx.com\/es\/wp-json\/wp\/v2\/media?parent=199189"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fivemx.com\/es\/wp-json\/wp\/v2\/categories?post=199189"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fivemx.com\/es\/wp-json\/wp\/v2\/tags?post=199189"}],"curies":[{"name":"gracias","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}