How to Install Wallabag (A Self-Hosted Read-It-Later That Keeps the Article)

Read it later, on your server: Wallabag saves the article itself — clean, offline, searchable, yours.

Linkding (tutorial 113) saves the link. Wallabag saves the article: it fetches the page, strips the adverts and navigation, and stores the readable text and images on your server, so it's there offline, after the site paywalls it, and after the site is gone. A phone app, a browser extension, tags, search, and an export to EPUB or straight to a Kindle. It's what Pocket was before it closed.

Quick reference

TaskWhat
Folder~/docker/wallabag/compose.yaml
Webhttp://server-ip:8082
Default loginwallabag / wallabag — change it
Browserthe wallabagger extension (Firefox, Chrome)
PhoneWallabag (Android, iOS) with your server URL and API client
ImportImport → Pocket / Instapaper / HTML / RSS

1. The compose file

mkdir -p ~/docker/wallabag && cd ~/docker/wallabag
nano compose.yaml

services:
wallabag:
image: wallabag/wallabag:latest
container_name: wallabag
ports:
- "8082:80"
environment:
SYMFONY__ENV__DOMAIN_NAME: http://192.168.1.50:8082
SYMFONY__ENV__DATABASE_DRIVER: pdo_pgsql
SYMFONY__ENV__DATABASE_HOST: db
SYMFONY__ENV__DATABASE_PORT: 5432
SYMFONY__ENV__DATABASE_NAME: wallabag
SYMFONY__ENV__DATABASE_USER: wallabag
SYMFONY__ENV__DATABASE_PASSWORD: ${DB_PASSWORD}
SYMFONY__ENV__SECRET: ${APP_SECRET}
SYMFONY__ENV__FOSUSER_REGISTRATION: "false"
SYMFONY__ENV__LOCALE: en
POPULATE_DATABASE: "true"
volumes:
- ./images:/var/www/wallabag/web/assets/images
- ./data:/var/www/wallabag/data
depends_on:
- db
- redis
restart: unless-stopped

db:
image: postgres:16-alpine
environment:
POSTGRES_USER: wallabag
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: wallabag
volumes:
- ./db:/var/lib/postgresql/data
restart: unless-stopped

redis:
image: redis:alpine
restart: unless-stopped

.env with DB_PASSWORD and APP_SECRET. DOMAIN_NAME must be the address you'll use — change it to https://read.example.com once it's behind the proxy, then up -d.

docker compose up -d
docker compose logs -f wallabag # wait for "Database populated"

2. First login

http://192.168.1.50:8082, wallabag / wallabag. Config → User information to change the password (and username). Registration is off, so add family under Config → Users if they want their own.

3. Save things

4. Read

Articles open as clean text with the images kept, adjustable font and dark mode, a reading-progress bar, and an estimated time. Tag them (#long, #recipes), star favourites, mark read. Search covers the full text. Rules (Config → Tagging rules) tag automatically: readingTime > 20 → long.

5. Send to a Kindle, or export

Any article → Export → EPUB / PDF / MOBI. For a weekly Kindle digest, the wallabag-kindle script or Calibre-Web (tutorial 86) with the EPUBs works. Everything can be exported in bulk from Config, so you're never stuck.

6. Import

Import → Pocket (upload the CSV from your Pocket export), Instapaper, Readability, a browser's HTML bookmarks, or a Wallabag JSON from another instance. Imports fetch each article's text as they go, which takes a while for thousands.

Troubleshooting

Saved an article but the text is empty. The site blocks fetching or needs a login. The extension can save the page as rendered instead; or paste the text manually.

Images missing after moving behind the proxy. DOMAIN_NAME still points at the old address.

App can't connect. API client missing, or the URL has a trailing slash problem — use https://read.example.com with no slash.

Slow imports. Redis handles the queue; docker compose logs redis should be quiet. Patience.

Wrapping up

Three containers, change the default login, create an API client, install the extension and the app. Every article you mean to read is on your server as clean text, readable on the train with no signal, and still there in ten years.

Call us