Publify
Overview
Publify is a long-running, open-source, self-hosted blogging and web publishing engine. It was first released as Typo and is one of the oldest Ruby on Rails applications that is still actively maintained. It gives you your own blog rather than a page on someone else's platform.
A web admin lets you write, edit and publish articles and standalone pages, organise them with categories and tags, and moderate reader comments. Publify publishes Atom and RSS feeds, and it supports drafts, a built-in text formatter and media uploads.
Publify ships as Ruby on Rails source rather than a finished server, so the SecureAnyCloud image supplies the stack around it. Publify is built from source at a current, CI-verified upstream commit (publify_core 10.0.3, Rails 7), with its assets precompiled at build time. The Puma application server runs it behind an nginx reverse proxy, backed by PostgreSQL 16 on the same instance.
Puma is bound to loopback 127.0.0.1:3000 and is never exposed directly. nginx on port 80 is the only way in, plus an unauthenticated /healthz endpoint for load balancer probes.
The image is secure by default. Publify itself never ships a built-in account, and nothing that matters is baked into the image. On the first boot of every VM, the image creates a fresh Rails SECRET_KEY_BASE, a fresh PostgreSQL password and a unique, randomly generated administrator password. It writes them to a root-only file and only then brings the site up. First boot also publishes a welcome post, so the front page shows a real rendered blog straight away instead of Publify's empty first-run setup wizard. The image is backed by 24/7 SecureAnyCloud support.
What you get:
- Publify built from source at a pinned, CI-verified upstream commit (publify_core 10.0.3, Rails 7) under
/opt/publify/app, with assets precompiled at build time - The Puma application server on loopback
127.0.0.1:3000, run by thepublifysystemd service, backed by a local PostgreSQL 16 database - nginx on port 80 as the reverse proxy, with an unauthenticated
/healthzendpoint for load balancer probes - A per-VM Rails
SECRET_KEY_BASE, PostgreSQL password and administrator password, generated on first boot and stored in/root/publify-credentials.txt - A welcome post published on first boot, so the front page is populated the moment the site comes up
- An Ubuntu 24.04 LTS base, patched at build time, with unattended security updates enabled
Before you begin
You need the following:
- An Azure subscription and permission to launch a VM
- An SSH key pair
- A
Standard_B2s(2 vCPU, 4 GiB) instance, on which Publify fits comfortably
The image opens TCP 22 (SSH), 80 (web) and 443 (optional TLS that you configure). Nothing else is exposed, because PostgreSQL and Puma listen only on loopback.
Launch the image
You can launch from the Azure portal or the Azure CLI.
Azure portal: find the offer on the Azure Marketplace and choose Create. Pick your resource group and region, select the Standard_B2s size, and provide your SSH public key for the azureuser admin account. Allow inbound 22, 80 and 443. Create the VM and note its public IP address.
Azure CLI: replace the resource group, name and image reference with your own values.
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:publify-ubuntu-24-04:default:latest
az vm create \
--resource-group my-rg \
--name publify \
--image sac1647283583153:publify-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardThen open the web port on the network security group of the VM:
az vm open-port --resource-group my-rg --name publify --port 80 --priority 900Retrieve the administrator password
Every instance generates its own administrator password on first boot and writes it, together with the site URL, to a root-only file. Connect to the VM over SSH and read the file:
ssh azureuser@<vm-ip>sudo cat /root/publify-credentials.txtThe file shows the per-VM values. The password is unique to your instance:
WEB_URL=http://<vm-ip>/ ADMIN_EMAIL=admin@publify.local ADMIN_PASSWORD=<set-at-first-boot> publify.host=<vm-ip>The login name is admin. Change the password in Publify after your first sign-in.
Check the services are healthy
Three systemd units serve the site: postgresql, publify (Puma) and nginx. Confirm that all three are active and that the application and database are bound to loopback only:
sudo systemctl is-active postgresql publify nginxcurl -s -o /dev/null -w 'GET /healthz -> HTTP %{http_code}\n' http://localhost/healthzcurl -s -o /dev/null -w 'GET / -> HTTP %{http_code}\n' http://localhost/Both requests return 200, and the service check prints active three times.
No default login ships. Publify never seeds a built-in user, the administrator account is unique to your VM, and Puma and PostgreSQL are reachable only over loopback. An unauthenticated request to the admin area is redirected to the sign-in page.
Sign in
Open http://<vm-ip>/admin in your browser to reach the sign-in form, or click the Admin link in the sidebar of the blog. Enter admin and the password from the credentials file.
The admin dashboard
After you sign in, you land on the Publify dashboard. The top navigation gives you Articles, Notes, Pages, the Media Library, Design, Settings and SEO. The overview panel links straight to writing a post, changing the presentation of your blog, and updating your profile or password.
Change the administrator password first. Open the profile link from the dashboard, set a new password and save.
Your blog front page
Open http://<vm-ip>/ to see the public blog. The welcome post published on first boot is rendered in full. The page shows the blog title, the archives and links sidebar, an RSS feed link and a comments section, so you can confirm immediately that the site is live and serving real content.
Writing and publishing
To publish your own content, sign in and choose Articles, then New article. Give the article a title, write the body, optionally add categories or tags, and choose Publish. Saving without publishing keeps the article as a draft. Each published article gets its own page with the full text and a comment form, and appears on the front page and in the RSS feed.
When you are ready to use the blog for your own writing, edit or delete the welcome post from Articles.
First boot and patching
A one-shot first-boot service creates the per-VM secrets. It runs once, before the site is exposed, and records a sentinel file when it completes. The base keeps patching itself with unattended security updates. Confirm that first boot completed and that the OS is current:
test -f /var/lib/sac/data/publify-firstboot.done && echo "first boot: complete"uname -rapt-mark showholdapt-mark showhold prints nothing, which means no packages are held back from security updates.
Optional: outbound email
Email is entirely optional, and the blog works fully over the web without a mail server. Out of the box, Publify generates mail (new comment notifications and password resets) but does not deliver it, so nothing fails before you have a relay. To send real mail, point Publify at your SMTP server by editing the mailer initializer, then restart the service:
# /opt/publify/app/config/initializers/zz_sac_mailer.rb Rails.application.config.action_mailer.delivery_method = :smtp Rails.application.config.action_mailer.smtp_settings = { address: "smtp.your-domain.example", port: 587, user_name: "notifications@your-domain.example", password: "your-smtp-password", authentication: :login, enable_starttls_auto: true }sudo systemctl restart publifyOptional: a custom domain and HTTPS
Point a DNS record at the public IP address of the VM. To terminate TLS, install a certificate with certbot for your domain:
sudo certbot --nginx -d your-domain.exampleThen set the base URL of the blog so that the links it generates are correct. Sign in, open Settings, set the blog URL to https://your-domain.example/ and save. nginx forwards X-Forwarded-Proto to Puma, so once TLS is in place Publify treats the connection as secure. After you change configuration, apply it with sudo systemctl restart publify.
Backups
Publify keeps all content in PostgreSQL and stores uploaded media under the application directory. Take a consistent database dump on a schedule, and copy it off the instance together with the uploads:
sudo -u postgres pg_dump publify_production > /var/backups/publify-$(date +%F).sqlUploaded images live under /opt/publify/app/public/uploads. Store backups off the instance. Never copy /etc/publify/publify.env, which holds the database password and the Rails secret key, into a world-readable location.
Support
SecureAnyCloud publishes this image and includes 24/7 support for the packaged software and its deployment. Publify is distributed under the MIT licence. Publify is a trademark of its respective owners. SecureAnyCloud is not affiliated with, endorsed by or sponsored by the Publify project, and uses the name nominatively to identify the open-source software packaged in this image.
Deploy on Azure
Launch Publify 10 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