P1
Applications Azure

Publify 10 on Ubuntu 24.04 on Azure User Guide

| Product: Publify 10 on Ubuntu 24.04 LTS on Azure

Overview

Publify is a long running open source, self hosted blogging and web publishing engine, first released as Typo and one of the oldest Ruby on Rails applications still actively maintained. It gives you your own blog rather than a page on someone else's platform: a web admin for writing, editing and publishing articles and standalone pages, organising them with categories and tags, moderating reader comments, and publishing Atom and RSS feeds, with drafts, a built in text formatter and media uploads.

Publify ships as Ruby on Rails source rather than a finished server, so the cloudimg image supplies the production 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, served by the Puma application server behind an nginx reverse proxy, and 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 a fresh Rails SECRET_KEY_BASE, a fresh PostgreSQL password and a unique, randomly generated administrator password are created, written to a root only file, and only then is the site brought up. A friendly welcome post is published on first boot so the front page shows a real rendered blog straight away, never Publify's empty first run setup wizard. Backed by 24/7 cloudimg support.

What is included:

  • 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 the publify systemd service, backed by a local PostgreSQL 16 database
  • nginx on port 80 as the reverse proxy, with an unauthenticated /healthz endpoint 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
  • A fully patched Ubuntu 24.04 LTS base with unattended security updates enabled

Before you begin

You will need an Azure subscription, permission to launch a VM, and an SSH key pair. Publify fits comfortably on a Standard_B2s (2 vCPU, 4 GiB) instance. The image opens TCP 22 (SSH), 80 (web) and 443 (optional TLS you configure). Nothing else is exposed; 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, choose Create, pick your resource group and region, select the Standard_B2s size, provide your SSH public key for the azureuser admin account, and 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.

az vm create \
  --resource-group my-rg \
  --name publify \
  --image <marketplace-image-urn> \
  --size Standard_B2s \
  --admin-username azureuser \
  --generate-ssh-keys \
  --public-ip-sku Standard

Then open the web port on the VM's network security group:

az vm open-port --resource-group my-rg --name publify --port 80 --priority 900

Retrieve 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. Sign in to the VM over SSH and read it:

ssh azureuser@<vm-ip>
sudo cat /root/publify-credentials.txt

You will see the per VM values (the password is unique to your instance):

WEB_URL=http://<vm-ip>/
ADMIN_EMAIL=admin@publify.local
ADMIN_PASSWORD=********
publify.host=<vm-ip>

Terminal showing the per VM Publify credentials file with mode 600 root:root and the administrator password redacted

The login name is admin. Change the password from within Publify after your first sign in.

Check the services are healthy

The site is served by three systemd units: postgresql, publify (Puma) and nginx. Confirm they are all active and that the application and database are bound to loopback only:

sudo systemctl is-active postgresql publify nginx
curl -s -o /dev/null -w 'GET /healthz -> HTTP %{http_code}\n' http://localhost/healthz
curl -s -o /dev/null -w 'GET / -> HTTP %{http_code}\n' http://localhost/

Both requests return 200, and the service check prints active three times.

Terminal showing the postgresql, publify and nginx services active, the Publify version and first boot complete

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.

Terminal showing puma and PostgreSQL bound to loopback only, the front page returning 200, the admin area refusing unauthenticated access, and exactly one administrator user

Sign in

Open http://<vm-ip>/admin in your browser to reach the sign in form, or click the Admin link in the blog's sidebar. Enter admin and the password from the credentials file.

The Publify sign in form with the login and password fields

The admin dashboard

After signing in you land on the Publify dashboard. The top navigation gives you Articles, Notes, Pages, the Media Library, Design, Settings and SEO, and the overview panel links straight to writing a post, changing your blog presentation and updating your profile or password.

The Publify admin dashboard after signing in, showing the navigation, the running version and the article and comment counts

Your first task should be to change the administrator password: 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, with the blog title, the archives and links sidebar, an RSS feed link and a comments section, so you can confirm the site is live and serving real content immediately.

The Publify blog front page rendering the welcome post in full with the sidebar, archives and RSS feed

Writing and publishing

To publish your own content, sign in, choose Articles then New article, give it a title, write the body, add categories or tags if you like, and choose Publish. Saving without publishing keeps it 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.

A published Publify article rendered on its own page with the full body and the comment form

Edit or delete the welcome post from Articles once you are ready to use the blog for your own writing.

First boot and patching

The per VM secrets are created by a one shot first boot service that runs once, before the site is exposed, and records a sentinel when it completes. The base keeps patching itself with unattended security updates. Confirm first boot completed and the OS is current:

test -f /var/lib/cloudimg/publify-firstboot.done && echo "first boot: complete"
uname -r
apt-mark showhold

apt-mark showhold prints nothing, meaning no packages are held back from security updates.

Terminal showing the first boot sentinel present, the auto upgrade configuration enabled, the running kernel and no held back packages

Optional: outbound email

Email is entirely optional; the blog works fully over the web without any mail server. Out of the box, mail (new comment notifications, password resets) is generated but not delivered, so nothing crashes 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_cloudimg_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 publify

Optional: a custom domain and HTTPS

Point a DNS record at the VM's public IP. To terminate TLS, install a certificate with certbot against your domain:

sudo certbot --nginx -d your-domain.example

Then set the blog's own base URL so 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 changing configuration apply it with sudo systemctl restart publify.

Backups

Publify keeps all content in PostgreSQL and uploaded media under the application directory. Take a consistent database dump on a schedule and copy it, together with the uploads, off the instance:

sudo -u postgres pg_dump publify_production > /var/backups/publify-$(date +%F).sql

Uploaded images live under /opt/publify/app/public/uploads. Store backups off the instance and never copy /etc/publify/publify.env (which holds the database password and the Rails secret key) into a world readable location.

Support

This image is published by cloudimg 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; cloudimg 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.