Set up for docker

This commit is contained in:
Gabriel Brown 2025-01-13 16:36:01 -06:00
parent 0d5197dd94
commit fe3dabe3b7
83 changed files with 323 additions and 27 deletions

0
.eslintrc.cjs Normal file → Executable file
View File

0
.gitignore vendored Normal file → Executable file
View File

0
.prod/Dockerfile Normal file → Executable file
View File

0
.prod/update.sh Normal file → Executable file
View File

0
README.md Normal file → Executable file
View File

0
components.json Normal file → Executable file
View File

View File

@ -0,0 +1,53 @@
# syntax=docker.io/docker/dockerfile:1
FROM node:18-alpine AS base
# 1. Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i; \
else echo "Lockfile not found." && exit 1; \
fi
# 2. Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# This will do the trick, use the corresponding env file for each environment.
COPY .env .env.production
RUN npm run build
# 3. Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
COPY --from=builder /app/public ./public
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
CMD HOSTNAME="0.0.0.0" node server.js

View File

@ -0,0 +1,17 @@
services:
techtracker:
build:
context: ../../
dockerfile: docker/development/Dockerfile
image: with-docker-multi-env-development
container_name: techtracker
networks:
- node_apps
ports:
- "3004:3000"
tty: true
restart: unless-stopped
networks:
node_apps:
external: true

View File

@ -0,0 +1,54 @@
# syntax=docker.io/docker/dockerfile:1
FROM node:18-alpine AS base
# 1. Install dependencies only when needed
FROM base AS deps
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
RUN apk add --no-cache libc6-compat
WORKDIR /app
# Install dependencies based on the preferred package manager
COPY package.json yarn.lock* package-lock.json* pnpm-lock.yaml* .npmrc* ./
RUN \
if [ -f yarn.lock ]; then yarn --frozen-lockfile; \
elif [ -f package-lock.json ]; then npm ci; \
elif [ -f pnpm-lock.yaml ]; then corepack enable pnpm && pnpm i; \
else echo "Lockfile not found." && exit 1; \
fi
# 2. Rebuild the source code only when needed
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# This will do the trick, use the corresponding env file for each environment.
COPY .env .env.production
RUN npm run build
# 3. Production image, copy all the files and run next
FROM base AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
COPY --from=builder /app/public ./public
# Automatically leverage output traces to reduce image size
# https://nextjs.org/docs/advanced-features/output-file-tracing
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
CMD HOSTNAME="0.0.0.0" node server.js

View File

@ -0,0 +1,16 @@
services:
techtracker:
build:
context: ../../
dockerfile: docker/production/Dockerfile
image: with-docker-multi-env-development
container_name: techtracker
networks:
- node_apps
ports:
- "3004:3000"
tty: true
restart: unless-stopped
networks:
node_apps:
external: true

0
drizzle.config.ts Normal file → Executable file
View File

0
env.example Normal file → Executable file
View File

67
next.config.js Normal file → Executable file
View File

@ -2,36 +2,49 @@
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
* for Docker builds. * for Docker builds.
*/ */
await import("./src/env.js"); import './src/env.js';
const cspHeader = `
default-src 'self';
script-src 'self' 'unsafe-eval' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' blob: data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
`
/** @type {import("next").NextConfig} */ /** @type {import("next").NextConfig} */
const config = { const config = {
async headers() { output: 'standalone',
return [
{
source: "/(.*)",
headers: [
{
key: "Content-Security-Policy",
value: cspHeader.replace(/\n/g, ''),
},
],
},
];
},
}; };
export default config; export default config;
/**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
* for Docker builds.
*/
//await import("./src/env.js");
//const cspHeader = `
//default-src 'self';
//script-src 'self' 'unsafe-eval' 'unsafe-inline';
//style-src 'self' 'unsafe-inline';
//img-src 'self' blob: data:;
//font-src 'self';
//object-src 'none';
//base-uri 'self';
//form-action 'self';
//frame-ancestors 'none';
//upgrade-insecure-requests;
//`
//[>* @type {import("next").NextConfig} <]
//const config = {
//async headers() {
//return [
//{
//source: "/(.*)",
//headers: [
//{
//key: "Content-Security-Policy",
//value: cspHeader.replace(/\n/g, ''),
//},
//],
//},
//];
//},
//};
//export default config;

0
package.json Normal file → Executable file
View File

0
pnpm-lock.yaml generated Normal file → Executable file
View File

0
postcss.config.cjs Normal file → Executable file
View File

0
prettier.config.js Normal file → Executable file
View File

0
public/favicon.ico Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

0
public/images/default_user_pfp.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 126 KiB

0
public/images/exit_fullscreen.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

0
public/images/fullscreen.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

0
public/images/gitea_logo.svg Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

0
public/images/microsoft_logo.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 260 KiB

After

Width:  |  Height:  |  Size: 260 KiB

0
public/images/tech_tracker_appicon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 98 KiB

0
public/images/tech_tracker_favicon.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

0
public/images/tech_tracker_logo.png Normal file → Executable file
View File

Before

Width:  |  Height:  |  Size: 386 KiB

After

Width:  |  Height:  |  Size: 386 KiB

105
scripts/files_to_clipboard.py Executable file
View File

@ -0,0 +1,105 @@
#!/usr/bin/env python3
import os
import sys
import argparse
from pathlib import Path
import pyperclip
import questionary
# List of directories to exclude
EXCLUDED_DIRS = {'node_modules', '.next', '.venv', '.git', '__pycache__', '.idea', '.vscode', 'ui'}
def collect_files(project_path):
"""
Collects files from the project directory, excluding specified directories and filtering by extensions.
Returns a list of file paths relative to the project directory.
"""
collected_files = []
for root, dirs, files in os.walk(project_path):
# Exclude specified directories
dirs[:] = [d for d in dirs if d not in EXCLUDED_DIRS]
for file in files:
file_path = Path(root) / file
relative_path = file_path.relative_to(project_path)
collected_files.append(relative_path)
return collected_files
def main():
# Parse command-line arguments
parser = argparse.ArgumentParser(description='Generate Markdown from selected files.')
parser.add_argument('path', nargs='?', default='.', help='Path to the project directory')
args = parser.parse_args()
project_path = Path(args.path).resolve()
if not project_path.is_dir():
print(f"Error: '{project_path}' is not a directory.")
sys.exit(1)
# Collect files from the project directory
file_list = collect_files(project_path)
if not file_list:
print("No files found in the project directory with the specified extensions.")
sys.exit(1)
# Sort file_list for better organization
file_list.sort()
# Interactive file selection using questionary
print("\nSelect the files you want to include:")
selected_files = questionary.checkbox(
"Press space to select files, and Enter when you're done:",
choices=[str(f) for f in file_list]
).ask()
if not selected_files:
print("No files selected.")
sys.exit(1)
# Generate markdown
markdown_lines = []
markdown_lines.append('')
for selected_file in selected_files:
file_path = project_path / selected_file
try:
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Determine the language for code block from file extension
language = file_path.suffix.lstrip('.')
markdown_lines.append(f'{selected_file}')
markdown_lines.append(f'```{language}')
markdown_lines.append(content)
markdown_lines.append('```')
markdown_lines.append('')
except Exception as e:
print(f"Error reading file {selected_file}: {e}")
markdown_text = '\n'.join(markdown_lines)
# Write markdown to file
output_file = 'output.md'
with open(output_file, 'w', encoding='utf-8') as f:
f.write(markdown_text)
print(f"\nMarkdown file '{output_file}' has been generated.")
# Copy markdown content to clipboard
pyperclip.copy(markdown_text)
print("Markdown content has been copied to the clipboard.")
if __name__ == "__main__":
# Check if required libraries are installed
try:
import questionary
import pyperclip
except ImportError as e:
missing_module = e.name
print(f"Error: Missing required module '{missing_module}'.")
print(f"Please install it by running: pip install {missing_module}")
sys.exit(1)
main()

View File

@ -0,0 +1,18 @@
/**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
* for Docker builds.
*/
import './src/env.js';
/** @type {import("next").NextConfig} */
const config = {
output: 'standalone',
typescript: {
ignoreBuildErrors: true,
},
eslint: {
ignoreDuringBuilds: true,
},
};
export default config;

View File

@ -0,0 +1,13 @@
/**
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
* for Docker builds.
*/
import './src/env.js';
/** @type {import("next").NextConfig} */
const config = {
output: 'standalone',
};
export default config;

7
scripts/reload_container.sh Executable file
View File

@ -0,0 +1,7 @@
git pull
mv ~/Documents/Web/Tech_Tracker_Web/next.config.js ~/Documents/Web/Tech_Tracker_Web/scripts/next.config.default.js
cp ~/Documents/Web/Tech_Tracker_Web/scripts/next.config.build.js ~/Documents/Web/Tech_Tracker_Web/next.config.js
sudo docker compose -f docker/development/compose.yaml down
sudo docker compose -f docker/development/compose.yaml build
sudo docker compose -f docker/development/compose.yaml up -d
cp ~/Documents/Web/Tech_Tracker_Web/scripts/next.config.default.js ~/Documents/Web/Tech_Tracker_Web/next.config.js

0
src/app/api/auth/[...nextauth]/route.ts Normal file → Executable file
View File

0
src/app/api/get_paginated_history/route.ts Normal file → Executable file
View File

0
src/app/api/get_technicians/route.ts Normal file → Executable file
View File

0
src/app/api/update_status_by_id/route.ts Normal file → Executable file
View File

0
src/app/api/update_status_by_name/route.ts Normal file → Executable file
View File

0
src/app/layout.tsx Normal file → Executable file
View File

0
src/app/page.tsx Normal file → Executable file
View File

0
src/auth.ts Normal file → Executable file
View File

0
src/components/auth/client/Sign_In.tsx Normal file → Executable file
View File

0
src/components/auth/client/Sign_Out.tsx Normal file → Executable file
View File

0
src/components/auth/server/Sign_In.tsx Normal file → Executable file
View File

0
src/components/auth/server/Sign_Out.tsx Normal file → Executable file
View File

0
src/components/context/TVModeContext.tsx Normal file → Executable file
View File

0
src/components/ui/Header.tsx Normal file → Executable file
View File

0
src/components/ui/History_Drawer.tsx Normal file → Executable file
View File

0
src/components/ui/Loading.tsx Normal file → Executable file
View File

0
src/components/ui/No_Session.tsx Normal file → Executable file
View File

0
src/components/ui/TV_Toggle.tsx Normal file → Executable file
View File

0
src/components/ui/Tech_Table.tsx Normal file → Executable file
View File

0
src/components/ui/scroll-area.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/button.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/calendar.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/checkbox.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/combobox.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/command.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/date-picker.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/dialog.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/drawer.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/dropdown-menu.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/form.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/input.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/label.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/pagination.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/popover.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/progress.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/radio-group.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/scroll-area.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/select.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/switch.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/table.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/toaster.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/toggle-group.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/toggle.tsx Normal file → Executable file
View File

0
src/components/ui/shadcn/tooltip.tsx Normal file → Executable file
View File

0
src/env.js Normal file → Executable file
View File

0
src/lib/utils.ts Normal file → Executable file
View File

0
src/middleware.ts Normal file → Executable file
View File

0
src/server/db/index.ts Normal file → Executable file
View File

0
src/server/db/schema.ts Normal file → Executable file
View File

0
src/server/functions.ts Normal file → Executable file
View File

0
src/styles/globals.css Normal file → Executable file
View File

0
tailwind.config.ts Normal file → Executable file
View File

0
tsconfig.json Normal file → Executable file
View File