惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Blog — PlanetScale
Blog — PlanetScale
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Vercel News
Vercel News
B
Blog
腾讯CDC
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
N
Netflix TechBlog - Medium
L
LangChain Blog
F
Fortinet All Blogs
T
The Blog of Author Tim Ferriss
人人都是产品经理
人人都是产品经理
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
I
InfoQ
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
aimingoo的专栏
aimingoo的专栏
D
DataBreaches.Net
Stack Overflow Blog
Stack Overflow Blog
The Cloudflare Blog
Last Week in AI
Last Week in AI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园 - 三生石上(FineUI控件)
T
Tailwind CSS Blog

Ittavern.com

Switching from Hugo to picopaper Encryption using SSH Keys with age in Linux ETag in nginx - Simple Resource Caching Sending nginx Logs to Loki with Grafana Alloy How to: Cisco ISE backup to SFTP repository with public key authentication Dummy IP & MAC Addresses for Documentation & Sanitization Deploying ISSO Commenting System for Static Content using Docker Generate a Vanity v3 Hidden Service Onion Address with mkp224o ssh-audit Primer - Audit your SSH Server mtr - More Detailed Traceroute - Network Troubleshooting My Personal Backup Strategy - August 2024 iperf3 - User Authentication with Password and RSA Public Keypair Adding a trash can to Linux with trash-cli Bandwidth Measurement using netcat on Linux Getting started with rsync - Comprehensive Guide Cron Jobs on Linux - Comprehensive Guide with Examples SSH Server Hardening Guide v2 Port Knocking with knockd and Linux - Server Hardening Getting started with rclone - Data transmission Getting started with dig - DNS troubleshooting Getting started with Fail2Ban on Linux Getting started with netcat on Linux with examples URL explained - The Fundamentals Troubleshooting Asking The Right Questions Create tmux layouts using bash scripts Getting started with tcpdump - Ittavern.com Curl on Linux - Reference Guide Getting started with nmap scripts My Offsite Backup - March 2023 Getting started with iperf3 - Network Troubleshooting
Wimage - Hosting Open-Source Image Uploader with Podman a...
2026-03-29 · via Ittavern.com

I was looking for a simple image hosting platform that I could self-host. Picsur and some other candidates are no longer maintained or are simply overkill. My Frankenstein’s monster of a solution for fetching images from my notes app is not the way to go.

So, after talking about this with a friend of mine, he simply created a simple platform for this - open-source and self-hostable. This is not an ad and I am not getting paid (although I should be @Frank).

Wimage is a simple open-source image uploading and hosting platform designed for personal and private use with guest keys for your friends, family and team. It has a great API and a simple UI in the browser. Metadata is stored in a local SQLite database and the images are saved in S3-compatible storage. By default, it uses a local Garage instance (which we don’t need) and Docker.

In this article I want to share a short instruction on how to host Wimage yourself with Podman and an external S3-compatible storage provider.

Requirements #

Just my personal setup, feel free to change things up. I assume the following is set up already:

  • Ubuntu 24.04
  • Installed: Podman (should work with Docker)
  • S3-compatible hosting provider (I use Backblaze), as well as network access to it (443/TCP)
  • Network access to Codeberg via HTTPS as we have to build the image ourselves
  • Reverse proxy for TLS termination - I use nginx, but Caddy and Apache will will work as well
  • Domain pointing to the host server

Installation #

So, this is a fairly new project and this setup it working as of now and can change any time. I’ll update this article if something changes.

Some considerations, I use the -e env variable options in the Podman run command instead of the .env file and a bind mount instead of a name volume for the local database for the meta data.

All configuration options can be found in the README on Codeberg.

Building Image #

mkdir -p /path/to/your/wimage
cd /path/to/your/wimage

git clone https://codeberg.org/fracwaffle/wimage.git
cd wimage

podman build -t localhost/wimage:latest .
# That is it

Preparation for S3 #

Fill out the information of the S3-ednpoint and make sure that the container can access it via HTTPS:

-e S3_ENDPOINT_URL="https://s3.eu-central-003.backblazeb2.com" \
-e S3_BUCKET="name-of-your-bucket" \
-e S3_ACCESS_KEY_ID="344325252535235235" \
-e S3_SECRET_ACCESS_KEY="HgfjhkfhFHhthdhdf/gsrtgg" \
-e S3_REGION=eu-"central-003" \

Side note: make sure that the bucket is private, use the NAME of the bucket, and not the ID and generate an API key that can write+read. The process is different with every provider, but should be straight forward.

Admin Access to application #

Generate a long and secure string - this key is being used for uploads, guest key generation and general administration.

Use openssl rand -base64 32 your your favorite password manager to generate it.

-e ADMIN_KEY=longandsecurekeylgrhgihrsigdsrighr \
-e BASE_URL="https://wimage.example.com" \

Storage for SQLite #

As mentioned before, I use a bind mount - feel free to use a named volume:

Create directory:

mkdir /path/to/your/wimage/data

And those options for later.

-e DATABASE_PATH=/app/data/wimage.db \ #just keep it
-v /path/to/your/wimage/data:/app/data

Optional Hardening #

Making the container inside read-only, strips all capabilities that are not needed and prevents the container from getting more. Will talk about more those option in a future post.

    --read-only \
    --security-opt no-new-privileges \
    --cap-drop ALL \
    --cap-add=CHOWN \
    --cap-add=NET_BIND_SERVICE \
    --cap-add=SETGID \
    --cap-add=SETUID \

Putting everything together #

So, the application in the image listens to port 8000/TCP and we are going to limit it to our localhost so only the traffic through the reverse-proxy can reach it.

The combined command looks like this then:

podman run --replace -d \
    --name container-wimage \
    -p 127.0.0.1:8000:8000 \
    -e S3_ENDPOINT_URL="https://s3.eu-central-003.backblazeb2.com" \
    -e S3_BUCKET="name-of-your-bucket" \
    -e S3_ACCESS_KEY_ID="344325252535235235" \
    -e S3_SECRET_ACCESS_KEY="HgfjhkfhFHhthdhdf/gsrtgg" \
    -e S3_REGION=eu-"central-003" \
    -e ADMIN_KEY=longandsecurekeylgrhgihrsigdsrighr \
    -e BASE_URL="https://wimage.example.com" \
    -e DATABASE_PATH=/app/data/wimage.db \ #just keep it
    -v /path/to/your/wimage/data:/app/data
    --read-only \
    --security-opt no-new-privileges \
    --cap-drop ALL \
    --cap-add=CHOWN \
    --cap-add=NET_BIND_SERVICE \
    --cap-add=SETGID \
    --cap-add=SETUID \
    localhost/wimage:latest

The container should be running!

A quick health check can be done with curl:

curl -L 127.0.0.1:8000/health
{"status":"ok","database":"ok","s3":"ok"}

Now, point your reverse proxy with the certificate and domain to 127.0.0.1:8000 and the service should be accessible.

The web interface can be accessed via https://wimage.example.com and the usage of the API is explained in the README and API Swagger description via https://wimage.example.com/docs

Have fun


Upgrade to new Version #

Check for new version on the repo.

cd /path/to/your/wimage/wimage

git pull main

podman build -t localhost/wimage:latest .

# Check change notes and adjust env variables IF needed, otherwise just run the same command again --replace will replace the old container