Files
medium-proxy/README.md
T
2026-05-08 17:59:37 +02:00

3.2 KiB

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_CERTS is 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.