mirror of
https://github.com/aserper/masto-rss.git
synced 2025-12-15 04:25:24 +00:00
Add multiarch Docker support and GHCR publishing
- Implement multiarch Dockerfile supporting linux/amd64 and linux/arm64 - Optimize Dockerfile with better layer caching and reduced image size - Update CI/CD pipeline to use Docker Buildx for multiarch builds - Add GitHub Container Registry (GHCR) as second publishing target - Configure automatic tagging (latest, branch name, commit SHA) - Add QEMU emulation support for cross-platform builds - Enable GitHub Actions layer caching for faster builds - Completely revamp README with comprehensive documentation - Add professional badges (build status, Docker Hub, GHCR, license, Python) - Include detailed setup instructions for Docker Hub and GHCR - Add Docker Compose example and configuration table - Document multiarch build process and state persistence
This commit is contained in:
55
.github/workflows/masto-rss.yml
vendored
55
.github/workflows/masto-rss.yml
vendored
@@ -5,16 +5,55 @@ on:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- name: Build & Push Image
|
||||
run: |
|
||||
echo "${{ secrets.DH_PASSWORD }}" | docker login -u "amitserper" --password-stdin
|
||||
docker build -t amitserper/masto-rss .
|
||||
docker push amitserper/masto-rss
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: amitserper
|
||||
password: ${{ secrets.DH_PASSWORD }}
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
amitserper/masto-rss
|
||||
ghcr.io/aserper/masto-rss
|
||||
tags: |
|
||||
type=ref,event=branch
|
||||
type=sha,prefix={{branch}}-
|
||||
type=raw,value=latest,enable={{is_default_branch}}
|
||||
|
||||
- name: Build and push multiarch image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
|
||||
15
Dockerfile
15
Dockerfile
@@ -4,14 +4,15 @@ FROM alpine:3.18
|
||||
# Set the working directory inside the container
|
||||
WORKDIR /app
|
||||
|
||||
# Copy the entire current directory into the container at /app
|
||||
# Install Python dependencies in a single layer
|
||||
RUN apk add --no-cache python3 py3-pip
|
||||
|
||||
# Copy requirements first for better layer caching
|
||||
COPY requirements.txt /app/
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
# Copy the application code
|
||||
COPY . /app
|
||||
|
||||
# Install any Python dependencies
|
||||
|
||||
RUN apk add python3
|
||||
RUN apk add py3-pip
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
# Run Python script
|
||||
CMD ["python", "main.py"]
|
||||
|
||||
220
README.md
220
README.md
@@ -1,20 +1,216 @@
|
||||
# Masto-rss
|
||||

|
||||
|
||||
A simple Mastodon bot written in python that posts updates from an RSS feed to a Mastodon account.
|
||||
This project is meant to be built to a docker container, so all of the options need to be set as environment variables:
|
||||
# Masto-RSS
|
||||
|
||||
MASTODON_CLIENT_ID = Mastodon client ID
|
||||
[](https://github.com/aserper/masto-rss/actions/workflows/masto-rss.yml)
|
||||
[](https://hub.docker.com/r/amitserper/masto-rss)
|
||||
[](https://github.com/aserper/masto-rss/pkgs/container/masto-rss)
|
||||
[](LICENSE)
|
||||
[](https://www.python.org/downloads/)
|
||||
[](https://github.com/aserper/masto-rss)
|
||||
|
||||
MASTODON_CLIENT_SECRET = Mastodon client secret
|
||||
A simple, lightweight Mastodon bot that automatically posts updates from RSS feeds to the Fediverse. Built with Python and designed to run seamlessly in Docker with multiarch support (amd64 & arm64).
|
||||
|
||||
MASTODON_ACCESS_TOKEN = Mastodon access token
|
||||
## Features
|
||||
|
||||
MASTODON_INSTANCE_URL = Mastodon instance URL
|
||||
- Automatically monitors RSS/Atom feeds and posts new items to Mastodon
|
||||
- Persistent state tracking to avoid duplicate posts
|
||||
- Configurable post visibility (public, unlisted, private, direct)
|
||||
- Lightweight Alpine-based Docker image
|
||||
- Multiarch support (amd64 & arm64) for broad compatibility
|
||||
- Continuous monitoring with configurable check intervals
|
||||
|
||||
RSS_FEED_URL = URL of RSS/xml feed
|
||||
## Quick Start
|
||||
|
||||
TOOT_VISIBILITY = 'public', 'unlisted', 'private', or 'direct'
|
||||
### Using Docker (Recommended)
|
||||
|
||||
The best way to use this project is by using [its docker container](https://hub.docker.com/r/amitserper/masto-rss)
|
||||
When using docker, make a bind mount between /state on the container to whatever directory you want on your machine in order to keep the state of the feeds that were already posted
|
||||

|
||||
The easiest way to run Masto-RSS is using the pre-built multiarch Docker images available on both Docker Hub and GitHub Container Registry.
|
||||
|
||||
#### Pull from Docker Hub
|
||||
|
||||
```bash
|
||||
docker pull amitserper/masto-rss:latest
|
||||
```
|
||||
|
||||
#### Pull from GitHub Container Registry
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/aserper/masto-rss:latest
|
||||
```
|
||||
|
||||
#### Run the Bot
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name masto-rss-bot \
|
||||
-e MASTODON_CLIENT_ID="your_client_id" \
|
||||
-e MASTODON_CLIENT_SECRET="your_client_secret" \
|
||||
-e MASTODON_ACCESS_TOKEN="your_access_token" \
|
||||
-e MASTODON_INSTANCE_URL="https://mastodon.social" \
|
||||
-e RSS_FEED_URL="https://example.com/feed.xml" \
|
||||
-e TOOT_VISIBILITY="public" \
|
||||
-e CHECK_INTERVAL="300" \
|
||||
-v /path/to/state:/state \
|
||||
amitserper/masto-rss:latest
|
||||
```
|
||||
|
||||
> **Important:** Use a bind mount for `/state` to persist the list of processed feed items across container restarts.
|
||||
|
||||
### Using Docker Compose
|
||||
|
||||
Create a `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
masto-rss:
|
||||
image: amitserper/masto-rss:latest
|
||||
# Or use GHCR: ghcr.io/aserper/masto-rss:latest
|
||||
container_name: masto-rss-bot
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MASTODON_CLIENT_ID: "your_client_id"
|
||||
MASTODON_CLIENT_SECRET: "your_client_secret"
|
||||
MASTODON_ACCESS_TOKEN: "your_access_token"
|
||||
MASTODON_INSTANCE_URL: "https://mastodon.social"
|
||||
RSS_FEED_URL: "https://example.com/feed.xml"
|
||||
TOOT_VISIBILITY: "public"
|
||||
CHECK_INTERVAL: "300"
|
||||
volumes:
|
||||
- ./state:/state
|
||||
```
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
All configuration is done via environment variables:
|
||||
|
||||
| Variable | Description | Required | Example |
|
||||
|----------|-------------|----------|---------|
|
||||
| `MASTODON_CLIENT_ID` | Mastodon application client ID | Yes | `abc123...` |
|
||||
| `MASTODON_CLIENT_SECRET` | Mastodon application client secret | Yes | `xyz789...` |
|
||||
| `MASTODON_ACCESS_TOKEN` | Mastodon access token | Yes | `token123...` |
|
||||
| `MASTODON_INSTANCE_URL` | URL of your Mastodon instance | Yes | `https://mastodon.social` |
|
||||
| `RSS_FEED_URL` | URL of the RSS/Atom feed to monitor | Yes | `https://example.com/feed.xml` |
|
||||
| `TOOT_VISIBILITY` | Post visibility level | Yes | `public`, `unlisted`, `private`, or `direct` |
|
||||
| `CHECK_INTERVAL` | Seconds between feed checks | Yes | `300` (5 minutes) |
|
||||
|
||||
### Getting Mastodon API Credentials
|
||||
|
||||
1. Log into your Mastodon instance
|
||||
2. Go to **Settings** → **Development** → **New Application**
|
||||
3. Give it a name (e.g., "RSS Bot")
|
||||
4. Set scopes to `write:statuses`
|
||||
5. Save and copy the client ID, client secret, and access token
|
||||
|
||||
## Building from Source
|
||||
|
||||
### Build Locally
|
||||
|
||||
```bash
|
||||
git clone https://github.com/aserper/masto-rss.git
|
||||
cd masto-rss
|
||||
docker build -t masto-rss .
|
||||
```
|
||||
|
||||
### Build Multiarch Images
|
||||
|
||||
```bash
|
||||
# Set up buildx
|
||||
docker buildx create --use
|
||||
|
||||
# Build for both architectures
|
||||
docker buildx build \
|
||||
--platform linux/amd64,linux/arm64 \
|
||||
-t yourusername/masto-rss:latest \
|
||||
--push \
|
||||
.
|
||||
```
|
||||
|
||||
## Running Without Docker
|
||||
|
||||
If you prefer to run the bot directly with Python:
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone https://github.com/aserper/masto-rss.git
|
||||
cd masto-rss
|
||||
|
||||
# Install dependencies
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Set environment variables
|
||||
export MASTODON_CLIENT_ID="your_client_id"
|
||||
export MASTODON_CLIENT_SECRET="your_client_secret"
|
||||
export MASTODON_ACCESS_TOKEN="your_access_token"
|
||||
export MASTODON_INSTANCE_URL="https://mastodon.social"
|
||||
export RSS_FEED_URL="https://example.com/feed.xml"
|
||||
export TOOT_VISIBILITY="public"
|
||||
export CHECK_INTERVAL="300"
|
||||
|
||||
# Run the bot
|
||||
python main.py
|
||||
```
|
||||
|
||||
> **Note:** When running without Docker, the bot stores its state in `/state/processed_entries.txt`. Make sure this directory exists or modify [main.py](main.py#L15) to use a different path.
|
||||
|
||||
## How It Works
|
||||
|
||||
1. The bot fetches the RSS feed at regular intervals (defined by `CHECK_INTERVAL`)
|
||||
2. For each feed item, it checks if the item's URL has been processed before
|
||||
3. If the item is new, it posts to Mastodon with the format: `{title}\n\n{link}`
|
||||
4. The item URL is saved to prevent duplicate posts
|
||||
5. The process repeats indefinitely
|
||||
|
||||
## Architecture
|
||||
|
||||
- **Base Image:** Alpine Linux 3.18 (minimal footprint)
|
||||
- **Python Version:** 3.10+
|
||||
- **Platforms:** linux/amd64, linux/arm64
|
||||
- **Dependencies:** feedparser, mastodon.py (see [requirements.txt](requirements.txt))
|
||||
|
||||
## State Persistence
|
||||
|
||||
The bot maintains state in `/state/processed_entries.txt` to track which feed items have already been posted. This prevents duplicate posts across restarts.
|
||||
|
||||
**Important:** Always mount `/state` as a volume to preserve this state file.
|
||||
|
||||
## CI/CD
|
||||
|
||||
The project uses GitHub Actions for automated multiarch builds and deployments:
|
||||
|
||||
- Builds on every push to `main`
|
||||
- Creates images for both amd64 and arm64 architectures
|
||||
- Automatically pushes to Docker Hub and GitHub Container Registry
|
||||
- Uses Docker layer caching for faster builds
|
||||
|
||||
See [.github/workflows/masto-rss.yml](.github/workflows/masto-rss.yml) for the full pipeline.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Feel free to:
|
||||
|
||||
- Report bugs by opening an issue
|
||||
- Submit pull requests for improvements
|
||||
- Suggest new features or enhancements
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for details.
|
||||
|
||||
## Support
|
||||
|
||||
If you find this project useful, please consider giving it a star on GitHub!
|
||||
|
||||
## Links
|
||||
|
||||
- [Docker Hub Repository](https://hub.docker.com/r/amitserper/masto-rss)
|
||||
- [GitHub Container Registry](https://github.com/aserper/masto-rss/pkgs/container/masto-rss)
|
||||
- [Source Code](https://github.com/aserper/masto-rss)
|
||||
- [Issues](https://github.com/aserper/masto-rss/issues)
|
||||
|
||||
BIN
header.jpg
Normal file
BIN
header.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 178 KiB |
Reference in New Issue
Block a user