diff options
| -rw-r--r-- | .dockerignore | 4 | ||||
| -rw-r--r-- | Caddyfile | 3 | ||||
| -rw-r--r-- | Dockerfile | 26 | ||||
| -rw-r--r-- | app/lib/db.server.ts | 4 | ||||
| -rw-r--r-- | docker-compose.yml | 29 | ||||
| -rwxr-xr-x | scripts/server-setup.sh | 35 |
6 files changed, 85 insertions, 16 deletions
diff --git a/.dockerignore b/.dockerignore index 9b8d514..a0f79e8 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,4 +1,6 @@ .react-router build node_modules -README.md
\ No newline at end of file +README.md +data +events
\ No newline at end of file diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..8db7f4d --- /dev/null +++ b/Caddyfile @@ -0,0 +1,3 @@ +golive.yyamashita.com { + reverse_proxy app:3000 +} @@ -1,22 +1,20 @@ -FROM node:20-alpine AS development-dependencies-env -COPY . /app +FROM node:20-alpine AS deps +COPY package.json package-lock.json /app/ WORKDIR /app RUN npm ci -FROM node:20-alpine AS production-dependencies-env -COPY ./package.json package-lock.json /app/ -WORKDIR /app -RUN npm ci --omit=dev - -FROM node:20-alpine AS build-env +FROM node:20-alpine AS build COPY . /app/ -COPY --from=development-dependencies-env /app/node_modules /app/node_modules +COPY --from=deps /app/node_modules /app/node_modules WORKDIR /app RUN npm run build -FROM node:20-alpine -COPY ./package.json package-lock.json /app/ -COPY --from=production-dependencies-env /app/node_modules /app/node_modules -COPY --from=build-env /app/build /app/build +FROM node:20-slim WORKDIR /app -CMD ["npm", "run", "start"]
\ No newline at end of file +COPY package.json package-lock.json ./ +RUN npm ci --omit=dev +COPY --from=build /app/build ./build +RUN npx playwright install chromium --with-deps +RUN mkdir -p /app/data +EXPOSE 3000 +CMD ["npm", "start"] diff --git a/app/lib/db.server.ts b/app/lib/db.server.ts index 26735c6..6da5a1c 100644 --- a/app/lib/db.server.ts +++ b/app/lib/db.server.ts @@ -3,7 +3,9 @@ import path from "path"; import { fileURLToPath } from "url"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const DB_PATH = path.join(__dirname, "../../events.db"); +const DB_PATH = process.env.DB_PATH + ? path.resolve(process.env.DB_PATH) + : path.join(__dirname, "../../events.db"); let _db: Database.Database | null = null; diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..69feee9 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,29 @@ +services: + app: + build: . + expose: + - "3000" + volumes: + - ./data:/app/data + environment: + - NODE_ENV=production + - DB_PATH=/app/data/events.db + restart: unless-stopped + + caddy: + image: caddy:2-alpine + ports: + - "80:80" + - "443:443" + - "443:443/udp" + volumes: + - ./Caddyfile:/etc/caddy/Caddyfile + - caddy_data:/data + - caddy_config:/config + depends_on: + - app + restart: unless-stopped + +volumes: + caddy_data: + caddy_config: diff --git a/scripts/server-setup.sh b/scripts/server-setup.sh new file mode 100755 index 0000000..f01d3fb --- /dev/null +++ b/scripts/server-setup.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# Run this once on a fresh Hetzner VPS (as root) +set -e + +APP_DIR=/app +REPO_DIR=/var/git/tokyo-livehouse-events.git + +# Install Docker +curl -fsSL https://get.docker.com | sh + +# Create app directory +mkdir -p "$APP_DIR" + +# Create bare git repo +mkdir -p "$REPO_DIR" +git init --bare "$REPO_DIR" + +# Create post-receive hook +cat > "$REPO_DIR/hooks/post-receive" << 'EOF' +#!/bin/bash +set -e +APP_DIR=/app +GIT_WORK_TREE=$APP_DIR git checkout -f +cd $APP_DIR +mkdir -p data +docker compose up -d --build +echo "Deploy complete" +EOF + +chmod +x "$REPO_DIR/hooks/post-receive" + +echo "" +echo "Setup complete. On your local machine, run:" +echo " git remote add hetzner root@<server-ip>:$REPO_DIR" +echo " git push hetzner main" |
