diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..4642c68 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1 @@ +task-3.0.2 diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..2373fea --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,48 @@ +# Use the official Golang image for building the backend +FROM golang:1.22-alpine as build + +# Set working directory +WORKDIR /app + +# Copy go.mod and go.sum files +COPY go.mod go.sum ./ +RUN go mod tidy + +# Copy the rest of the application code +COPY . . + +# Copy the .env file +COPY .env .env + +# Install dependencies for Taskwarrior and libuuid-dev +RUN apk add --no-cache cmake g++ make tar util-linux-dev rust cargo libuuid libstdc++ +RUN apk update +RUN apk add util-linux +RUN apk add libgcc +RUN apk add libstdc++ + +# Copy Taskwarrior source code and build it +COPY task-3.0.2.tar.gz /tmp/task-3.0.2.tar.gz +RUN tar xzf /tmp/task-3.0.2.tar.gz && \ + cd task-3.0.2 && \ + cmake -DCMAKE_BUILD_TYPE=release . && \ + make && \ + make install + +# Build the Go application +RUN go build -o main . + +# Use a minimal image for running the backend (Can use others as well) +FROM alpine:latest +WORKDIR /root/ + +# Copy the binary and .env file from the build stage +COPY --from=build /app/main . +COPY --from=build /app/.env . +COPY --from=build /usr/local/bin/task /usr/local/bin/task + +# Expose port 8000 +EXPOSE 8000 + +# Command to run the executable +CMD ["./main"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f3597e8 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,32 @@ +services: + frontend: + build: + context: ./frontend + dockerfile: Dockerfile + ports: + - "80:80" + networks: + - tasknetwork + + backend: + build: + context: ./backend + dockerfile: Dockerfile + ports: + - "8000:8000" + networks: + - tasknetwork + depends_on: + - syncserver + + syncserver: + # THIS IMAGE SHOULD BE PULLED FROM THE OFFICIAL TASKCHAMPION-SYNC-SERVER REPOSITORY + image: taskchampion-sync-server:latest + ports: + - "8080:8080" + networks: + - tasknetwork + +networks: + tasknetwork: + driver: bridge diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..fe773c2 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,26 @@ +# Use node image for building the frontend +FROM node:16-alpine as build + +# Set working directory +WORKDIR /app + +# Copy package.json and install dependencies +COPY package.json package-lock.json ./ +RUN npm install + +# Copy the rest of the application code and build +COPY . . +RUN npm run build + +# Serve the frontend using nginx +FROM nginx:alpine +COPY --from=build /app/dist /usr/share/nginx/html + +# Copy nginx configuration file +COPY nginx.conf /etc/nginx/conf.d/default.conf + +# Expose port 80 +EXPOSE 80 + +# Start nginx +CMD ["nginx", "-g", "daemon off;"] diff --git a/frontend/nginx.conf b/frontend/nginx.conf new file mode 100644 index 0000000..480ca38 --- /dev/null +++ b/frontend/nginx.conf @@ -0,0 +1,8 @@ +server { + listen 80; + + location / { + root /usr/share/nginx/html; + try_files $uri /index.html; + } +} diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 13c08d5..23adf52 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -13,10 +13,12 @@ "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-navigation-menu": "^1.1.4", "@radix-ui/react-slot": "^1.0.2", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", + "date-fns": "^3.6.0", "firebase": "^10.12.2", "lucide-react": "^0.294.0", "react": "^18.2.0", @@ -1966,6 +1968,29 @@ } } }, + "node_modules/@radix-ui/react-label": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.0.2.tgz", + "integrity": "sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-menu": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.0.6.tgz", @@ -3285,6 +3310,15 @@ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==", "devOptional": true }, + "node_modules/date-fns": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", + "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", diff --git a/frontend/package.json b/frontend/package.json index 5c8fc2c..5d83c1f 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,10 +16,12 @@ "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-dropdown-menu": "^2.0.6", "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-navigation-menu": "^1.1.4", "@radix-ui/react-slot": "^1.0.2", "class-variance-authority": "^0.7.0", "clsx": "^2.0.0", + "date-fns": "^3.6.0", "firebase": "^10.12.2", "lucide-react": "^0.294.0", "react": "^18.2.0",