{"id":2792,"date":"2026-04-15T20:19:20","date_gmt":"2026-04-15T20:19:20","guid":{"rendered":"https:\/\/www.serverspan.com\/blog\/"},"modified":"2026-04-15T20:19:21","modified_gmt":"2026-04-15T20:19:21","slug":"firefly-iii-on-a-vps-own-your-financial-data-before-your-banks-app-owns-you","status":"publish","type":"post","link":"https:\/\/www.serverspan.com\/en\/blog\/firefly-iii-on-a-vps-own-your-financial-data-before-your-banks-app-owns-you\/","title":{"rendered":"Firefly III on a VPS: Own Your Financial Data Before Your Bank&#8217;s App Owns You"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">You can self-host Firefly III on a VPS in under 20 minutes using Docker Compose. The result is a fully private personal finance manager running on your own server, with transaction data stored in a MariaDB container, accessible over HTTPS behind Nginx, and connected to the Data Importer for CSV bank exports. This guide covers the complete setup and the one configuration mistake that silently corrupts your encrypted data on every version upgrade.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What Firefly III actually does<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Firefly III is an open-source personal finance manager built for people who want a real double-entry transaction ledger, not a bank app&#8217;s filtered view of their spending. You define accounts (checking, savings, credit cards, cash wallets, investment accounts), record transactions manually or import them from CSV files or bank connections, and build budgets, categories, and reports on top. The application runs entirely on your own infrastructure. No third-party service touches your financial data.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The practical workflow on a VPS is straightforward: export a CSV from your bank&#8217;s online portal once a week, feed it to the Data Importer container, and Firefly III categorizes and stores the transactions. Over time you get accurate spending history, multi-currency support, recurring transaction automation, and financial reports that would otherwise require a paid subscription to a cloud app that stores your data on someone else&#8217;s server. On a ct.Steady plan (4 cores, 4GB RAM, 50GB SSD), Firefly III runs alongside other services without noticeable resource pressure.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What you need before you start<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You need a VPS running Debian 12 or Ubuntu 22.04\/24.04 with Docker and the Compose plugin installed. Firefly III&#8217;s stated minimum is 512MB RAM, but with MariaDB and the cron container also running, a 1GB instance becomes tight under normal operation. Plan for 2GB to give yourself comfortable headroom. You also need a domain or subdomain pointed at your server&#8217;s IP address before setting up the Nginx reverse proxy. The default SMTP block on new VPS instances does not affect Firefly III since email is optional configuration.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If Docker is not yet installed, run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -fsSL https:\/\/get.docker.com | sh\nsystemctl enable --now docker<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Verify that the Compose plugin is available:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker compose version<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the command returns a v2.x version number, proceed. If it fails, install the plugin manually:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apt install docker-compose-plugin -y<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Directory setup and file downloads<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create a dedicated directory and move into it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p \/opt\/firefly-iii &amp;&amp; cd \/opt\/firefly-iii<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Download the three required files directly from the official Firefly III repositories:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -O https:\/\/raw.githubusercontent.com\/firefly-iii\/docker\/main\/docker-compose.yml\ncurl -o .env https:\/\/raw.githubusercontent.com\/firefly-iii\/firefly-iii\/main\/.env.example\ncurl -o .db.env https:\/\/raw.githubusercontent.com\/firefly-iii\/docker\/main\/database.env<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The filenames are not arbitrary. The compose file contains <code>env_file: .env<\/code> and <code>env_file: .db.env<\/code> as literal references. Renaming the files requires editing the compose file to match. Download the raw files with <code>curl<\/code> rather than copy-pasting from a browser, since YAML is whitespace-sensitive and rendered pages may introduce invisible formatting changes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Docker Compose file<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The default compose file from the Firefly III Docker repository defines three core services: the main application (<code>app<\/code>), the database (<code>db<\/code> running MariaDB LTS), and a lightweight Alpine cron container that triggers recurring transaction processing each night. A minimal compose file configured for a production VPS deployment looks like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>services:\n  app:\n    image: fireflyiii\/core:latest\n    hostname: app\n    container_name: firefly_iii_core\n    restart: always\n    volumes:\n      - firefly_iii_upload:\/var\/www\/html\/storage\/upload\n    env_file: .env\n    networks:\n      - firefly_iii\n    ports:\n      - \"127.0.0.1:8080:8080\"\n    depends_on:\n      - db\n\n  db:\n    image: mariadb:lts\n    hostname: db\n    container_name: firefly_iii_db\n    restart: always\n    env_file: .db.env\n    networks:\n      - firefly_iii\n    volumes:\n      - firefly_iii_db:\/var\/lib\/mysql\n\n  cron:\n    image: alpine\n    container_name: firefly_iii_cron\n    restart: always\n    command: &gt;\n      sh -c \"echo '0 3 * * * wget -qO- http:\/\/app:8080\/api\/v1\/cron\/REPLACE_WITH_CRON_TOKEN' | crontab - &amp;&amp; crond -f -L \/dev\/stdout\"\n    networks:\n      - firefly_iii\n\nvolumes:\n  firefly_iii_upload:\n  firefly_iii_db:\n\nnetworks:\n  firefly_iii:\n    driver: bridge<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The port binding uses <code>127.0.0.1:8080:8080<\/code> instead of <code>0.0.0.0:8080:8080<\/code>. This restricts direct container access to the loopback interface. The only path into Firefly III from outside the server is through your Nginx reverse proxy. Binding to <code>0.0.0.0<\/code> is a routine mistake on new VPS deployments that bypasses any firewall rules you have in place for port 8080.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Configuring .env and why APP_KEY is the most important variable in the file<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Open <code>.env<\/code> and set these values before the containers ever start. The database password must match exactly between <code>.env<\/code> and <code>.db.env<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># .env\nAPP_KEY=                              # Generate this FIRST - see below\nAPP_URL=https:\/\/finance.yourdomain.com\nSITE_OWNER=you@yourdomain.com\nDB_CONNECTION=mysql\nDB_HOST=db\nDB_PORT=3306\nDB_DATABASE=firefly\nDB_USERNAME=firefly\nDB_PASSWORD=a_strong_password_here\nSTATIC_CRON_TOKEN=a32characterrandomtokenstringhere\nTZ=Europe\/Bucharest<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># .db.env\nMYSQL_RANDOM_ROOT_PASSWORD=yes\nMYSQL_USER=firefly\nMYSQL_PASSWORD=a_strong_password_here\nMYSQL_DATABASE=firefly<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Set the database password in both files before the first <code>docker compose up<\/code>. MariaDB initializes its data directory on the first container start and stores the credentials in the volume. If you start the stack with one password and change it later in the env files, the database volume still holds the original credentials. You will get authentication failures on every subsequent start that require dropping the <code>firefly_iii_db<\/code> volume to fix.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Generating APP_KEY correctly<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">APP_KEY is Laravel&#8217;s application encryption key. Firefly III uses it to encrypt all OAuth tokens, API keys, and sensitive fields written to the database. The key must be exactly 32 characters. Generate one before you start the containers:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>head \/dev\/urandom | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 32 &amp;&amp; echo<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Copy the output into <code>.env<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>APP_KEY=yourgenerated32characterstring<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Store this value in a password manager immediately. You will need the original, unchanged key every time you update the container image, rebuild the stack, or migrate the installation to a different server. This key is permanently tied to the encrypted data in your MariaDB volume. It does not rotate. It does not change.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">The failure mode that breaks installations on upgrades<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In our experience managing Docker deployments, this is the most common Firefly III support pattern: a user wants to upgrade to a new version, re-downloads the <code>.env.example<\/code> from the repository to get clean settings, leaves <code>APP_KEY<\/code> blank or generates a new one, and starts the updated container against the existing database volume. The new key cannot decrypt anything written with the old one. The application throws a <code>Illuminate\\Contracts\\Encryption\\DecryptException<\/code> in the log and all previously created OAuth clients, API tokens, and encrypted account fields are unusable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Check the application log inside the running container:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker exec -it firefly_iii_core tail -n 50 \/var\/www\/html\/storage\/logs\/laravel.log<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If you see <code>DecryptException<\/code> entries, the cause is almost always APP_KEY mismatch. The recovery path is to restore the original key in <code>.env<\/code> and restart the stack. There is no automated re-encryption utility. Changing APP_KEY after data has been written to the database is not recoverable without the original key.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>STATIC_CRON_TOKEN<\/code> value goes into both the cron container command and your <code>.env<\/code>. Generate it the same way as APP_KEY and keep it stable across upgrades for the same reason.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Starting the stack and verifying health<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Start all containers:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker compose up -d --pull=always<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Watch the application logs until initialization completes:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker compose logs -f app<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On a first run, Firefly III executes database migrations automatically. On a vm.Entry or ct.Ready plan, this typically finishes within 60 to 90 seconds. The &#8220;Thank you for installing Firefly III&#8221; line in the log confirms the application is ready. Verify the APP_KEY and database connection are working correctly with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>docker exec firefly_iii_core php artisan firefly-iii:decrypt-all<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If that command returns without error output, the stack is healthy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Nginx reverse proxy configuration<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Install Nginx on the host if it is not already running:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>apt install nginx -y<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create a server block at <code>\/etc\/nginx\/sites-available\/firefly<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server {\n    listen 80;\n    server_name finance.yourdomain.com;\n    return 301 https:\/\/$host$request_uri;\n}\n\nserver {\n    listen 443 ssl;\n    server_name finance.yourdomain.com;\n\n    ssl_certificate \/etc\/letsencrypt\/live\/finance.yourdomain.com\/fullchain.pem;\n    ssl_certificate_key \/etc\/letsencrypt\/live\/finance.yourdomain.com\/privkey.pem;\n\n    client_max_body_size 64M;\n\n    location \/ {\n        proxy_pass         http:\/\/127.0.0.1:8080;\n        proxy_set_header   Host $host;\n        proxy_set_header   X-Real-IP $remote_addr;\n        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header   X-Forwarded-Proto $scheme;\n    }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Enable the site and obtain a certificate from Let&#8217;s Encrypt:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ln -s \/etc\/nginx\/sites-available\/firefly \/etc\/nginx\/sites-enabled\/\napt install certbot python3-certbot-nginx -y\ncertbot --nginx -d finance.yourdomain.com\nnginx -t &amp;&amp; systemctl reload nginx<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>client_max_body_size 64M<\/code> directive is not optional if you plan to import large CSV files. Nginx rejects uploads above its 1MB default with a 413 error. Firefly III does not surface a helpful message in the UI when this happens, so the request silently fails and the import never starts. If you are running a DirectAdmin or cPanel stack on the same server with an existing Nginx front-end, add the proxy location to the relevant virtual host configuration instead of creating a parallel Nginx instance.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Adding the Data Importer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Data Importer is a separate container maintained by the Firefly III project. It reads CSV files or connects to supported bank APIs via GoCardless and pushes parsed transactions into Firefly III through the REST API. Running it as an additional service in the same compose file is the cleanest approach on a single VPS.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Add the importer service to <code>docker-compose.yml<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  importer:\n    image: fireflyiii\/data-importer:latest\n    hostname: importer\n    container_name: firefly_iii_importer\n    restart: always\n    networks:\n      - firefly_iii\n    ports:\n      - \"127.0.0.1:8081:8080\"\n    env_file: .importer.env\n    depends_on:\n      - app<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Create <code>.importer.env<\/code>. Two variables are non-negotiable:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># .importer.env\nFIREFLY_III_URL=http:\/\/app:8080\nVANITY_URL=https:\/\/finance.yourdomain.com\nTZ=Europe\/Bucharest<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>FIREFLY_III_URL<\/code> value is the internal Docker bridge network address. The importer communicates with the Firefly III container over the shared <code>firefly_iii<\/code> network, using the container hostname <code>app<\/code> and internal port <code>8080<\/code>. Setting this to your public domain name will fail because the importer cannot resolve external DNS from inside the Docker network. The <code>VANITY_URL<\/code> is what the importer displays in its own interface to generate correct redirect links pointing at your public domain.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Creating the OAuth client<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">After bringing up the updated stack with <code>docker compose up -d<\/code>, open Firefly III in your browser and go to your profile page. Scroll to the OAuth section and create a new client:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Name: Data Importer (or anything descriptive)<\/li>\n\n\n\n<li>Redirect URL: <code>https:\/\/finance.yourdomain.com\/callback<\/code><\/li>\n\n\n\n<li>Uncheck &#8220;Confidential&#8221;<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Note the client ID that is generated (it is a small integer, typically 1 or 2). You will enter this the first time you open the importer interface. Add an Nginx proxy block for the importer. The simplest configuration is a separate subdomain or a path-based location on the same server block as Firefly III:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server {\n    listen 443 ssl;\n    server_name importer.yourdomain.com;\n\n    ssl_certificate \/etc\/letsencrypt\/live\/importer.yourdomain.com\/fullchain.pem;\n    ssl_certificate_key \/etc\/letsencrypt\/live\/importer.yourdomain.com\/privkey.pem;\n\n    client_max_body_size 64M;\n\n    location \/ {\n        proxy_pass http:\/\/127.0.0.1:8081;\n        proxy_set_header Host $host;\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Importing your first bank CSV<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Most banks provide CSV export from their online portal under the transaction history section. The exact column structure varies by institution, but Firefly III&#8217;s Data Importer handles column mapping during the first import from each bank. You match CSV columns to Firefly III fields (date, amount, description, account IBAN), save the configuration as a JSON file, and every subsequent import from that bank reuses it. The process reduces to selecting the CSV, selecting the saved JSON configuration, and clicking import.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The importer shows a preview of parsed transactions before committing them to the database. Verify that date parsing is correct and that debit\/credit direction is handled accurately for your bank&#8217;s format before confirming. Some banks export amounts with a separate debit\/credit column rather than signed values, and the column mapper handles both patterns.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For teams running business expense tracking on a <a href=\"https:\/\/www.serverspan.com\/en\/virtual-servers\">managed VPS<\/a>, Firefly III&#8217;s REST API also accepts transactions directly. You can build automated import pipelines with n8n or a cron script that posts transaction data to the API endpoint, eliminating the manual CSV step entirely for accounts that support programmatic export. If you need help setting up Docker workloads or configuring the reverse proxy on a new server, <a href=\"https:\/\/www.serverspan.com\/en\/linux-administration\">ServerSpan&#8217;s Linux administration service<\/a> covers this type of deployment work.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Running Firefly III alongside other self-hosted services on a single VPS requires careful memory allocation and Docker network management. If you would rather focus on the application than the infrastructure, <a href=\"https:\/\/www.serverspan.com\/en\/virtual-servers\">ServerSpan&#8217;s managed VPS hosting<\/a> includes Docker pre-configured, root SSH access, NVMe SSD storage, and technical support for deployment questions. View available plans and data center locations across Germany, Canada, and the USA.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For practical guidance on managing Docker containers and resource limits on a VPS, see our guide on <a href=\"https:\/\/www.serverspan.com\/en\/blog\/managing-docker-and-containers-on-a-vps-best-practices-for-stability-and-performance\/\">Docker container management best practices<\/a>. If you are sizing a new VPS for multiple self-hosted applications running concurrently, our deep-dive on <a href=\"https:\/\/www.serverspan.com\/en\/blog\/linux-swap-vs-ram-the-definitive-guide-to-memory-management-on-vps\/\">Linux swap versus RAM memory management<\/a> explains how to configure swap as a safety net for workloads with variable memory demand.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You can self-host Firefly III on a VPS in under 20 minutes using Docker Compose. The result is a fully private personal finance manager running on your own server, with transaction data stored in a MariaDB container, accessible over HTTPS behind Nginx, and connected to the Data Importer for CSV bank exports. This guide covers [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2793,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,12],"tags":[15605,15604,15600,15623,15608,15620,15595,15598,15597,15618,15611,15617,15601,15614,15606,15609,15615,15594,15612,15607,15602,15622,15610,15616,15599,15596,15603,15613,15621,15619],"class_list":["post-2792","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","category-virtual-servers","tag-docker-compose-personal-finance-vps","tag-firefly-iii-app-key-decryptexception-fix","tag-firefly-iii-app-key-encryption-error","tag-firefly-iii-app-key-generate-32-characters","tag-firefly-iii-cron-container-setup","tag-firefly-iii-csv-bank-import-tutorial-2026","tag-firefly-iii-data-importer-csv-import","tag-firefly-iii-data-importer-docker","tag-firefly-iii-docker-compose-tutorial","tag-firefly-iii-docker-database-password-setup","tag-firefly-iii-docker-importer-env-configuration","tag-firefly-iii-importer-env-firefly_iii_url","tag-firefly-iii-mariadb-docker-compose","tag-firefly-iii-mariadb-lts-container","tag-firefly-iii-nginx-reverse-proxy","tag-firefly-iii-oauth-client-setup","tag-firefly-iii-production-docker-deployment","tag-firefly-iii-self-hosted-personal-finance","tag-firefly-iii-static-cron-token","tag-firefly-iii-upgrade-app-key-mismatch","tag-firefly-iii-vps-installation-guide","tag-managed-vps-docker-deployment-serverspan","tag-managed-vps-self-hosting-docker-apps","tag-open-source-budget-tracker-self-hosted","tag-open-source-personal-finance-manager-docker","tag-self-host-firefly-iii-vps-docker-setup","tag-self-hosted-budgeting-app-vps","tag-self-hosted-finance-app-linux-vps","tag-self-hosted-financial-data-privacy-server","tag-vps-docker-compose-self-hosted-apps"],"_links":{"self":[{"href":"https:\/\/www.serverspan.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2792","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.serverspan.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.serverspan.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.serverspan.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.serverspan.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2792"}],"version-history":[{"count":1,"href":"https:\/\/www.serverspan.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2792\/revisions"}],"predecessor-version":[{"id":2794,"href":"https:\/\/www.serverspan.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2792\/revisions\/2794"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.serverspan.com\/blog\/index.php?rest_route=\/wp\/v2\/media\/2793"}],"wp:attachment":[{"href":"https:\/\/www.serverspan.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2792"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.serverspan.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2792"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.serverspan.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2792"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}