Plik on Ubuntu 24.04 on Azure User Guide
Overview
Plik is a scalable, open source, self hosted temporary file upload and sharing service. Users upload one or more files through a clean web interface or an HTTP API, choose how long they should live, and receive short shareable links that expire automatically. One shot links that self destruct after a single download, password protected uploads, streaming uploads that are never written to disk, and markdown comments make it a flexible replacement for emailing large attachments or standing up ad hoc file drops.
The cloudimg image installs the official prebuilt Plik server at /opt/plik/plikd, running as the plik service bound to loopback 127.0.0.1:8080, behind nginx which terminates TLS on port 443. The metadata database and the uploaded files live on a dedicated data disk, so the appliance is production ready within minutes of launch with no package installation and no proxy configuration.
Secure by default, no anonymous uploads: Plik ships wide open by default, accepting anonymous uploads from anyone. This image never does that. Authentication is forced, so every upload requires a valid account or API token, and open self registration is disabled. A plik-firstboot.service oneshot creates a unique administrator account and API token on each VM's first boot, writes them to a root only file, regenerates a per VM TLS certificate, and then disables itself. The plik service requires the first boot unit, so it can never serve before the per VM credentials exist. No two VMs share credentials and none is baked into the image.
Dedicated data disk: the SQLite metadata database (plik.db) and the file store (files/) live on a dedicated data disk mounted at /var/lib/plik, captured into the image so every VM is provisioned with it. The server binary and web frontend stay on the OS disk.
What is included:
- Plik 1.4.2, the official prebuilt server binary and bundled web frontend
- The full Plik web UI, served over TLS: upload, set an expiry, get shareable links
plik.servicebound to loopback127.0.0.1:8080- nginx terminating TLS on
443, with80redirecting to HTTPS and an unauthenticated/healthzprobe plik-firstboot.servicefor the first boot admin account, API token, per VM TLS certificate and info note- Forced authentication with anonymous uploads disabled and self registration turned off
- A dedicated data disk mounted at
/var/lib/plikfor the metadata database and file store - Ubuntu 24.04 LTS base, fully patched
- 24/7 cloudimg support, 24h response SLA
Prerequisites
An active Azure subscription, an SSH key pair, and a VNet with a subnet. Recommended VM size: Standard_B2s (2 vCPU, 4 GB RAM) for evaluation and light sharing, or a Standard_D2s_v5 or larger for busier workloads. The dedicated data disk holds your uploads, so resize it to suit how much you expect to store at once (the default maximum time to live is 30 days).
Step 1: Deploy from the Azure Portal
Search the Marketplace for Plik on Ubuntu 24.04, choose your VM size, and attach an NSG that allows TCP 22 (SSH) from your management network and TCP 443 (the web UI and API) from the networks and users that need to share files. Port 80 only issues an HTTPS redirect.
Step 2: Deploy from the Azure CLI
RG="plik-prod"; LOCATION="eastus"; VM_NAME="plik-01"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/plik-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create -g "$RG" --name plik-vnet --address-prefix 10.90.0.0/16 --subnet-name plik-subnet --subnet-prefix 10.90.1.0/24
az network nsg create -g "$RG" --name plik-nsg
az network nsg rule create -g "$RG" --nsg-name plik-nsg --name allow-ssh --priority 100 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create -g "$RG" --nsg-name plik-nsg --name allow-https --priority 110 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 443 --access Allow --protocol Tcp
az vm create -g "$RG" --name "$VM_NAME" --image "$GALLERY_IMAGE_ID" \
--size Standard_B2s --storage-sku StandardSSD_LRS \
--admin-username azureuser --ssh-key-values "$SSH_KEY" \
--vnet-name plik-vnet --subnet plik-subnet --nsg plik-nsg --public-ip-sku Standard
Step 3: Connect via SSH
ssh azureuser@<vm-ip>
Step 4: Verify the services are running
Plik listens on loopback 127.0.0.1:8080; nginx fronts it with TLS on port 443. The /healthz endpoint is public for load balancer probes; the web UI and API require your per VM credentials.
sudo systemctl is-active plik nginx plik-firstboot
ss -tln | grep -E '127.0.0.1:8080|:443 '
curl -ks -o /dev/null -w 'healthz HTTP %{http_code}\n' https://127.0.0.1/healthz
cat /opt/plik/VERSION
You should see the services active, plikd listening on loopback with nginx on 443, healthz HTTP 200, and the installed Plik version.

The web UI is served over TLS at https://<your-vm-ip>/. Because the certificate is self signed per VM, your browser will warn on first visit; accept the exception (or trust /etc/nginx/tls/plik.crt) to reach it. Because authentication is forced, you are met with a sign in screen rather than an open upload form.

Step 5: Read your per VM credentials and confirm auth is enforced
The administrator account and API token were generated on this VM's first boot and stored in a root only file. Read them and keep them secret. Then confirm that an unauthenticated upload is rejected while the per VM token is accepted.
sudo cat /root/plik-info.txt
echo "anonymous -> HTTP $(curl -ks -o /dev/null -w '%{http_code}' -X POST https://127.0.0.1/upload -d '{}')"
echo "wrong token -> HTTP $(curl -ks -o /dev/null -w '%{http_code}' -X POST -H 'X-PlikToken: wrong' https://127.0.0.1/upload -d '{}')"
PLIK_TOKEN=$(sudo grep '^PLIK_API_TOKEN=' /root/plik-info.txt | cut -d= -f2-)
echo "per-VM tok -> HTTP $(curl -ks -o /dev/null -w '%{http_code}' -X POST -H "X-PlikToken: $PLIK_TOKEN" -H 'Content-Type: application/json' https://127.0.0.1/upload -d '{}')"
The info note holds PLIK_ADMIN_LOGIN, PLIK_ADMIN_PASSWORD and PLIK_API_TOKEN, owned root:root with mode 0600. An anonymous upload returns 400 anonymous uploads are disabled, a wrong token returns 403 invalid token, and only your per VM token returns 200.

Step 6: Upload and share a file from the API
Load your token into a shell variable, create an upload, add a file, and Plik returns a shareable link and gives you the file back on download. Use the X-PlikToken header to authenticate every request.
PLIK_TOKEN=$(sudo grep '^PLIK_API_TOKEN=' /root/plik-info.txt | cut -d= -f2-)
printf 'Q3 revenue report - cloudimg demo\n' > /tmp/report.txt
UPID=$(curl -ks -X POST -H "X-PlikToken: $PLIK_TOKEN" -H 'Content-Type: application/json' https://127.0.0.1/upload -d '{}' | jq -r '.id')
FILE=$(curl -ks -X POST -H "X-PlikToken: $PLIK_TOKEN" -F "file=@/tmp/report.txt" https://127.0.0.1/file/$UPID)
FID=$(echo "$FILE" | jq -r '.id'); FNAME=$(echo "$FILE" | jq -r '.fileName')
echo "share link: https://<your-vm-ip>/#/?id=$UPID"
curl -ks -H "X-PlikToken: $PLIK_TOKEN" https://127.0.0.1/file/$UPID/$FID/$FNAME
The upload is created, the file uploads over TLS with status uploaded, you get a share link that expires with the upload, and downloading it returns the original content byte for byte.

Step 7: Upload and share from the web UI
Sign in at https://<your-vm-ip>/ with the PLIK_ADMIN_LOGIN and PLIK_ADMIN_PASSWORD from your info note. Drag a file onto the upload area (or click to select), choose an expiry and any options such as one shot or password protection, then click Upload.

Plik returns a shareable link and an admin link for the upload, along with a QR code, a zip archive of all files, and a preview of each file. Share the link with anyone who needs the file; it stops working when the upload expires.

Step 8: One shot and expiring links
Set "oneShot": true when creating an upload so the file self destructs after a single download, ideal for sending a secret or a one time file. Combine it with a short time to live for links that expire quickly.
PLIK_TOKEN=$(sudo grep '^PLIK_API_TOKEN=' /root/plik-info.txt | cut -d= -f2-)
printf 'one time secret - cloudimg demo\n' > /tmp/secret.txt
UPID=$(curl -ks -X POST -H "X-PlikToken: $PLIK_TOKEN" -H 'Content-Type: application/json' https://127.0.0.1/upload -d '{"oneShot":true,"ttl":3600}' | jq -r '.id')
FILE=$(curl -ks -X POST -H "X-PlikToken: $PLIK_TOKEN" -F "file=@/tmp/secret.txt" https://127.0.0.1/file/$UPID)
echo "one shot upload $UPID created, expires in 1 hour, file self destructs after the first download"
echo "$FILE" | jq -r '"file: \(.fileName) status: \(.status)"'
The default and maximum time to live are 30 days; the appliance also supports password protected and removable uploads through the same API and the web UI.
Step 9: Manage the server from the admin panel
Your account is an administrator, so the Admin menu opens a dashboard showing the server configuration and live statistics, and lets you manage users and uploads. The statistics confirm that anonymous uploads stay at zero because authentication is forced.

Step 10: Persistence and the data disk
The metadata database and the uploaded files live on the dedicated data disk mounted at /var/lib/plik, so uploads survive reboots and the disk is captured into the image. You can confirm the mount and that authentication is forced.
findmnt -no SOURCE,TARGET,FSTYPE /var/lib/plik
df -h /var/lib/plik | tail -1
sudo ls /var/lib/plik
curl -ks https://127.0.0.1/config | jq '{feature_authentication, maxFileSize, defaultTTL}'
The data disk is ext4 mounted at /var/lib/plik, holding plik.db (the SQLite metadata database) and the files store, and /config reports feature_authentication: forced.

Step 11: Enable a real TLS certificate
The appliance ships with a self signed certificate generated per VM. For production, point a DNS record at the VM and replace it with a CA signed certificate. With certbot you can obtain one and drop it into the nginx TLS paths.
sudo apt-get update && sudo apt-get install -y certbot
sudo certbot certonly --standalone -d your-domain.example.com
sudo cp /etc/letsencrypt/live/your-domain.example.com/fullchain.pem /etc/nginx/tls/plik.crt
sudo cp /etc/letsencrypt/live/your-domain.example.com/privkey.pem /etc/nginx/tls/plik.key
sudo systemctl reload nginx
Clients can then verify the certificate normally instead of using -k.
First boot, credentials and updates
The first boot service creates the per VM administrator account and API token, regenerates the per VM TLS certificate, resolves the instance URL and writes the root only info note at /root/plik-info.txt, then disables itself so subsequent reboots are unaffected. To rotate the API token, run sudo /opt/plik/plikd --config /etc/plik/plikd.cfg token create --login admin and store the new token. The OS ships fully patched with unattended security upgrades enabled.
Support
Every cloudimg deployment includes 24/7 support with a 24 hour response SLA. Contact support@cloudimg.co.uk for help with deployment, configuration or scaling.
This is a repackaged open source software product with additional charges for cloudimg support services. Plik is a trademark of its respective owner. All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.