Initial commit: 23 docker stacks for GitOps deployment
Stacks included:
- Infrastructure: traefik, authentik, gitea, registry, watchtower, dockge
- Monitoring: smokeping, changedetection
- Apps: ghost, gollum, wallabag, radicale, invidious, xbackbone, filebrowser, syncthing, zerotier
- Custom: obsidian-tools, memento, perilous, ramz, bookclub, brain
🤖 Generated with Claude Code
This commit is contained in:
14
stacks/bookclub/.env.template
Normal file
14
stacks/bookclub/.env.template
Normal file
@@ -0,0 +1,14 @@
|
||||
DOMAIN=${DOMAIN}
|
||||
SMTP_HOST=${BOOKCLUB_SMTP_HOST}
|
||||
SMTP_PORT=465
|
||||
SMTP_SECURE=true
|
||||
SMTP_USER=${BOOKCLUB_SMTP_USER}
|
||||
SMTP_PASS=${BOOKCLUB_SMTP_PASS}
|
||||
MAIL_FROM=${BOOKCLUB_MAIL_FROM}
|
||||
MAIL_TO=${BOOKCLUB_MAIL_TO}
|
||||
SECRET_PHRASE=${BOOKCLUB_SECRET_PHRASE}
|
||||
THANK_YOU_URL=/thanks.html
|
||||
BIND_HOST=0.0.0.0
|
||||
BIND_PORT=3000
|
||||
TRUST_PROXY=true
|
||||
TZ=America/New_York
|
||||
7
stacks/bookclub/Dockerfile
Normal file
7
stacks/bookclub/Dockerfile
Normal file
@@ -0,0 +1,7 @@
|
||||
FROM node:20-alpine
|
||||
WORKDIR /app
|
||||
COPY package.json ./
|
||||
RUN npm install
|
||||
COPY server.js ./
|
||||
EXPOSE 3000
|
||||
CMD ["node", "server.js"]
|
||||
20
stacks/bookclub/docker-compose.yml
Normal file
20
stacks/bookclub/docker-compose.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
services:
|
||||
form-mailer:
|
||||
build: .
|
||||
container_name: bookclub-form-mailer
|
||||
restart: unless-stopped
|
||||
env_file:
|
||||
- .env
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.form-mailer.rule=Host(`bookclub.${DOMAIN}`)"
|
||||
- "traefik.http.routers.form-mailer.entrypoints=https"
|
||||
- "traefik.http.routers.form-mailer.tls=true"
|
||||
- "traefik.http.routers.form-mailer.tls.certresolver=http"
|
||||
- "traefik.http.services.form-mailer.loadbalancer.server.port=3000"
|
||||
networks:
|
||||
- web
|
||||
|
||||
networks:
|
||||
web:
|
||||
external: true
|
||||
13
stacks/bookclub/package.json
Normal file
13
stacks/bookclub/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "bookclub-form-mailer",
|
||||
"version": "1.0.0",
|
||||
"description": "Simple form mailer service",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"start": "node server.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"nodemailer": "^6.9.7"
|
||||
}
|
||||
}
|
||||
51
stacks/bookclub/server.js
Normal file
51
stacks/bookclub/server.js
Normal file
@@ -0,0 +1,51 @@
|
||||
const express = require('express');
|
||||
const nodemailer = require('nodemailer');
|
||||
|
||||
const app = express();
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
app.use(express.json());
|
||||
|
||||
if (process.env.TRUST_PROXY === 'true') {
|
||||
app.set('trust proxy', true);
|
||||
}
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: process.env.SMTP_HOST,
|
||||
port: parseInt(process.env.SMTP_PORT || '465'),
|
||||
secure: process.env.SMTP_SECURE === 'true',
|
||||
auth: {
|
||||
user: process.env.SMTP_USER,
|
||||
pass: process.env.SMTP_PASS
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/submit', async (req, res) => {
|
||||
const { secret, ...formData } = req.body;
|
||||
|
||||
if (secret !== process.env.SECRET_PHRASE) {
|
||||
return res.status(403).send('Invalid secret phrase');
|
||||
}
|
||||
|
||||
try {
|
||||
await transporter.sendMail({
|
||||
from: process.env.MAIL_FROM,
|
||||
to: process.env.MAIL_TO,
|
||||
subject: 'New Form Submission',
|
||||
text: Object.entries(formData)
|
||||
.map(([key, value]) => `${key}: ${value}`)
|
||||
.join('\n')
|
||||
});
|
||||
|
||||
res.redirect(process.env.THANK_YOU_URL || '/thanks.html');
|
||||
} catch (error) {
|
||||
console.error('Mail error:', error);
|
||||
res.status(500).send('Failed to send email');
|
||||
}
|
||||
});
|
||||
|
||||
const port = parseInt(process.env.BIND_PORT || '3000');
|
||||
const host = process.env.BIND_HOST || '0.0.0.0';
|
||||
|
||||
app.listen(port, host, () => {
|
||||
console.log(`Form mailer listening on ${host}:${port}`);
|
||||
});
|
||||
Reference in New Issue
Block a user