Direct origin probing
- Control
- Outbound-only tunnel and zero published application ports
- Residual risk
- Cloudflare account security and provider availability remain dependencies.
Published a national legal journal from self-hosted infrastructure without exposing a single inbound application port.

Reader selected.
BRASILCON had no digital editorial platform at all: submission, review, editorial rounds, and publication had to be built from zero, without taking on a conventional hosted-infrastructure budget.
The security challenge was unusually concrete: serve a public institution from residential infrastructure while keeping the origin and application ports out of the normal inbound attack path.
Volunteer build of the editorial management platform for the Revista de Direito do Consumidor - the journal of BRASILCON, the Brazilian Institute of Consumer Policy and Law. There was no system to migrate: the journal had no digital editorial platform, so I built one from scratch on my own server - a self-hosted Open Journal Systems (OJS) stack, now live at revistabrasilcon.com. I architected it, run it in production solo, and BRASILCON formally recognized the work in an official letter (Ofício nº 13/2026) signed by its President, the journal's Director-General, and its Secretary-General.
ZERO-OPEN-PORT INGRESS - The core security decision: the journal is published to the internet without a single inbound port. Ingress is an outbound-only Cloudflare Tunnel - the cloudflared container dials out to Cloudflare's edge, and all public traffic rides back down that authenticated connection. No port-forwards, no exposed origin IP, no direct attack surface on a residential network. TLS terminates at Cloudflare's edge, which also provides DDoS absorption and traffic filtering for free.
DEFENSE IN DEPTH BY ARCHITECTURE - The stack is three Docker containers on an isolated bridge network: a custom-built OJS 3.4 image (configuration and patches baked in at build time - the running container is reproducible, not hand-mutated), MariaDB for the editorial database, and cloudflared. The compose file publishes zero host ports: the database is reachable only by the OJS container on the internal Docker network, and OJS itself is reachable only through the tunnel. Even someone on the LAN cannot talk to the database directly.
OPERATIONS - All three containers restart automatically and survive reboots unattended. Day-2 work is mine alone: image rebuilds, DNS, tunnel health monitoring, incident documentation and runbooks. The platform digitizes the journal's full academic workflow - article submission, double-blind peer review, editorial rounds, and publication - for a national legal institute, running on hardware I own.
No control is presented as total risk elimination.
Publish without router port forwarding.
Make the application the sole database client.
Bake configuration and patches at build time.
The public path stops while the origin remains closed to direct inbound traffic.
Container restart policies restore the stack in dependency order.
01# Zero published host ports. The journal is reachable ONLY through the tunnel.02services:03 ojs:04 build: ./ojs # OJS 3.4 - patches baked in at build time05 depends_on:06 db: { condition: service_healthy }07 networks: [internal] # no route to the outside world08 restart: unless-stopped09 # NOTE: no `ports:` block - nothing is ever bound to the host.10 11 db:12 image: mariadb:1113 environment:14 MARIADB_PASSWORD_FILE: /run/secrets/db_pass # secret, never inline15 secrets: [db_pass]16 networks: [internal] # reachable only by the ojs container17 volumes: [ojs_db:/var/lib/mysql]18 restart: unless-stopped19 20 cloudflared:21 image: cloudflare/cloudflared:latest22 command: tunnel --no-autoupdate run23 environment:24 TUNNEL_TOKEN_FILE: /run/secrets/cf_token25 secrets: [cf_token]26 networks: [edge, internal] # dials OUT to Cloudflare's edge27 restart: unless-stopped28 29networks:30 edge: {} # cloudflared egress only31 internal: { internal: true } # air-gapped from the public internet32 33secrets:34 db_pass: { file: ./secrets/db_pass.txt }35 cf_token: { file: ./secrets/cf_token.txt }Zero published host ports - ingress is an outbound-only Cloudflare Tunnel.
National journal workflow operating on infrastructure Pedro owns
Public access without a direct application-port path to the origin
Architecture, operation, and recovery owned by one accountable operator