diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..914e7c1 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,27 @@ +ARG NODE_VERSION + +FROM node:${NODE_VERSION}-alpine AS base + +# Install libc6-compat for better compatibility +RUN apk add --no-cache libc6-compat + +# Enable Corepack +RUN corepack enable + +WORKDIR /app + +# Copy dependency files +COPY package.json pnpm-lock.yaml ./ + +# Copy prisma schema +COPY prisma ./prisma + +# Install dependencies +RUN pnpm install --frozen-lockfile + +# Copy source code +COPY . . + +EXPOSE 3000 + +CMD ["pnpm", "dev"] \ No newline at end of file diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..6e951ba --- /dev/null +++ b/compose.yaml @@ -0,0 +1,15 @@ +services: + web: + build: + context: . + args: + NODE_VERSION: 24.11.1 + volumes: + - .:/app + - /app/node_modules + - /app/.next + environment: + - WATCHPACK_POLLING=true + - CI=true + ports: + - "3000:3000" \ No newline at end of file diff --git a/docker.py b/docker.py new file mode 100755 index 0000000..daddcc9 --- /dev/null +++ b/docker.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python3 + +import subprocess +import sys +from dataclasses import dataclass + +@dataclass +class Command: + name: str + cmd: list[str] + error_msg: str + silent: bool = True + +REQUISITE_COMMANDS = [ + Command( + name="check_docker", + cmd=["docker", "-v"], + error_msg="[FATAL]: Check that you have Docker installed." + ), + Command( + name="check_compose", + cmd=["docker", "compose", "version"], + error_msg="[FATAL]: Check that you have Docker compose installed." + ), + Command( + name="check_docker_running", + cmd=["docker", "info"], + error_msg="[FATAL]: Check that Docker is running." + ), +] + +COMPOSE_COMMANDS = { + "s": Command( + name="docker_compose_up_build", + cmd=["docker", "compose", "up", "-d", "--build"], + error_msg="[FATAL]: Failed to build and start containers. Check logs.", + silent=False + ), + "d": Command( + name="docker_compose_down_and_cleanup", + cmd=["sh", "-c", "docker compose down -v --rmi local && rm -rf ./.pnpm-store"], + error_msg="[FATAL]: Failed to cleanup Docker containers and local files.", + silent=False + ) +} + +def execute(c: Command): + print(f"[LOG]: Executing command: {c.name}.") + p = subprocess.Popen( + c.cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + bufsize=1 + ) + + if not c.silent: + for line in p.stdout: + print(line, end="") + + code = p.wait() + if code != 0: + print(f"{c.error_msg} [CODE={code}]") + sys.exit(code) + +if __name__ == "__main__": + choice = input("Would you like to start [s/S] or destroy [d/D] (all other options will be ignored): ").lower() + + if choice not in ["s", "d"]: + print("Invalid option. Aborting.") + sys.exit(1) + + for command in REQUISITE_COMMANDS: + execute(command) + + print("[LOG]: Starting main execution. If building, please wait a minute.") + execute(COMPOSE_COMMANDS[choice]) + print("[LOG]: Execution complete. If destroying, please refresh source control.") + sys.exit(0) \ No newline at end of file