A lightweight REST API for persistent Docker container log storage and retrieval
Docker Log Proxy monitors running Docker containers, captures their logs to the filesystem, and exposes them via a simple REST API. Logs remain accessible even after containers exit, making it ideal for debugging, auditing, and log aggregation workflows.
- Automatic Discovery - Monitors all running containers or specific containers by name
- Persistent Storage - Logs saved to filesystem and accessible after container termination
- Real-time Streaming - Stream logs as they're generated with
followparameter - Selective Output - Filter stdout/stderr independently
- Zero Configuration - Works out of the box with sensible defaults
- Extensible Design - Modular architecture for pluggable storage backends
flowchart LR
Client[HTTP Client] -->|GET /logs/{name}| API[REST API]
API -->|fetch live| Docker[Docker Engine]
API -.->|fallback| Storage[(Filesystem)]
Collector[Log Collector] -->|fetch live| Docker
Collector -->|persist| Storage
docker-logproxy/
├── main.go # Application entry point
├── internal/
│ ├── api/ # HTTP server and handlers
│ ├── docker/ # Docker Engine API client wrapper
│ ├── log/ # Core business logic
│ │ ├── collector.go # Monitors containers and saves logs
│ │ ├── service.go # Retrieves logs from Docker or storage
│ │ ├── container.go # Container model
│ │ └── error.go # Application error types
│ └── filesystem/ # Filesystem-based log storage
├── api/ # OpenAPI specifications
└── Makefile # Build and test commands
# Build and run the proxy
make build && ./docker-logproxy
# In another terminal, start a container
docker run --name test-container alpine echo "Hello World"
# Retrieve the logs via REST API
curl http://localhost:8000/logs/test-container- Go 1.25 or higher
- Docker Engine running locally or accessible via TCP
- Docker Socket Access - typically requires
/var/run/docker.sockpermissions
# Clone the repository
git clone https://github.com/matthieugusmini/docker-logproxy.git
cd docker-logproxy
# Build the binary
make build
# Run the application
./docker-logproxygo install github.com/matthieugusmini/docker-logproxy@latestStart the log proxy with default settings:
./docker-logproxyThe server will:
- Connect to the Docker daemon
- Discover all running containers
- Start capturing logs to
./logsdirectory - Expose the REST API on
http://localhost:8000
| Flag | Description | Default |
|---|---|---|
-port |
HTTP server port | 8000 |
-log-dir |
Directory where container logs are stored | logs |
-containers |
Comma-separated list of container names to watch | All containers |
-v |
Enable debug logging | false |
Examples:
# Watch specific containers only
./docker-logproxy -containers nginx,redis
# Use custom port
./docker-logproxy -port 3000
# Store logs in custom directory
./docker-logproxy -log-dir /var/log/containers
# Enable verbose logging
./docker-logproxy -vTip
Full API documentation is available in the OpenAPI specification at /api/openapi.yaml. You can visualize and interact with the API using Swagger Editor.
Retrieve logs for a specific container.
Path Parameters:
name(required) - Container name or ID
Query Parameters:
follow- Stream logs in real-time (0or1, default:0)stdout- Include stdout logs (0or1, default:0)stderr- Include stderr logs (0or1, default:1)
Response:
200 OK- Returns logs astext/plain404 Not Found- Container not found500 Internal Server Error- Server error
curl http://localhost:8000/logs/nginxcurl http://localhost:8000/logs/nginx?follow=1curl http://localhost:8000/logs/nginx?stdout=1curl http://localhost:8000/logs/nginx?stdout=1&stderr=0curl http://localhost:8000/logs/nginx?follow=1&stdout=0To test the business logic in isolation using test doubles.
make test-unitTest the complete application with real Docker containers.
make test-e2eThis application monitors Docker containers on the host system and must run directly on the host. Running Docker inside a container (Docker-in-Docker) creates a separate daemon that can't see host containers.
Caution
While mounting the Docker socket with -v /var/run/docker.sock:/var/run/docker.sock makes containerization technically possible, it grants root-equivalent host access.1 If you're comfortable with that risk, running the binary directly on the host is simpler and has a clearer security model.
1: Socket mounting implications
Note: This project was created as a technical assessment demonstrating Go REST API development.