Plik
Overview
Plik is a scalable, open-source, self-hosted service for temporary file uploads and sharing. Users upload one or more files through a clean web interface or an HTTP API, choose how long the files 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 Plik a flexible replacement for emailing large attachments or standing up ad hoc file drops.
The SecureAnyCloud image installs the official prebuilt Plik server at /opt/plik/plikd. It runs 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 and accepts anonymous uploads from anyone. This image does not. 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. It 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 are 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. The disk is captured into the image, so every VM is provisioned with it. The server binary and web frontend stay on the OS disk.
What you get:
- 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 and 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.service, which creates 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, patched at build time
- 24/7 SecureAnyCloud support with a 24-hour response SLA
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet with a subnet.
- VM size: Standard_B2s (2 vCPU, 4 GB RAM) suits evaluation and light sharing. Use Standard_D2s_v5 or larger for busier workloads.
- Data disk: 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.
Deploy from the Azure Portal
Search the Marketplace for Plik on Ubuntu 24.04 and choose your VM size. Attach an NSG that allows TCP 22 (SSH) from your management network. Also allow TCP 443 (the web UI and API) from the networks and users that need to share files. Port 80 only issues an HTTPS redirect.
Deploy from the Azure CLI
RG="plik-prod"; LOCATION="eastus"; VM_NAME="plik-01" IMAGE_URN="sac1647283583153:plik-ubuntu-24-04:default:latest" 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
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:plik-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
--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 StandardConnect via SSH
Connect to the VM over SSH with your admin user and key:
ssh azureuser@<vm-ip>Verify the services are running
Plik listens on loopback 127.0.0.1:8080, and 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/VERSIONYou 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>/. The certificate is self-signed per VM, so your browser warns on first visit. Accept the exception, or trust /etc/nginx/tls/plik.crt, to reach the page. Because authentication is forced, you see a sign-in screen rather than an open upload form.
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 and that 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. It is owned by 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.
Upload and share a file from the API
Load your token into a shell variable, create an upload and add a file. Plik returns a shareable link and gives you the file back on download. Authenticate every request with the X-PlikToken header.
PLIK_TOKEN=$(sudo grep '^PLIK_API_TOKEN=' /root/plik-info.txt | cut -d= -f2-) printf 'Q3 revenue report - sac 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/$FNAMEThe upload is created, and 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.
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 one. Choose an expiry and any options, such as one-shot or password protection, then select 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.
One-shot and expiring links
Set "oneShot": true when you create an upload, and the file self-destructs after a single download. This suits 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 - sac 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.
Manage the server from the admin panel
Your account is an administrator, so the Admin menu opens a dashboard. It shows the server configuration and live statistics, and it lets you manage users and uploads. The statistics show anonymous uploads at zero, because authentication is forced.
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. Confirm the mount, and confirm 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, and holds plik.db (the SQLite metadata database) and the files store. The /config endpoint reports feature_authentication: forced.
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. Use Certbot to obtain one, then copy 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 nginxClients 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, and resolves the instance URL. It writes the root-only info note at /root/plik-info.txt, then disables itself so later 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 is patched at build time and ships with unattended security upgrades enabled.
Support
Every SecureAnyCloud deployment includes 24/7 support with a 24-hour response SLA. Contact sales@secureanycloud.com for help with deployment, configuration or scaling.
This is a repackaged open-source software product, with additional charges for SecureAnyCloud support services. Plik is a trademark of its respective owner. All product and company names are trademarks or registered trademarks of their respective holders. Their use does not imply any affiliation with or endorsement by them.
Deploy on Azure
Launch Plik 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
Overview
This image runs Plik, an open-source, self-hosted service for temporary file uploads and sharing. Users upload one or more files through a clean web interface or the HTTP API, choose how long the files should live, and receive short shareable links that expire automatically.
Optional 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 Plik a flexible replacement for emailing large attachments or standing up ad hoc file drops.
Plik is installed from the official prebuilt release, pinned to version 1.4.2 (github.com/root-gg/plik, MIT licensed). The image contains the plikd server binary and the compiled web frontend, with no source build and no runtime interpreter.
What you get:
- The server (
plikd) binds to loopback only (127.0.0.1:8080). nginx fronts it, terminates TLS on port 443 and is the sole network-facing surface. - HTTPS is required for safe use: API tokens and shared files must never cross the wire in plaintext. Both
plik.serviceandnginx.serviceare managed by systemd and start automatically on boot. - The image is secure by default. Plik normally allows open anonymous uploads, but this image sets
FeatureAuthentication="forced". Every upload requires a valid account or API token, and anonymous uploads are rejected. - Open self-registration is not possible. Plik 1.4.2 has no local-registration route and never auto-creates accounts, and no OAuth provider is configured, so only an administrator can create local users.
- On the first boot of every deployed instance, a one-shot service creates a fresh administrator account with a random password and an API token. It also regenerates a per-instance self-signed TLS certificate and writes the credentials to
/root/plik-info.txt(mode0600, root only). - Two instances launched from the same AMI never share an administrator password, API token or certificate. No credentials, users or files are baked into the image.
- The SQLite metadata database (
plik.db) and the uploaded file store (files/) live under/var/lib/plik, on a dedicated EBS data volume separate from the operating system disk. You can resize the data tier independently. - 24/7 SecureAnyCloud support
Prerequisites
Before you deploy this image, you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group that allows inbound port 22 from your management network and inbound ports 80 and 443 from the networks your users reach Plik on
- The AWS CLI (version 2) installed locally, if you plan to deploy from the command line
Launch the instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images, choose AWS Marketplace AMIs and search for Plik. Select the SecureAnyCloud listing and choose Select, then choose Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings, select your VPC and subnet. Then create or select a security group that allows inbound port 22 from your management network and inbound ports 80 and 443 from the networks your users use. Leave the root volume at the default size or larger. The data volume is attached automatically.
Select Launch instance. First-boot initialisation takes well under a minute after the instance state becomes Running and the status checks pass.
Launch the instance from the AWS CLI
The following command launches an instance from the SecureAnyCloud Plik Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing. Replace <key-name> with your EC2 key pair name and <subnet-id> with your subnet ID. Replace <security-group-id> with a security group that opens ports 22, 80 and 443 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--metadata-options 'HttpTokens=required,HttpEndpoint=enabled' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=plik}]'Connecting to your instance
Connect over SSH. Replace <instance-public-ip> with the public IP address or DNS name shown in the EC2 console, and <key.pem> with the path to your private key.
On the Ubuntu 24.04 image, the login user is ubuntu. For example, run ssh -i <key.pem> ubuntu@<instance-public-ip>.
Retrieve your per-instance credentials
The administrator account and API token are generated uniquely on the first boot of your instance and written to a root-only file. Read them over SSH:
sudo cat /root/plik-info.txtThe file contains the web URL, the admin login and password, and the API token. Keep the file secret, because anyone with the API token can upload to your instance. Confirm the installed version and that both services are running:
sudo cat /opt/plik/VERSION systemctl is-active plik nginxYou should see plik 1.4.2 and both services reported as active.
Verify the security model from the command line
Confirm that the Plik server is bound to loopback only and that nginx is the sole network-facing listener on ports 80 and 443:
sudo ss -tlnp | grep -E ':(80|443|8080)\b'plikd listens on 127.0.0.1:8080 (loopback only), while nginx listens on 0.0.0.0:80 and 0.0.0.0:443.
Now confirm that anonymous uploads are rejected. Authentication is forced, so an unauthenticated upload request returns an error:
curl -ks -o /dev/null -w '%{http_code}\n' -X POST https://127.0.0.1/upload -H 'Content-Type: application/json' -d '{}'This returns 400, and the response body reads anonymous uploads are disabled. Every upload must present the per-instance account or API token.
Sign in to the web interface
Browse to https://<instance-public-ip>/ over HTTPS. The TLS certificate is self-signed and generated uniquely for your instance, so your browser warns about it until you install a certificate from a trusted certificate authority (see Bring your own domain and certificate below). Because authentication is forced, you go straight to the sign-in page.
Sign in with the login admin and the password from /root/plik-info.txt. You land on the upload page. Drag in files and choose your upload options: one-shot self-destruct, streaming, removable, end-to-end encryption, password and comment. Set an expiration up to the configured maximum.
Select Upload to create the share. Plik generates a short share link to send to recipients and a separate admin URL for managing the upload. It shows when the share expires, and it offers actions to download a zip archive, show a QR code, add more files or delete the upload.
Script uploads with the API token
The API token lets you upload from scripts and pipelines without the browser. The commands below create an upload, add a file to it, and download the file back to prove the round trip. Replace <your-plik-token> with the PLIK_API_TOKEN value from /root/plik-info.txt.
TOKEN='<your-plik-token>' echo 'hello from sac' > /tmp/plik-demo.txt
UPID=$(curl -ksf -X POST -H "X-PlikToken: $TOKEN" -H 'Content-Type: application/json' https://127.0.0.1/upload -d '{}' | jq -r .id)
FJSON=$(curl -ksf -X POST -H "X-PlikToken: $TOKEN" -F "file=@/tmp/plik-demo.txt" https://127.0.0.1/file/$UPID)
FID=$(echo "$FJSON" | jq -r .id);
FNAME=$(echo "$FJSON" | jq -r .fileName)
curl -ksf -H "X-PlikToken: $TOKEN" "https://127.0.0.1/file/$UPID/$FID/$FNAME"The final command prints hello from SecureAnyCloud, downloaded back through the share link. This is a full authenticated upload and download round trip over TLS. The plik command-line client is also bundled under /opt/plik/clients for scripted uploads with a friendlier interface.
Manage your account and review statistics
Open the admin menu in the web interface to review your account configuration and usage statistics. The configuration covers maximum file size, maximum user size, and default and maximum time to live. Manage your API tokens under the Tokens tab.
The dedicated data volume
The SQLite metadata database and all uploaded files live under /var/lib/plik, on a dedicated EBS volume separate from the operating system disk. Confirm the layout:
df -h /var/lib/plikBecause the data tier is on its own volume, you can resize it independently of the root disk and snapshot it for backups. To back up Plik, snapshot this EBS volume, or stop the service and copy /var/lib/plik/plik.db and /var/lib/plik/files/.
Bring your own domain and certificate
The image ships with a per-instance self-signed certificate, so the service is encrypted from the first request. For production, put Plik behind a real domain and a certificate from a trusted authority.
Point a DNS record at your instance. Then replace the certificate and key that nginx references at /etc/nginx/tls/plik.crt and /etc/nginx/tls/plik.key with your own (for example, from Let's Encrypt), and reload nginx:
sudo nginx -t && sudo systemctl reload nginxShare links use the host in each request. Once you reach Plik on your own domain, the links it generates use that domain automatically, so there is no base URL to configure.
Service management
Both services are managed by systemd:
systemctl status plik nginxTo rotate the API token, run the Plik CLI against the metadata backend:
sudo /opt/plik/plikd --config /etc/plik/plikd.cfg token create --login adminRestart the stack after any configuration change:
sudo systemctl restart plik nginxSupport
Every subscription includes 24/7 technical support from SecureAnyCloud engineers by email and live chat. Support covers deployment, first-boot credential retrieval, upgrades to new Plik releases, reverse proxy and TLS termination, bringing your own domain and CA certificate, authentication and upload policy tuning, and data volume backups. Email sales@secureanycloud.com. Critical issues receive a one-hour average response time.
Deploy on AWS
Launch Plik with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com