Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Environment Variables
.env

# Apple Push Notification Certificate
*.p8

# Node
node_modules
46 changes: 34 additions & 12 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,22 +1,44 @@
FROM node:latest
# Build stage
FROM node:22-alpine AS builder

# Install wait-for-it
RUN apt-get update && apt-get install -y wait-for-it
# Add metadata labels
LABEL maintainer="Hamlet Jiang Su"
LABEL description="Thunder server for handling notifications and related services"
LABEL version="0.1.0"

# Set working directory in the container
# Set working directory
WORKDIR /app

# Copy package.json and package-lock.json to the working directory
# Copy package files
COPY package*.json ./
COPY tsconfig.json ./

# Install dependencies
RUN npm install
RUN npm ci --only=production=false

# Copy the rest of the application code to the working directory
COPY . .
# Copy source code
COPY src/ ./src/

# Expose the port the app runs on
EXPOSE 5100
# Build TypeScript to JavaScript
RUN npm run build || npx tsc

# Production stage
FROM node:22-alpine AS production

# Wait for PostgreSQL to be ready and then start the Node.js server
CMD wait-for-it $POSTGRES_HOSTNAME:5432 -- npm start
# Set working directory
WORKDIR /app

# Copy package files
COPY package*.json ./

# Install only production dependencies
RUN npm ci --only=production

# Copy built application from builder stage
COPY --from=builder /app/dist ./dist

# Expose the port the app runs on
EXPOSE 2831

# Start the server
CMD ["node", "dist/index.js"]
83 changes: 83 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<p align="center">
<img src="https://raw.githubusercontent.com/thunder-app/thunder/refs/heads/develop/assets/logo.png" alt="Thunder Server" width="200">
</p>

<h1 align="center">Thunder Server</h1>

<p align="center">
A companion server which handles Thunder related services
</p>

<p align="center">
<a href="https://lemmy.world/c/thunder_app">
<img src="https://img.shields.io/lemmy/thunder_app%40lemmy.world?label=lemmy%20community" alt="Lemmy">
</a>
<a href="https://matrix.to/#/#thunderapp:matrix.org">
<img src="https://img.shields.io/badge/chat-matrix-blue?style=flat&logo=matrix" alt="Matrix">
</a>
</p>

<p align="center">
<a href="#overview">Overview</a> •
<a href="#features">Features</a> •
<a href="#quick-setup-guide">Quick Setup</a> •
<a href="#environment-configuration">Configuration</a> •
<a href="#contributing">Contributing</a>
</p>

## Overview

Thunder Server is an **experimental** companion service for [Thunder](https://github.com/thunder-app/thunder) that handles push notifications for both UnifiedPush and Apple Push Notification Service (APNs).

## Features

- **Push Notifications**: Supports both UnifiedPush and Apple Push Notification Service (APNs)
- **Multi-Account Support**: Polls and delivers notifications for multiple accounts
- **Docker-Ready**: Pre-configured Docker containers for easy deployment

## Quick Setup Guide

A docker compose configuration is provided for quick deployment. For custom deployments, docker images are available via GitHub.

### Setup

```bash
# Clone the repository
git clone https://github.com/thunder-app/thunder-server.git
cd thunder-server

# Copy and configure environment variables
cp example.env .env

# Start the server and database
docker-compose up -d
```

The server will be available at `http://localhost:2831` by default.

## Environment Configuration

Configure your environment by copying `example.env` to `.env` and updating the following settings:

### Application Settings
```bash
APP_PORT=2831
```

### Database Configuration
```bash
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
POSTGRES_HOSTNAME=postgres
POSTGRES_PORT=5432
POSTGRES_DATABASE=thunder_database
```

### Apple Push Notifications (APNs)
```bash
APNS_KEY_ID=your_key_id # Your Apple Developer Key ID
APNS_TEAM_ID=your_team_id # Your Apple Developer Team ID
APNS_APP_BUNDLE_ID=com.example.thunder # Your app's bundle identifier
```

> **Note**: For APNs to work, you'll need to configure your Apple Developer account and obtain the necessary certificates.
38 changes: 29 additions & 9 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,23 +1,43 @@
version: '3.8'

services:
main:
thunder-server:
build: .
ports:
- "5100:2831"
- "${APP_PORT:-2831}:2831"
depends_on:
- postgres
postgres:
condition: service_healthy
env_file: .env
environment:
- POSTGRES_HOSTNAME=postgres
- POSTGRES_PORT=5432
restart: unless-stopped
networks:
- thunder-network

postgres:
image: postgres:latest
restart: always
image: postgres:17-alpine
restart: unless-stopped
env_file: .env
environment:
POSTGRES_DB: database
- POSTGRES_DB=${POSTGRES_DATABASE:-thunder_database}
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password}
ports:
- "5432:5432"
- "${POSTGRES_PORT:-5432}:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- thunder-network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-postgres} -d ${POSTGRES_DATABASE:-thunder_database}"]
interval: 5s
timeout: 5s
retries: 5

volumes:
postgres_data:
driver: local

networks:
thunder-network:
driver: bridge
11 changes: 8 additions & 3 deletions example.env
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# Application Configuration
APP_PORT=2831

# PostgreSQL Database Configuration
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
POSTGRES_HOSTNAME=postgres
POSTGRES_PORT=5432
POSTGRES_DATABASE=thunder_database

APNS_KEY_ID=key_id
APNS_TEAM_ID=team_id
APNS_APP_BUNDLE_ID=com.example
# Apple Push Notification Service (APNS) Configuration
# APNS_KEY_ID=key_id
# APNS_TEAM_ID=team_id
# APNS_APP_BUNDLE_ID=com.example
Loading