Deployment guide

Suwayomi

Overview

Suwayomi Server is a free, open-source, Tachiyomi-compatible manga server and reader. It installs extension sources, browses and searches their catalogs, and serves a browser reading UI where you read chapters or download them for offline access. The library, reading progress and downloads all stay on a server you own.

The SecureAnyCloud image installs Suwayomi Server 2.3.2243 from the official GitHub release jar with SHA-256 verification, on a headless OpenJDK 21 runtime. Two things differ from a stock Suwayomi install:

  • Suwayomi ships with authentication disabled (server.authMode = "none"), which would leave the reader open to anyone who can reach the port. This image therefore binds Suwayomi to the loopback interface only and fronts it with an nginx reverse proxy on port 80 that requires HTTP authentication on every request. A single anonymous endpoint, /healthz, is kept for load-balancer and monitoring probes.
  • No credential ships in the image. A one-shot first-boot service generates a 24-character admin password that is unique to this VM. It writes the password into the proxy's credential store and into a root-only file. Until that has happened, neither the reader nor the proxy serves any request.

What you get:

  • Suwayomi Server 2.3.2243 as a single self-contained jar at /opt/suwayomi/Suwayomi-Server.jar, with the web reader UI bundled inside it
  • Headless OpenJDK 21 JRE from Ubuntu 24.04 noble main
  • suwayomi.service running as the unprivileged suwayomi service user, bound to 127.0.0.1:4567
  • The server data root on a dedicated 40 GiB Azure data disk mounted at /var/lib/suwayomi, holding the library database, downloaded chapters, thumbnails, extension sources, the cached web UI and server.conf
  • An nginx reverse proxy on port 80 with HTTP Basic authentication and an unauthenticated /healthz endpoint
  • A per-VM admin password generated at first boot and stored in /root/suwayomi-credentials.txt (mode 0600)
  • Unattended security upgrades enabled
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key, and a VNet with a subnet.

Standard_B2s (2 vCPU, 4 GB RAM, 1024m JVM heap by default) suits a personal or small-group library. For a large library, heavy concurrent reading or bulk downloading, raise the VM size and the JVM heap together (Step 12).

Configure the NSG inbound rules to allow 22/tcp from your management CIDR and 80/tcp from the client CIDRs that need the reading UI. You do not need to open 4567/tcp. Suwayomi binds only to loopback and is reached exclusively through the proxy.

The reader is served over plain HTTP on port 80. For production, put TLS in front of it with an Azure Application Gateway, Azure Front Door, or your own reverse proxy with a certificate for your domain.

Step 1-3 - Deploy the VM and connect over SSH

Deploy the VM from the Azure Marketplace offer, then connect over SSH as azureuser:

ssh azureuser@<vm-ip>
4

Check service status and health

Confirm that both services are active and that the unauthenticated health endpoint responds:

sudo systemctl is-active suwayomi.service nginx.service curl -s -o /dev/null -w 'healthz: HTTP %{http_code}\n' http://127.0.0.1/healthz

Both units report active, and /healthz returns HTTP 200. nginx serves /healthz directly and never proxies it to Suwayomi. You can point a load balancer or monitor at it as a front-door liveness signal, with no credential.

5

Read the per-VM admin credentials

First boot wrote the admin password, which is unique to this VM, to a root-only file. Read it with sudo:

sudo cat /root/suwayomi-credentials.txt

The file lists SUWAYOMI_ADMIN_USER (admin), SUWAYOMI_ADMIN_PASSWORD (the per-VM password) and SUWAYOMI_URL. Store the password safely. It is the only credential that unlocks the reader.

6

Test authentication

Confirm that the proxy refuses anonymous requests, accepts the per-VM password and refuses a wrong password:

curl -s -o /dev/null -w 'anonymous: HTTP %{http_code}\n' http://127.0.0.1/
curl -s -u 'admin:<SUWAYOMI_ADMIN_PASSWORD>' -o /dev/null -w 'with password: HTTP %{http_code}\n' http://127.0.0.1/
curl -s -u 'admin:wrong-password' -o /dev/null -w 'wrong password: HTTP %{http_code}\n' http://127.0.0.1/

You get 401, 200, 401. The GraphQL API behaves the same way through the proxy: /api/graphql on port 80 also requires the credential. Nothing on the server is reachable anonymously except /healthz.

7

Verify the version, runtime, bind address and data disk

From the VM itself, Suwayomi's own GraphQL API answers without a credential on 127.0.0.1:4567. That interface is not exposed to the network. Run these checks on the VM:

curl -sS -H 'Content-Type: application/json' \
  --data '{"query":"{ aboutServer { version buildType } }"}' \
  http://127.0.0.1:4567/api/graphql; echo java -version 2>&1 | head -1 ss -tlnH | grep 4567 findmnt /var/lib/suwayomi

aboutServer reports v2.3.2243 / Stable. The socket line matters most for security. It reads [::ffff:127.0.0.1]:4567, an IPv4-mapped loopback socket, which confirms the server is not listening on any routable interface. findmnt confirms that the data root is the dedicated Azure data disk and not the OS disk.

8

Sign in to the reading UI

Browse to http://<vm-ip>/. When your browser prompts for credentials, enter admin and the password from Step 5. The Library view loads. It is empty on a fresh VM, because no library data ships in the image.

The left-hand rail holds the whole application: Library (your saved titles), Updates, History, Browse (sources and extensions), Downloads, Settings and About.

9

Add an extension source

Suwayomi reads catalogs through Tachiyomi-compatible extensions. Extensions come from repositories that you choose and add yourself. No repository is pre-configured in this image.

In the UI, open Browse. The Source tab lists the available sources. On a fresh VM it shows only Local source, the built-in source that serves comics you place on the VM yourself (Step 10). Installed extensions appear on the Extension tab after you add a repository under Settings > Browse > Extension repositories.

Choose your repositories deliberately. You are responsible for the sources you add and the content you access through them. SecureAnyCloud does not bundle, endorse or host any catalog.

10

Serve your own comics with the Local source

The Local source reads directly from the data disk, so you can host your own scans or legally obtained archives without any extension. Use one directory per title, and one directory (or one CBZ file) per chapter:

/var/lib/suwayomi/local/ └── My Comic/ ├── cover.jpg ├── details.json └── Chapter 1/ ├── 001.jpg ├── 002.jpg └── 003.jpg

Create the directory, copy your page images in, then restart the server so it re-indexes:

sudo install -d -o suwayomi -g suwayomi -m 0755 "/var/lib/suwayomi/local/My Comic/Chapter 1"
sudo systemctl restart suwayomi.service for i in $(seq 1 60); do curl -sf -o /dev/null http://127.0.0.1:4567/ && break; sleep 2; done curl -s -u 'admin:<SUWAYOMI_ADMIN_PASSWORD>' -o /dev/null -w 'reader after restart: HTTP %{http_code}\n' http://127.0.0.1/

The reader returns HTTP 200 again after the restart. In the UI, Browse > Local source > Latest now lists your title. Open it and tap the heart to add it to your Library.

11

Read a chapter

Open a title from the Library to reach its detail view, which shows the cover, metadata, description and chapter list. For local titles, the optional details.json fields (title, author, artist, description, genre, status) appear here.

Click a chapter to open the reader. Pages render full width with a page counter. You can set the reading mode (paged, continuous vertical, right-to-left) per title and globally under Settings > Reader. Reading progress is stored server-side, so you resume in the same place from any browser.

12

Tune the JVM heap and VM size

The service runs with a 1024 MB maximum heap, which suits a personal library on Standard_B2s. Check the current setting:

systemctl cat suwayomi.service | grep -E 'ExecStart|Xmx'

To raise it, move to a larger VM size first, then add a systemd drop-in. The heap flags are part of ExecStart, so the override must clear and restate the whole line. Create /etc/systemd/system/suwayomi.service.d/10-heap.conf:

[Service] ExecStart= ExecStart=/usr/bin/java -Djava.awt.headless=true -Xms512m -Xmx3072m -Dsuwayomi.tachidesk.config.server.rootDir=/var/lib/suwayomi -jar /opt/suwayomi/Suwayomi-Server.jar

Then run sudo systemctl daemon-reload && sudo systemctl restart suwayomi.service.

Never set a maximum heap larger than about 75% of the VM's RAM. The image deliberately ships no swap, because Azure manages swap on the ephemeral resource disk and a swap file baked into an image fails Azure certification. An oversized heap is therefore killed by the OOM reaper rather than paged.

13

Manage server settings and backups

Everything Suwayomi exposes is under Settings: reader defaults, library categories and update behavior, download locations, extension repositories, backups, and the server settings that mirror server.conf.

Take care with two settings, because changing them removes the protection this image adds:

  • Do not change the server IP or port from 127.0.0.1:4567. The proxy expects the server there, and exposing it directly would publish an unauthenticated reader.
  • Suwayomi's own authentication is deliberately off. The nginx layer authenticates you. You can also turn on Suwayomi's built-in authentication, but then you manage two credentials.

Suwayomi writes automatic backups into the data root. List them and inspect what the data disk holds:

sudo ls -la /var/lib/suwayomi/backups
sudo du -sh /var/lib/suwayomi 2>/dev/null df -h /var/lib/suwayomi | tail -1

The library, downloads and backups all live on the dedicated data disk. You can snapshot that disk in Azure for a point-in-time copy of the whole library, and grow it without touching the OS disk.

14

Change the reader password

The reader credential is an nginx htpasswd entry, so rotate it with htpasswd. Replace <new-password> with your own password:

sudo htpasswd -bB /etc/nginx/.suwayomi_htpasswd admin '<new-password>'
sudo chown root:www-data /etc/nginx/.suwayomi_htpasswd
sudo chmod 0640 /etc/nginx/.suwayomi_htpasswd
sudo nginx -t && sudo systemctl reload nginx.service

-B stores the password bcrypt-hashed. To keep the password out of your shell history, drop the -b flag and the argument (sudo htpasswd -B /etc/nginx/.suwayomi_htpasswd admin). htpasswd then prompts for the password instead.

Update /root/suwayomi-credentials.txt yourself if you want that file to stay accurate. Nothing reads it at runtime. It is a record for you.

15

Patching, logs and troubleshooting

Unattended security upgrades are enabled, so the OS patches itself. Check their status:

systemctl is-enabled unattended-upgrades.service cat /etc/apt/apt.conf.d/20auto-upgrades

Server logs go to the journal. Suwayomi also writes its own log files to the data disk:

sudo journalctl -u suwayomi.service -n 20 --no-pager sudo ls -la /var/lib/suwayomi/logs

Common checks:

  • Browser prompts repeatedly (401 loop). The password is wrong. Re-read it with sudo cat /root/suwayomi-credentials.txt, or set a new one (Step 14).
  • HTTP 502 from the proxy. Suwayomi is not up. Run sudo systemctl status suwayomi.service and sudo journalctl -u suwayomi.service -n 50. A JVM start takes a few seconds. A heap set larger than the VM's RAM (Step 12) fails here.
  • HTTP 500 on the reader but /healthz returns 200. The proxy's credential file is missing. This is the fail-closed state. Restore the file with Step 14.
  • A new title does not appear. Restart the server so the Local source re-indexes (Step 10), and check that suwayomi owns the directory. A chapter directory with no page images is indexed as an empty chapter.
  • ERROR CEFManager -- Failed to set up CEF / CefException: CEF is disabled in the journal at every start. This is expected and harmless. CEF is Suwayomi's optional embedded Chromium WebView, used only for sources that need to solve an in-browser challenge. This image sets server.kcefEnabled = false, because CEF downloads a full Chromium runtime at first use. A headless server does not need that runtime, and it would add a large unpatched attack surface to the image. Suwayomi logs the refusal at ERROR level, but nothing is broken. If you need a source that requires a browser challenge, enable kcefEnabled under Settings and accept that download, or configure FlareSolverr instead.
  • Suwayomi rewrites server.conf. This is normal. On its first start, Suwayomi normalizes the file into its own flat server.<key> = <value> reference form and keeps your values. Edit the file in that form, or use the UI.

Security

  • Single front door. The Suwayomi server binds only to 127.0.0.1:4567 and is never exposed to the network. nginx on port 80 is the only entry point, and it requires HTTP authentication for every path except /healthz.
  • No shared credential. The admin password is generated uniquely on each VM's first boot and stored in /root/suwayomi-credentials.txt (mode 0600, root only). No shared or default credential exists in the image, and the server ships with no in-app account at all.
  • Hardened service. The service runs as the unprivileged suwayomi user under systemd hardening (NoNewPrivileges, ProtectSystem=full, PrivateTmp, and write access confined to the data root).
  • Restrict the network. Limit port 80 in your NSG to the client CIDRs that need the reader, and keep port 4567 closed. Terminate TLS in front of the VM before production.
  • Protect the data. The library and downloads live on a dedicated data disk. You can encrypt it with Azure disk encryption and snapshot it independently.

You are responsible for the extension repositories you add and the content you access through them. SecureAnyCloud bundles no catalog and no repository.

Support

SecureAnyCloud provides 24/7 technical support by email and live chat. Support covers deployment and VM sizing, reverse-proxy and authentication setup, extension-source configuration, data-disk management and backups, and JVM administration. Email sales@secureanycloud.com.

Deploy on Azure

Launch Suwayomi Server 2.3.2243 on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure