RWParcer is a .NET application that parses rw.by data and provides train subscriptions with notifications on changing seats.
RWParcer/— bot application, command routing, configuration, and session integration.RWParcerCore/— domain logic, entities, repositories, services, interfaces, and database infrastructure.RWParcerCore.Tests/— unit tests.proxy-manager/— lightweight proxy health-check and routing service used by the main app.docker-compose.yml— single deployment file for local, dev, and production environments via environment overrides.Dockerfile— main application image build instructions.env/— example configuration (appsettings, data, logging).
- .NET (C#)
- Entity Framework Core (migrations and database access)
- PostgreSQL
- Docker + docker-compose
-
Make sure you have installed:
- Docker & Docker Compose
-
Review / update configuration in
env/appsettings.jsonas needed.
For local development:
git clone https://github.com/danilaltd/RWParcer
cd RWParcer
docker compose -f docker-compose.yml up --buildThis starts:
- the main
parcerservice (built fromDockerfile) - the
proxy-managerservice (built fromproxy-manager/Dockerfile)
For dev/prod deployment, set the environment variables you need and run:
docker compose -f docker-compose.yml up -dExamples:
DATA_DIR=/var/lib/rwparcer-dev/data PROXY_FILE_PATH=/var/lib/rwparcer-dev/proxies.txt docker compose -f docker-compose.yml up -dPARSER_IMAGE=ghcr.io/<owner>/rwparcer:dev-latest PROXY_MANAGER_IMAGE=ghcr.io/<owner>/rwparcer-proxy-manager:dev-latest docker compose -f docker-compose.yml up -d
To stop the stack, run
docker compose -f docker-compose.yml down.
Program.csinitializes DI, loads configuration, and registers services.BotService(orCommandRouter) handles incoming commands and calls intoRWParcerCore.RWParcerCorecontains business logic, domain entities, and repository implementations.- Sessions/state are persisted to the database (PostgreSQL/SQLite) via
SessionDbContext.
The project uses GitHub Actions with a three-stage workflow defined in .github/workflows/main.yml:
Push to main branch
↓
[ci-checks] (github-hosted ubuntu-latest)
- Secret detection (Gitleaks)
- .NET build check
- Optional: Unit tests
↓
[build] (github-hosted ubuntu-latest)
- Build Docker images
- Push to GitHub Container Registry (ghcr.io)
↓
[deploy] (self-hosted runner)
- Pull and deploy using docker-compose
- Apply runtime configuration from secrets
Runs code quality and build validation:
- Secret Detection — Gitleaks scans for accidentally committed secrets.
- Setup .NET — Uses .NET 8.0.x SDK.
- Restore & Build — Restores NuGet dependencies and builds in Release mode.
Builds and publishes Docker images:
- Builds two images:
- ghcr.io/<owner>/rwparcer:<env>-latest (main application)
- ghcr.io/<owner>/rwparcer-proxy-manager:<env>-latest (proxy-manager service)
- Waits for ci-checks job to pass
- Pushes both images to GitHub Container Registry
- Requires GITHUB_TOKEN permissionsDeploys the application to production:
- Checks out code
- Creates
./env/directory - Injects
appsettings.jsonfrom GitHub Secrets - Pulls latest images from ghcr.io
- Runs
docker compose -f docker-compose.yml up -dto deploy/update services
The self-hosted runner must be configured on a production/staging server with:
- Docker & Docker Compose installed
- GitHub Runner installed and registered
Ensure the runner can:
- Execute
dockeranddocker composecommands - Read/write to
/var/lib/rwparcer/dataand/var/lib/rwparcer/proxies.txt - Access GitHub Container Registry (via
docker login)
The CI/CD pipeline requires these secrets configured in GitHub Settings → Secrets and variables → Actions:
- Default token, used for:
- Container registry authentication
- Wait-on-check workflow step
- Complete
appsettings.jsoncontent as a multiline secret for the corresponding environment - Example structure:
{ "BotSettings": { "Token": "your-bot-token" }, "DatabaseSettings": { "ConnectionString": "Server=parcer-db;..." }, "ProxySettings": { "ProxyRotationEnabled": true }, "Logging": { "LogLevel": { "Default": "Information", "Microsoft": "Warning" } } }
- Go to GitHub Repository → Settings → Secrets and variables → Actions
- Click New repository secret
- Name:
PROD_APP_SETTINGS_JSON(production) orDEV_APP_SETTINGS_JSON(development) - Value: Paste the full
appsettings.jsoncontent for that environment - Save
proxy-manager is the current proxy-routing component used to:
- health-check and score available proxies
- choose a working proxy for each outgoing request
- report failures back to the proxy pool
In docker-compose.yml, the service is configured as:
services:
proxy-manager:
image: ghcr.io/danilaltd/rwparcer-proxy-manager:prod-latest
volumes:
- /var/lib/rwparcer/proxies.txt:/app/proxies.txt:ro
environment:
PROXY_MANAGER_PORT: 8080
HEALTH_CHECK_INTERVAL: 30
restart: alwaysproxy-managerloads proxies fromproxy-manager/proxies.txt.- It periodically checks each proxy with TCP health checks and updates scores.
- The main app reaches it via
PROXY_MANAGER_URLand uses the returned proxy for HTTP requests.
The main parcer service communicates with the manager through:
services:
parcer:
environment:
PROXY_MANAGER_URL: http://proxy-manager:8080The application code in RWParcerCore/Infrastructure uses HttpClientFactoryWithProxyRotation to:
- ask the manager for the next healthy proxy
- route the request through it
- report success/failure back to the manager for score updates
docker compose -f docker-compose.local.yml up --buildStarts both proxy-manager and parcer locally for development.
- Developer pushes to
mainbranch - GitHub Actions triggered automatically:
- Runs
ci-checks(linting, build) - Builds Docker images (
rwparcer+rwparcer-proxy-manager) - Pushes to ghcr.io
- Runs
- Self-hosted runner pulls latest images
- Production deployment via
docker compose pull && docker compose up -d
If deployment fails:
# On self-hosted machine
docker compose down
docker compose up -d --remove-orphans