fix: create data dir with 777 perms + handle in code
Deploy / build-and-deploy (push) Successful in 1m48s
Deploy / build-and-deploy (push) Successful in 1m48s
This commit is contained in:
@@ -31,8 +31,9 @@ jobs:
|
|||||||
|
|
||||||
- name: Copy files to server
|
- name: Copy files to server
|
||||||
run: |
|
run: |
|
||||||
|
ssh root@barabingo 'mkdir -p /opt/barabingo/data /opt/barabingo/uploads'
|
||||||
scp /tmp/barabingo.tar.gz docker-compose.yml root@barabingo:/opt/barabingo/
|
scp /tmp/barabingo.tar.gz docker-compose.yml root@barabingo:/opt/barabingo/
|
||||||
|
|
||||||
- name: Deploy on server
|
- name: Deploy on server
|
||||||
run: |
|
run: |
|
||||||
ssh root@barabingo 'cd /opt/barabingo && docker load < barabingo.tar.gz && docker compose down --remove-orphans 2>/dev/null; docker compose up -d && rm -f barabingo.tar.gz && docker image prune -f'
|
ssh root@barabingo 'chmod 777 /opt/barabingo/data /opt/barabingo/uploads && cd /opt/barabingo && docker load < barabingo.tar.gz && docker compose down --remove-orphans 2>/dev/null; docker compose up -d && rm -f barabingo.tar.gz && docker image prune -f'
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ COPY --from=builder /app/public ./public
|
|||||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
|
|
||||||
RUN mkdir -p /app/data && chown nextjs:nodejs /app/data
|
RUN mkdir -p /app/data /app/public/uploads && chmod 777 /app/data /app/public/uploads
|
||||||
|
|
||||||
USER nextjs
|
USER nextjs
|
||||||
|
|
||||||
|
|||||||
+56
-54
@@ -2,63 +2,65 @@ import Database from "better-sqlite3";
|
|||||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||||
import * as schema from "./schema";
|
import * as schema from "./schema";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
import fs from "fs";
|
||||||
|
|
||||||
const DB_PATH = path.join(process.cwd(), "data", "bingo.db");
|
const DB_DIR = path.join(process.cwd(), "data");
|
||||||
|
const DB_PATH = path.join(DB_DIR, "bingo.db");
|
||||||
|
|
||||||
function getDb() {
|
try {
|
||||||
const sqlite = new Database(DB_PATH);
|
fs.mkdirSync(DB_DIR, { recursive: true, mode: 0o777 });
|
||||||
sqlite.pragma("journal_mode = WAL");
|
} catch {}
|
||||||
sqlite.pragma("foreign_keys = ON");
|
|
||||||
return sqlite;
|
|
||||||
}
|
|
||||||
|
|
||||||
function initDatabase(sqlite: Database.Database) {
|
const sqlite = (() => {
|
||||||
sqlite.exec(`
|
const s = new Database(DB_PATH);
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
s.pragma("journal_mode = WAL");
|
||||||
id TEXT PRIMARY KEY,
|
s.pragma("foreign_keys = ON");
|
||||||
nickname TEXT UNIQUE NOT NULL,
|
return s;
|
||||||
password_hash TEXT NOT NULL,
|
})();
|
||||||
is_admin INTEGER NOT NULL DEFAULT 0,
|
|
||||||
created_at TEXT NOT NULL
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS sessions (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
expires_at TEXT NOT NULL,
|
|
||||||
created_at TEXT NOT NULL
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS campaigns (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
grid_size INTEGER NOT NULL DEFAULT 5,
|
|
||||||
status TEXT NOT NULL DEFAULT 'active',
|
|
||||||
created_by TEXT NOT NULL REFERENCES users(id),
|
|
||||||
created_at TEXT NOT NULL
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS bingo_items (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
campaign_id TEXT NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE,
|
|
||||||
text TEXT NOT NULL,
|
|
||||||
emoji TEXT NOT NULL DEFAULT '💀',
|
|
||||||
sound_category TEXT NOT NULL DEFAULT 'horn',
|
|
||||||
sound_url TEXT,
|
|
||||||
grid_index INTEGER NOT NULL,
|
|
||||||
created_at TEXT NOT NULL
|
|
||||||
);
|
|
||||||
CREATE TABLE IF NOT EXISTS marks (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
campaign_id TEXT NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE,
|
|
||||||
item_id TEXT NOT NULL REFERENCES bingo_items(id) ON DELETE CASCADE,
|
|
||||||
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
||||||
created_at TEXT NOT NULL
|
|
||||||
);
|
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_campaign_item_pos ON bingo_items(campaign_id, grid_index);
|
|
||||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_unique_mark ON marks(campaign_id, item_id);
|
|
||||||
`);
|
|
||||||
|
|
||||||
try { sqlite.exec("ALTER TABLE bingo_items ADD COLUMN sound_url TEXT"); } catch {}
|
sqlite.exec(`
|
||||||
}
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
nickname TEXT UNIQUE NOT NULL,
|
||||||
|
password_hash TEXT NOT NULL,
|
||||||
|
is_admin INTEGER NOT NULL DEFAULT 0,
|
||||||
|
created_at TEXT NOT NULL
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS sessions (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
expires_at TEXT NOT NULL,
|
||||||
|
created_at TEXT NOT NULL
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS campaigns (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
grid_size INTEGER NOT NULL DEFAULT 5,
|
||||||
|
status TEXT NOT NULL DEFAULT 'active',
|
||||||
|
created_by TEXT NOT NULL REFERENCES users(id),
|
||||||
|
created_at TEXT NOT NULL
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS bingo_items (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
campaign_id TEXT NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE,
|
||||||
|
text TEXT NOT NULL,
|
||||||
|
emoji TEXT NOT NULL DEFAULT '💀',
|
||||||
|
sound_category TEXT NOT NULL DEFAULT 'horn',
|
||||||
|
sound_url TEXT,
|
||||||
|
grid_index INTEGER NOT NULL,
|
||||||
|
created_at TEXT NOT NULL
|
||||||
|
);
|
||||||
|
CREATE TABLE IF NOT EXISTS marks (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
campaign_id TEXT NOT NULL REFERENCES campaigns(id) ON DELETE CASCADE,
|
||||||
|
item_id TEXT NOT NULL REFERENCES bingo_items(id) ON DELETE CASCADE,
|
||||||
|
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
created_at TEXT NOT NULL
|
||||||
|
);
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_campaign_item_pos ON bingo_items(campaign_id, grid_index);
|
||||||
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_unique_mark ON marks(campaign_id, item_id);
|
||||||
|
`);
|
||||||
|
|
||||||
|
try { sqlite.exec("ALTER TABLE bingo_items ADD COLUMN sound_url TEXT"); } catch {}
|
||||||
|
|
||||||
const sqlite = getDb();
|
|
||||||
initDatabase(sqlite);
|
|
||||||
export const db = drizzle(sqlite, { schema });
|
export const db = drizzle(sqlite, { schema });
|
||||||
|
|||||||
Reference in New Issue
Block a user