843cf9a12d032f119e908836030e68414f2662d0
medium-proxy
Transparent HTTPS proxy that sits between Postiz and api.medium.com.
When Postiz publishes a post to Medium it sends raw Markdown. This proxy intercepts the request and applies two fixes before forwarding to Medium's real API:
| Problem | Fix |
|---|---|
Tables render as plain text with | |
Converts Markdown → HTML (contentFormat: 'html') |
| Stories show a pattern thumbnail instead of a real image | Moves the first <img> to the top of the content |
Everything else (authentication, tags, canonical URL, publish status) is forwarded unchanged.
How it works
Postiz container
│ fetch("https://api.medium.com/v1/users/.../posts")
│
│ [extra_hosts redirects api.medium.com → 172.19.0.100]
▼
medium-proxy:443 (self-signed cert for api.medium.com, trusted via NODE_EXTRA_CA_CERTS)
│ - markdown → HTML
│ - featured image to top
▼
api.medium.com (real Medium API)
First-time deployment
On the Postiz LXC (192.168.1.90):
# 1. Clone this repo
cd /root
git clone https://gitea.alexandre-vazquez.cloud/alexandrev/medium-proxy.git
cd medium-proxy
# 2. Generate TLS certs, build image, start container
chmod +x setup.sh
./setup.sh
# 3. Apply the snippet printed by setup.sh to /root/postiz/docker-compose.yaml
# (adds extra_hosts, NODE_EXTRA_CA_CERTS, and volume mount for the CA cert)
# 4. Restart only the postiz service
cd /root/postiz && docker compose up -d postiz
Postiz docker-compose.yaml patch
Add the following inside the postiz service block:
extra_hosts:
- "api.medium.com:172.19.0.100"
environment:
NODE_EXTRA_CA_CERTS: /certs/ca.crt
volumes:
- /root/medium-proxy/certs/ca.crt:/certs/ca.crt:ro
Updating
cd /root/medium-proxy
git pull
docker compose up -d --build
No need to touch the Postiz docker-compose again — certs are reused.
Redeploying from scratch (e.g. after losing the LXC)
cd /root
git clone https://gitea.alexandre-vazquez.cloud/alexandrev/medium-proxy.git
cd medium-proxy
./setup.sh # generates new certs
# Apply the printed snippet to /root/postiz/docker-compose.yaml
# Restart postiz
Note: New certs mean a new CA. Don't forget to restart the postiz container after updating the CA cert mount so Node.js picks it up (
NODE_EXTRA_CA_CERTSis read at startup).
Verifying it works
# Check proxy is running
docker logs medium-proxy
# Send a test publish from Postiz and look for the conversion log line:
# INFO POST /v1/users/.../posts | contentFormat: markdown → html
docker logs -f medium-proxy
Limitations
- Paywall: Medium's public API (v1) has no endpoint to toggle the Partner Program paywall. Enable it manually for each story from the Medium web editor.
- Featured image from WordPress: The proxy moves the first image already present in the article body. If the WordPress featured image is not embedded in the article content (only stored as a post thumbnail), the proxy has no way to retrieve it — the story will still show the pattern thumbnail.
- Post updates: Medium's v1 API is create-only. Already-published stories with broken tables or missing images must be fixed manually via the Medium web editor.
Description
Languages
Python
60.4%
Shell
34%
Dockerfile
5.6%