Docker support
This commit is contained in:
@@ -0,0 +1,42 @@
|
|||||||
|
# Build directories
|
||||||
|
builddir/
|
||||||
|
testbuild/
|
||||||
|
|
||||||
|
# Git
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# Documentation
|
||||||
|
README.md
|
||||||
|
*.md
|
||||||
|
|
||||||
|
# CI/CD
|
||||||
|
.github/
|
||||||
|
|
||||||
|
# IDE files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Docker files
|
||||||
|
Dockerfile
|
||||||
|
.dockerignore
|
||||||
|
docker-compose.yml
|
||||||
|
|
||||||
|
# Coverage reports
|
||||||
|
.codecov.yml
|
||||||
|
coverage/
|
||||||
|
*.gcov
|
||||||
|
*.gcda
|
||||||
|
*.gcno
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
|
*.log
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
name: Build and Publish Docker Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "main" ]
|
||||||
|
tags: [ 'v*.*.*' ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "main" ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
IMAGE_NAME: ${{ github.repository }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
meson \
|
||||||
|
ninja-build \
|
||||||
|
pkg-config \
|
||||||
|
libboost-all-dev \
|
||||||
|
libgtest-dev \
|
||||||
|
libgmock-dev
|
||||||
|
|
||||||
|
- name: Setup build directory
|
||||||
|
run: meson setup builddir --buildtype=release
|
||||||
|
|
||||||
|
- name: Build project
|
||||||
|
run: meson compile -C builddir
|
||||||
|
|
||||||
|
- name: Run tests
|
||||||
|
run: meson test -C builddir
|
||||||
|
|
||||||
|
- name: Upload test results
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: test-results
|
||||||
|
path: builddir/meson-logs/testlog.txt
|
||||||
|
|
||||||
|
build-and-push-image:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build-and-test
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Log in to Container Registry
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Extract metadata (tags, labels) for Docker
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
tags: |
|
||||||
|
type=ref,event=branch
|
||||||
|
type=ref,event=pr
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=semver,pattern={{major}}.{{minor}}
|
||||||
|
type=semver,pattern={{major}}
|
||||||
|
type=sha,prefix={{branch}}-
|
||||||
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
|
||||||
|
- name: Build and push Docker 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
|
||||||
|
|
||||||
|
- name: Generate artifact attestation
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
uses: actions/attest-build-provenance@v1
|
||||||
|
with:
|
||||||
|
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||||
|
subject-digest: ${{ steps.build.outputs.digest }}
|
||||||
|
push-to-registry: true
|
||||||
|
|
||||||
|
security-scan:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: build-and-push-image
|
||||||
|
if: github.event_name != 'pull_request'
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Run Trivy vulnerability scanner
|
||||||
|
uses: aquasecurity/trivy-action@master
|
||||||
|
with:
|
||||||
|
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
||||||
|
format: 'sarif'
|
||||||
|
output: 'trivy-results.sarif'
|
||||||
|
|
||||||
|
- name: Upload Trivy scan results to GitHub Security tab
|
||||||
|
uses: github/codeql-action/upload-sarif@v3
|
||||||
|
with:
|
||||||
|
sarif_file: 'trivy-results.sarif'
|
||||||
@@ -0,0 +1,365 @@
|
|||||||
|
# Docker Setup and Deployment
|
||||||
|
|
||||||
|
This document describes how to build, run, and deploy the finger service using Docker and GitHub Actions.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### Using Docker Compose (Recommended)
|
||||||
|
|
||||||
|
1. **Clone the repository:**
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/waffle2k/finger.git
|
||||||
|
cd finger
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Start the service:**
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Test the service:**
|
||||||
|
```bash
|
||||||
|
# Test with the example user
|
||||||
|
finger john@localhost
|
||||||
|
|
||||||
|
# Or using telnet
|
||||||
|
telnet localhost 79
|
||||||
|
# Then type: john
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Add your own users:**
|
||||||
|
```bash
|
||||||
|
# Create a status file for a user
|
||||||
|
echo "Your status message here" > users/yourusername
|
||||||
|
|
||||||
|
# Test it
|
||||||
|
finger yourusername@localhost
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using Docker directly
|
||||||
|
|
||||||
|
1. **Build the image:**
|
||||||
|
```bash
|
||||||
|
docker build -t finger-service .
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Run the container:**
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name finger \
|
||||||
|
-p 79:79 \
|
||||||
|
-v $(pwd)/users:/var/finger/users \
|
||||||
|
finger-service
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using Pre-built Images
|
||||||
|
|
||||||
|
You can also use the automatically built images from GitHub Container Registry:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name finger \
|
||||||
|
-p 79:79 \
|
||||||
|
-v $(pwd)/users:/var/finger/users \
|
||||||
|
ghcr.io/waffle2k/finger:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
## Docker Architecture
|
||||||
|
|
||||||
|
### Multi-stage Build
|
||||||
|
|
||||||
|
The Dockerfile uses a multi-stage build approach:
|
||||||
|
|
||||||
|
1. **Builder Stage (Ubuntu 24.04):**
|
||||||
|
- Installs all build dependencies (meson, ninja, boost, gtest, etc.)
|
||||||
|
- Compiles the C++20 source code
|
||||||
|
- Runs all tests to ensure quality
|
||||||
|
- Creates a statically linked binary
|
||||||
|
|
||||||
|
2. **Runtime Stage (Alpine Linux):**
|
||||||
|
- Minimal base image (~5MB)
|
||||||
|
- Only includes runtime dependencies
|
||||||
|
- Runs as non-root user for security
|
||||||
|
- Includes health checks
|
||||||
|
|
||||||
|
### Security Features
|
||||||
|
|
||||||
|
- **Non-root execution:** Runs as user `finger` (UID 1000)
|
||||||
|
- **Minimal attack surface:** Alpine Linux base with minimal packages
|
||||||
|
- **Health checks:** Built-in container health monitoring
|
||||||
|
- **Read-only filesystem:** Application doesn't write to filesystem
|
||||||
|
|
||||||
|
### Image Size
|
||||||
|
|
||||||
|
- **Final image:** ~15MB (Alpine + binary + minimal runtime deps)
|
||||||
|
- **Build image:** ~2GB (includes all build tools, discarded after build)
|
||||||
|
|
||||||
|
## GitHub Actions CI/CD
|
||||||
|
|
||||||
|
### Automated Workflow
|
||||||
|
|
||||||
|
The repository includes a comprehensive GitHub Actions workflow (`.github/workflows/docker-publish.yml`) that:
|
||||||
|
|
||||||
|
1. **Build and Test:**
|
||||||
|
- Builds the project with meson
|
||||||
|
- Runs all unit tests
|
||||||
|
- Uploads test results as artifacts
|
||||||
|
|
||||||
|
2. **Multi-platform Docker Build:**
|
||||||
|
- Builds for `linux/amd64` and `linux/arm64`
|
||||||
|
- Uses Docker Buildx for cross-platform support
|
||||||
|
- Implements build caching for faster builds
|
||||||
|
|
||||||
|
3. **Container Registry Publishing:**
|
||||||
|
- Publishes to GitHub Container Registry (`ghcr.io`)
|
||||||
|
- Tags with multiple strategies:
|
||||||
|
- `latest` for main branch
|
||||||
|
- `v1.2.3` for semantic version tags
|
||||||
|
- `main-abc1234` for commit SHA
|
||||||
|
- `pr-123` for pull requests
|
||||||
|
|
||||||
|
4. **Security Scanning:**
|
||||||
|
- Runs Trivy vulnerability scanner
|
||||||
|
- Uploads results to GitHub Security tab
|
||||||
|
- Fails on high-severity vulnerabilities
|
||||||
|
|
||||||
|
5. **Supply Chain Security:**
|
||||||
|
- Generates SLSA build provenance attestations
|
||||||
|
- Signs container images
|
||||||
|
- Provides build transparency
|
||||||
|
|
||||||
|
### Triggering Builds
|
||||||
|
|
||||||
|
The workflow triggers on:
|
||||||
|
- **Push to main branch:** Builds and publishes `latest` tag
|
||||||
|
- **Version tags:** Builds and publishes semantic version tags (`v1.0.0`)
|
||||||
|
- **Pull requests:** Builds but doesn't publish (security)
|
||||||
|
|
||||||
|
### Using Published Images
|
||||||
|
|
||||||
|
Images are available at: `ghcr.io/waffle2k/finger`
|
||||||
|
|
||||||
|
Available tags:
|
||||||
|
- `latest` - Latest stable build from main branch
|
||||||
|
- `v1.0.0` - Specific version releases
|
||||||
|
- `main-abc1234` - Specific commit builds
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Environment Variables
|
||||||
|
|
||||||
|
The container supports these environment variables:
|
||||||
|
|
||||||
|
- `FINGER_PORT`: Port to listen on (default: 79)
|
||||||
|
- `FINGER_DATA_DIR`: Directory for user files (default: /var/finger/users)
|
||||||
|
|
||||||
|
### Volume Mounts
|
||||||
|
|
||||||
|
- `/var/finger/users`: Directory containing user status files
|
||||||
|
- Mount your local `users/` directory here
|
||||||
|
- Each file represents a user (filename = username)
|
||||||
|
- File contents = user's status message
|
||||||
|
|
||||||
|
### Health Checks
|
||||||
|
|
||||||
|
The container includes built-in health checks:
|
||||||
|
- **Check:** TCP connection to port 79
|
||||||
|
- **Interval:** Every 30 seconds
|
||||||
|
- **Timeout:** 10 seconds
|
||||||
|
- **Retries:** 3 attempts
|
||||||
|
- **Start period:** 40 seconds
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
### Local Development with Docker
|
||||||
|
|
||||||
|
1. **Build development image:**
|
||||||
|
```bash
|
||||||
|
docker build --target builder -t finger-dev .
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Run tests in container:**
|
||||||
|
```bash
|
||||||
|
docker run --rm finger-dev meson test -C builddir
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Interactive development:**
|
||||||
|
```bash
|
||||||
|
docker run -it --rm \
|
||||||
|
-v $(pwd):/app \
|
||||||
|
-w /app \
|
||||||
|
finger-dev bash
|
||||||
|
```
|
||||||
|
|
||||||
|
### Debugging
|
||||||
|
|
||||||
|
1. **View container logs:**
|
||||||
|
```bash
|
||||||
|
docker logs finger
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Execute into running container:**
|
||||||
|
```bash
|
||||||
|
docker exec -it finger sh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Check health status:**
|
||||||
|
```bash
|
||||||
|
docker inspect finger | grep -A 10 Health
|
||||||
|
```
|
||||||
|
|
||||||
|
## Production Deployment
|
||||||
|
|
||||||
|
### Docker Swarm
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
finger:
|
||||||
|
image: ghcr.io/waffle2k/finger:latest
|
||||||
|
ports:
|
||||||
|
- "79:79"
|
||||||
|
volumes:
|
||||||
|
- finger_data:/var/finger/users
|
||||||
|
deploy:
|
||||||
|
replicas: 2
|
||||||
|
restart_policy:
|
||||||
|
condition: on-failure
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "nc", "-z", "localhost", "79"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
finger_data:
|
||||||
|
```
|
||||||
|
|
||||||
|
### Kubernetes
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: finger-service
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: finger
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: finger
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: finger
|
||||||
|
image: ghcr.io/waffle2k/finger:latest
|
||||||
|
ports:
|
||||||
|
- containerPort: 79
|
||||||
|
volumeMounts:
|
||||||
|
- name: user-data
|
||||||
|
mountPath: /var/finger/users
|
||||||
|
livenessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: 79
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 10
|
||||||
|
volumes:
|
||||||
|
- name: user-data
|
||||||
|
configMap:
|
||||||
|
name: finger-users
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: finger-service
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: finger
|
||||||
|
ports:
|
||||||
|
- port: 79
|
||||||
|
targetPort: 79
|
||||||
|
type: LoadBalancer
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **Permission denied on user files:**
|
||||||
|
```bash
|
||||||
|
# Fix file permissions
|
||||||
|
chmod 644 users/*
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Port 79 requires root:**
|
||||||
|
```bash
|
||||||
|
# Use a different port
|
||||||
|
docker run -p 8079:79 finger-service
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Container won't start:**
|
||||||
|
```bash
|
||||||
|
# Check logs
|
||||||
|
docker logs finger
|
||||||
|
|
||||||
|
# Check if port is available
|
||||||
|
netstat -ln | grep :79
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Health check failing:**
|
||||||
|
```bash
|
||||||
|
# Test manually
|
||||||
|
docker exec finger nc -z localhost 79
|
||||||
|
|
||||||
|
# Check if service is running
|
||||||
|
docker exec finger ps aux
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Tuning
|
||||||
|
|
||||||
|
1. **Resource limits:**
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
finger:
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 64M
|
||||||
|
cpus: '0.1'
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Connection limits:**
|
||||||
|
- The service handles concurrent connections efficiently
|
||||||
|
- Default OS limits should be sufficient for most use cases
|
||||||
|
- Monitor with `docker stats` for resource usage
|
||||||
|
|
||||||
|
## Security Considerations
|
||||||
|
|
||||||
|
1. **Network Security:**
|
||||||
|
- Finger protocol sends data in plain text
|
||||||
|
- Consider using behind a reverse proxy with TLS
|
||||||
|
- Restrict access with firewall rules
|
||||||
|
|
||||||
|
2. **Data Security:**
|
||||||
|
- User files are readable by the finger user
|
||||||
|
- Don't store sensitive information in status files
|
||||||
|
- Consider file permissions on the host
|
||||||
|
|
||||||
|
3. **Container Security:**
|
||||||
|
- Runs as non-root user
|
||||||
|
- Uses minimal base image
|
||||||
|
- Regular security scanning in CI/CD
|
||||||
|
- Keep images updated
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
When contributing Docker-related changes:
|
||||||
|
|
||||||
|
1. Test locally with `docker build`
|
||||||
|
2. Ensure all tests pass in the container
|
||||||
|
3. Update this documentation if needed
|
||||||
|
4. The CI/CD pipeline will automatically test your changes
|
||||||
|
|
||||||
|
For more information, see the main [README.md](README.md).
|
||||||
+68
@@ -0,0 +1,68 @@
|
|||||||
|
# Multi-stage build for C++ finger service
|
||||||
|
# Build stage - use Ubuntu with all development dependencies
|
||||||
|
FROM ubuntu:24.04 AS builder
|
||||||
|
|
||||||
|
# Avoid interactive prompts during package installation
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
# Install build dependencies
|
||||||
|
RUN apt-get update && apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
meson \
|
||||||
|
ninja-build \
|
||||||
|
pkg-config \
|
||||||
|
libboost-all-dev \
|
||||||
|
libgtest-dev \
|
||||||
|
libgmock-dev \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy source files
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Build the project
|
||||||
|
RUN meson setup builddir --buildtype=release
|
||||||
|
RUN meson compile -C builddir
|
||||||
|
|
||||||
|
# Run tests to ensure quality
|
||||||
|
RUN meson test -C builddir
|
||||||
|
|
||||||
|
# Runtime stage - minimal Alpine Linux
|
||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
# Install runtime dependencies (if any)
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
libstdc++ \
|
||||||
|
&& addgroup -g 1000 finger \
|
||||||
|
&& adduser -D -s /bin/sh -u 1000 -G finger finger
|
||||||
|
|
||||||
|
# Copy the compiled binary from builder stage
|
||||||
|
COPY --from=builder /app/builddir/finger /usr/local/bin/finger
|
||||||
|
|
||||||
|
# Make the binary executable
|
||||||
|
RUN chmod +x /usr/local/bin/finger
|
||||||
|
|
||||||
|
# Create the directory for user data with proper permissions
|
||||||
|
RUN mkdir -p /var/finger/users && \
|
||||||
|
chown -R finger:finger /var/finger
|
||||||
|
|
||||||
|
# Switch to non-root user
|
||||||
|
USER finger
|
||||||
|
|
||||||
|
# Expose port 79 (finger protocol)
|
||||||
|
EXPOSE 79
|
||||||
|
|
||||||
|
# Add health check
|
||||||
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||||
|
CMD nc -z localhost 79 || exit 1
|
||||||
|
|
||||||
|
# Set metadata labels
|
||||||
|
LABEL org.opencontainers.image.title="finger"
|
||||||
|
LABEL org.opencontainers.image.description="A silly finger service written in C++20"
|
||||||
|
LABEL org.opencontainers.image.source="https://github.com/waffle2k/finger"
|
||||||
|
LABEL org.opencontainers.image.licenses="MIT"
|
||||||
|
|
||||||
|
# Set the binary as the default command
|
||||||
|
CMD ["finger"]
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
finger:
|
||||||
|
build: .
|
||||||
|
ports:
|
||||||
|
- "79:79"
|
||||||
|
volumes:
|
||||||
|
- ./users:/var/finger/users
|
||||||
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "nc", "-z", "localhost", "79"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
|
|
||||||
|
# Example using published image instead of building locally
|
||||||
|
# finger:
|
||||||
|
# image: ghcr.io/waffle2k/finger:latest
|
||||||
|
# ports:
|
||||||
|
# - "79:79"
|
||||||
|
# volumes:
|
||||||
|
# - ./users:/var/finger/users
|
||||||
|
# restart: unless-stopped
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
John Doe is currently working on the finger service project.
|
||||||
|
He's available for collaboration and can be reached via email.
|
||||||
|
|
||||||
|
Current status: Online and coding! 🚀
|
||||||
|
|
||||||
|
Last updated: January 2025
|
||||||
Reference in New Issue
Block a user