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

推荐订阅源

F
Full Disclosure
WordPress大学
WordPress大学
小众软件
小众软件
Cloudbric
Cloudbric
AWS News Blog
AWS News Blog
腾讯CDC
量子位
人人都是产品经理
人人都是产品经理
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
V
Vulnerabilities – Threatpost
Scott Helme
Scott Helme
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
C
CXSECURITY Database RSS Feed - CXSecurity.com
The Hacker News
The Hacker News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
IT之家
IT之家
Jina AI
Jina AI
Attack and Defense Labs
Attack and Defense Labs
S
SegmentFault 最新的问题
Simon Willison's Weblog
Simon Willison's Weblog
The Cloudflare Blog
阮一峰的网络日志
阮一峰的网络日志
T
Tailwind CSS Blog
Last Week in AI
Last Week in AI
博客园 - 【当耐特】
Google Online Security Blog
Google Online Security Blog
美团技术团队
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
罗磊的独立博客
L
LINUX DO - 最新话题
博客园 - Franky
博客园 - 叶小钗
Apple Machine Learning Research
Apple Machine Learning Research
The Last Watchdog
The Last Watchdog
J
Java Code Geeks
AI
AI
C
Cisco Blogs
酷 壳 – CoolShell
酷 壳 – CoolShell
C
Cyber Attacks, Cyber Crime and Cyber Security
Cisco Talos Blog
Cisco Talos Blog
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
Help Net Security
Help Net Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
云风的 BLOG
云风的 BLOG
I
Intezer
S
Securelist

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 ICMP echo requests on Linux and Windows - Reference Guide Simulate an unreliable network connection with tc and netem on Linux Detecting Rogue DHCP Server - Ittavern.com Basics of the Linux Bash Command History with Examples Getting started with GNU screen - Beginners Guide Basics of Power over Ethernet (PoE) Difference between RSS and Atom SSH Troubleshooting Guide - Ittavern.com Backup Guide - how to secure crucial data SSH - run script or command at login Linux - unmount a busy target safely Visual guide to SSH tunneling and port forwarding Guide to Wireshark display filters Online Security Guide - Ittavern.com My IT EDC tool kit v2212 10 prompts - 1000 AI generated images - openAI Dall-E SSH - How to use public key authentication on Linux Ways to support open-source projects Getting started with nmap - Ittavern.com nginx - simple and native authentication function Linux - How to work with complex commands EICAR test file - riskless method to test your antivirus and firewall solution Linux - connect to a serial port with screen Podman / Docker - expose port only to the localhost of the host machine Tmux - reload .tmux.conf configuration file My use cases for CyberChef Nginx - simple permanent or temporary redirects Getting started with tmux - Ittavern.com Tmux - synchronize the input of all panes within a window Nginx - check your public IP CyberChef - How to remove empty lines
Wimage - Hosting Open-Source Image Uploader with Podman and external S3 Storage
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