5 months ago
Set up a complete, production-grade CitrineOS infrastructure on Railway following the architecture described in the official docs at:
https://citrineos.github.io/latest/
For more info, CitrineOS has YouTube videos on local installs. I have been able to get this running locally, but want to have a cloud version within Railway to begin production development. CitrineOS also has an active Discord server for developer questions.
The following is based on my interpretation of the recommended architecture. Follow the docs and each CitrineOS repo’s README as the source of truth.
Requirements
Deploy and integrate the following:
- CitrineOS Core Repo + docs: https://github.com/citrineos/citrineos-core
- Public gateway for Core HTTP + OCPP WebSocket
- Everest OCPP server for testing/simulation Repo + docs: https://github.com/EVerest/everest
- OCPI service Repo + docs: https://github.com/citrineos/citrineos-ocpi
- Payments service Repo + docs: https://github.com/citrineos/citrineos-payment
- Operator UI Repo + docs: https://github.com/citrineos/citrineos-operator-ui
- PostgreSQL - timescaledb
- RabbitMQ with persistent volume and secure credentials
- Redis
- Hasura GraphQL Engine Docs: https://hasura.io/docs
- Directus with persistent uploads Docs: https://docs.directus.io
Use private networking where appropriate, pin container versions (avoid using latest), and follow security and scaling best practices recommended in the CitrineOS documentation.
Extensions Service (Required)
Create a separate service where custom logic lives outside of Core, including a minimal working example demonstrating:
- consuming messages/events (e.g., from RabbitMQ), and/or
- making calls to Core APIs
Document where extensions should be placed and how they are deployed without modifying CitrineOS Core.
Acceptance Criteria
- All services deployed and healthy
- Public endpoints reachable via domains
- Core, database, cache, and broker remain private
- OCPI, Payments, Hasura, Directus, Everest verified working
- No modifications to CitrineOS Core source
- README covering architecture overview, env vars, deployment steps, and how to extend the platform safely
Constraints
- Infrastructure and platform setup only
- No product feature or UI work beyond basic verification
5 Replies
5 months ago
This thread has been marked as public for community involvement, as it does not contain any sensitive or personal information. Any further activity in this thread will be visible to everyone.
Status changed to Open nico • 5 months ago
5 months ago
Hey, hope this helps you ;)
Not worried about the bounty, just lmk. This is from my fine-tuned Opus, so just want to know if he's doing a good job heh.
Attachments
4 months ago
were you able to fix it ?
3 months ago
is this open yet?
2 months ago
Hi, thanks for the detailed requirements.
After researching the CitrineOS architecture and Railway's networking capabilities, this is fully feasible with a few design decisions.
The main challenge is that CitrineOS Core exposes multiple WebSocket ports (one per OCPP protocol/security profile), but Railway only exposes one port per service.
The solution is deploying an nginx reverse proxy as the single public entry point, routing /ws/ocpp201/ and /ws/ocpp16/ paths to the Core's internal WebSocket servers, and / to the REST API. The dynamic tenant port range (10000-10500) can be safely ignored since current CitrineOS uses path-based tenant resolution instead. All backing services (PostgreSQL with PostGIS, RabbitMQ, Redis, Hasura, Core itself) stay on Railway's private network, while only nginx, Operator UI, and Directus get public domains.
Security profiles 2/3 (mTLS) won't work with Railway's TLS termination, so we'd start with profile 0 or 1 and address mTLS later if needed. EVerest stays outside Railway (local or VM) and connects outbound to the public WebSocket endpoint for testing.
I'm ready to build out the full infrastructure whenever you give the green light.
21 days ago
Hey — I built this out:
https://github.com/thinkkits-llc/citrineos-railway-template
9 Dockerfiles + nginx reverse proxy for the multi-port WebSocket problem (path-based routing for OCPP 1.6/2.0.1/2.1), railway.toml, and health checks on every service, Railway private networking between everything. PostgreSQL, Redis, and RabbitMQ are set up as Railway plugins. Full docs in the README.
Happy to publish it as a template whenever.
