fix docker mounts — data dir + env path vars
This commit is contained in:
+4
-3
@@ -6,8 +6,9 @@ services:
|
|||||||
environment:
|
environment:
|
||||||
- PORT=3333
|
- PORT=3333
|
||||||
- ADMIN_PASSWORD=changeme
|
- ADMIN_PASSWORD=changeme
|
||||||
|
- DB_PATH=/app/data/colony.json
|
||||||
|
- DECKS_PATH=/app/data/decks.json
|
||||||
|
- DECK_IMAGES_PATH=/app/data/deck-images
|
||||||
volumes:
|
volumes:
|
||||||
- ./data/colony.json:/app/colony.json
|
- ./data:/app/data
|
||||||
- ./data/decks.json:/app/decks.json
|
|
||||||
- ./data/deck-images:/app/assets/deck-images
|
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
+3
-14
@@ -1,17 +1,6 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
set -e
|
||||||
|
mkdir -p /app/data /app/assets/deck-images
|
||||||
# If Docker created these paths as directories (because the host file didn't exist),
|
[ -f /app/data/colony.json ] || echo '{"games":[]}' > /app/data/colony.json
|
||||||
# remove them and create proper JSON files.
|
[ -f /app/data/decks.json ] || echo '{"decks":[]}' > /app/data/decks.json
|
||||||
for f in /app/colony.json /app/decks.json; do
|
|
||||||
if [ -d "$f" ]; then
|
|
||||||
rm -rf "$f"
|
|
||||||
fi
|
|
||||||
if [ ! -f "$f" ]; then
|
|
||||||
echo '{}' > "$f"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
mkdir -p /app/assets/deck-images
|
|
||||||
|
|
||||||
exec node server.js
|
exec node server.js
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ function broadcast(slug) {
|
|||||||
try { res.write(msg) } catch {}
|
try { res.write(msg) } catch {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const DB_PATH = path.join(__dirname, 'colony.json')
|
const DB_PATH = process.env.DB_PATH || path.join(__dirname, 'colony.json')
|
||||||
|
const DECKS_PATH = process.env.DECKS_PATH || path.join(__dirname, 'decks.json')
|
||||||
|
const DECK_IMAGES_PATH = process.env.DECK_IMAGES_PATH || path.join(__dirname, 'assets', 'deck-images')
|
||||||
|
|
||||||
function loadDB() {
|
function loadDB() {
|
||||||
try { return JSON.parse(fs.readFileSync(DB_PATH, 'utf8')) }
|
try { return JSON.parse(fs.readFileSync(DB_PATH, 'utf8')) }
|
||||||
@@ -289,13 +291,13 @@ app.delete('/api/games/:slug/keywords/:id', requirePassword, (req, res) => {
|
|||||||
|
|
||||||
// --- Decks (image libraries) ---
|
// --- Decks (image libraries) ---
|
||||||
function loadDecks() {
|
function loadDecks() {
|
||||||
try { return JSON.parse(fs.readFileSync(path.join(__dirname, 'decks.json'), 'utf8')) }
|
try { return JSON.parse(fs.readFileSync(DECKS_PATH, 'utf8')) }
|
||||||
catch { return { decks: [] } }
|
catch { return { decks: [] } }
|
||||||
}
|
}
|
||||||
function saveDecks(data) {
|
function saveDecks(data) {
|
||||||
const tmp = path.join(__dirname, 'decks.json') + '.tmp'
|
const tmp = DECKS_PATH + '.tmp'
|
||||||
fs.writeFileSync(tmp, JSON.stringify(data, null, 2))
|
fs.writeFileSync(tmp, JSON.stringify(data, null, 2))
|
||||||
fs.renameSync(tmp, path.join(__dirname, 'decks.json'))
|
fs.renameSync(tmp, DECKS_PATH)
|
||||||
}
|
}
|
||||||
|
|
||||||
app.get('/api/decks', (req, res) => {
|
app.get('/api/decks', (req, res) => {
|
||||||
@@ -328,7 +330,7 @@ app.delete('/api/decks/:id', requireAdmin, (req, res) => {
|
|||||||
if (idx === -1) return res.status(404).json({ error: 'Deck not found' })
|
if (idx === -1) return res.status(404).json({ error: 'Deck not found' })
|
||||||
// Delete image files
|
// Delete image files
|
||||||
for (const img of db.decks[idx].images || []) {
|
for (const img of db.decks[idx].images || []) {
|
||||||
try { fs.unlinkSync(path.join(__dirname, 'assets', 'deck-images', img.filename)) } catch {}
|
try { fs.unlinkSync(path.join(DECK_IMAGES_PATH, img.filename)) } catch {}
|
||||||
}
|
}
|
||||||
db.decks.splice(idx, 1)
|
db.decks.splice(idx, 1)
|
||||||
saveDecks(db)
|
saveDecks(db)
|
||||||
@@ -368,7 +370,7 @@ app.delete('/api/decks/:deckId/cards/:cardId', requireAdmin, (req, res) => {
|
|||||||
const idx = (deck.cards || []).findIndex(c => c.id === req.params.cardId)
|
const idx = (deck.cards || []).findIndex(c => c.id === req.params.cardId)
|
||||||
if (idx === -1) return res.status(404).json({ error: 'Card not found' })
|
if (idx === -1) return res.status(404).json({ error: 'Card not found' })
|
||||||
for (const img of deck.cards[idx].images || []) {
|
for (const img of deck.cards[idx].images || []) {
|
||||||
try { fs.unlinkSync(path.join(__dirname, 'assets', 'deck-images', img.filename)) } catch {}
|
try { fs.unlinkSync(path.join(DECK_IMAGES_PATH, img.filename)) } catch {}
|
||||||
}
|
}
|
||||||
deck.cards.splice(idx, 1)
|
deck.cards.splice(idx, 1)
|
||||||
saveDecks(db)
|
saveDecks(db)
|
||||||
@@ -385,8 +387,8 @@ app.post('/api/decks/:deckId/cards/:cardId/images', requireAdmin, (req, res) =>
|
|||||||
if (!data) return res.status(400).json({ error: 'data required' })
|
if (!data) return res.status(400).json({ error: 'data required' })
|
||||||
const ext = path.extname(filename || '.jpg') || '.jpg'
|
const ext = path.extname(filename || '.jpg') || '.jpg'
|
||||||
const savedName = `deck-${newId()}${ext}`
|
const savedName = `deck-${newId()}${ext}`
|
||||||
fs.mkdirSync(path.join(__dirname, 'assets', 'deck-images'), { recursive: true })
|
fs.mkdirSync(DECK_IMAGES_PATH, { recursive: true })
|
||||||
fs.writeFileSync(path.join(__dirname, 'assets', 'deck-images', savedName), Buffer.from(data, 'base64'))
|
fs.writeFileSync(path.join(DECK_IMAGES_PATH, savedName), Buffer.from(data, 'base64'))
|
||||||
const img = { id: newId(), filename: savedName, keywords: keywords || [], created_at: now() }
|
const img = { id: newId(), filename: savedName, keywords: keywords || [], created_at: now() }
|
||||||
card.images = card.images || []
|
card.images = card.images || []
|
||||||
card.images.push(img)
|
card.images.push(img)
|
||||||
@@ -402,7 +404,7 @@ app.delete('/api/decks/:deckId/cards/:cardId/images/:imgId', requireAdmin, (req,
|
|||||||
if (!card) return res.status(404).json({ error: 'Card not found' })
|
if (!card) return res.status(404).json({ error: 'Card not found' })
|
||||||
const idx = (card.images || []).findIndex(i => i.id === req.params.imgId)
|
const idx = (card.images || []).findIndex(i => i.id === req.params.imgId)
|
||||||
if (idx === -1) return res.status(404).json({ error: 'Image not found' })
|
if (idx === -1) return res.status(404).json({ error: 'Image not found' })
|
||||||
try { fs.unlinkSync(path.join(__dirname, 'assets', 'deck-images', card.images[idx].filename)) } catch {}
|
try { fs.unlinkSync(path.join(DECK_IMAGES_PATH, card.images[idx].filename)) } catch {}
|
||||||
card.images.splice(idx, 1)
|
card.images.splice(idx, 1)
|
||||||
saveDecks(db)
|
saveDecks(db)
|
||||||
res.json({ ok: true })
|
res.json({ ok: true })
|
||||||
@@ -417,7 +419,7 @@ app.post('/api/decks/:id/images', requireAdmin, (req, res) => {
|
|||||||
if (!data) return res.status(400).json({ error: 'data required' })
|
if (!data) return res.status(400).json({ error: 'data required' })
|
||||||
const ext = path.extname(filename || '.jpg') || '.jpg'
|
const ext = path.extname(filename || '.jpg') || '.jpg'
|
||||||
const savedName = `deck-${newId()}${ext}`
|
const savedName = `deck-${newId()}${ext}`
|
||||||
const imgPath = path.join(__dirname, 'assets', 'deck-images', savedName)
|
const imgPath = path.join(DECK_IMAGES_PATH, savedName)
|
||||||
fs.mkdirSync(path.dirname(imgPath), { recursive: true })
|
fs.mkdirSync(path.dirname(imgPath), { recursive: true })
|
||||||
fs.writeFileSync(imgPath, Buffer.from(data, 'base64'))
|
fs.writeFileSync(imgPath, Buffer.from(data, 'base64'))
|
||||||
const img = { id: newId(), filename: savedName, keywords: keywords || [], created_at: now() }
|
const img = { id: newId(), filename: savedName, keywords: keywords || [], created_at: now() }
|
||||||
@@ -444,7 +446,7 @@ app.delete('/api/decks/:deckId/images/:imgId', requireAdmin, (req, res) => {
|
|||||||
if (!deck) return res.status(404).json({ error: 'Deck not found' })
|
if (!deck) return res.status(404).json({ error: 'Deck not found' })
|
||||||
const idx = deck.images.findIndex(i => i.id === req.params.imgId)
|
const idx = deck.images.findIndex(i => i.id === req.params.imgId)
|
||||||
if (idx === -1) return res.status(404).json({ error: 'Image not found' })
|
if (idx === -1) return res.status(404).json({ error: 'Image not found' })
|
||||||
try { fs.unlinkSync(path.join(__dirname, 'assets', 'deck-images', deck.images[idx].filename)) } catch {}
|
try { fs.unlinkSync(path.join(DECK_IMAGES_PATH, deck.images[idx].filename)) } catch {}
|
||||||
deck.images.splice(idx, 1)
|
deck.images.splice(idx, 1)
|
||||||
saveDecks(db)
|
saveDecks(db)
|
||||||
res.json({ ok: true })
|
res.json({ ok: true })
|
||||||
|
|||||||
Reference in New Issue
Block a user