diff --git a/.env b/.env index 0a007615..445f287b 100644 --- a/.env +++ b/.env @@ -1,30 +1,30 @@ -# frontend: +# frontend PORT=8080 -AUTH_API_ADDRESS=http://auth-api:8081 -TODOS_API_ADDRESS=http://todos-api:8082 +AUTH_API_ADDRESS=https://nemyred.xyz/api/auth +TODOS_API_ADDRESS=https://nemyred.xyz/api/todos -# auth-api: +# auth-api AUTH_API_PORT=8081 JWT_SECRET=myfancysecret USERS_API_ADDRESS=http://users-api:8083 -# todos-api: +# todos-api JWT_SECRET=myfancysecret -REDIS_HOST=redis-queue +REDIS_HOST=redis REDIS_PORT=6379 REDIS_CHANNEL=log_channel -# users-api: +# users-api SERVER_PORT=8083 JWT_SECRET=myfancysecret -# log-message-processor: -REDIS_HOST=redis-queue +# log-message-processor +REDIS_HOST=redis REDIS_PORT=6379 REDIS_CHANNEL=log_channel -#login details +# login details (not valid environment variables - remove or handle separately) # USERNAME PASSWORD -admin Admin123 -hng HngTech -user Password +# admin Admin123 +# hng HngTech +# user Password diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ccc90aae --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +letsencrypt/ diff --git a/README.md b/README.md index 678eb616..b369fae4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# HNG12 DevOps Stage3 Task +# HNG12 DevOps Stage4 Task This Repo Contains the code for a microservice application comprising of several components communicating to each other. In other words, this is an example of microservice. These microservices are written in different languages. diff --git a/auth-api/Dockerfile b/auth-api/Dockerfile new file mode 100644 index 00000000..a5edeaee --- /dev/null +++ b/auth-api/Dockerfile @@ -0,0 +1,14 @@ +FROM golang:1.21 + +WORKDIR /app + +COPY go.mod go.sum ./ +RUN go mod download + +COPY . . + +RUN go build -o auth-api . + +EXPOSE 8080 + +CMD ["./auth-api"] diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 00000000..80242d1f --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,134 @@ +version: '3.8' + +services: + traefik: + image: traefik:v3.0 + container_name: traefik + restart: always + command: + - "--configFile=/traefik.yml" + ports: + - "80:80" + - "443:443" + - "8080:8080" + volumes: + - "/var/run/docker.sock:/var/run/docker.sock:ro" + - "./traefik.yml:/traefik.yml" + - "./letsencrypt:/letsencrypt" + labels: + - "traefik.enable=true" + - "traefik.http.routers.traefik.rule=Host(`nemyred.xyz`) && PathPrefix(`/dashboard`)" + - "traefik.http.routers.traefik.entrypoints=websecure" + - "traefik.http.routers.traefik.tls=true" + - "traefik.http.routers.traefik.tls.certresolver=letsencrypt" + - "traefik.http.services.traefik.loadbalancer.server.port=8080" + networks: + - web + + frontend: + build: ./frontend + container_name: vue_frontend + expose: + - "80" + env_file: + - .env # Ensure .env with updated AUTH_API_ADDRESS is used + environment: + - NODE_ENV=production # Force production mode to use correct env + labels: + - "traefik.enable=true" + - "traefik.http.routers.frontend.rule=Host(`nemyred.xyz`)" + - "traefik.http.routers.frontend.entrypoints=websecure" + - "traefik.http.routers.frontend.tls=true" + - "traefik.http.routers.frontend.tls.certresolver=letsencrypt" + - "traefik.http.services.frontend.loadbalancer.server.port=80" + networks: + - web + depends_on: + - auth-api + - todos-api + + auth-api: + build: ./auth-api + container_name: auth_api + expose: + - "8081" + env_file: + - .env + labels: + - "traefik.enable=true" + - "traefik.http.routers.auth.rule=Host(`nemyred.xyz`) && (PathPrefix(`/api/auth`) || PathPrefix(`/login`))" # Fallback for /login + - "traefik.http.routers.auth.entrypoints=websecure" + - "traefik.http.routers.auth.tls=true" + - "traefik.http.routers.auth.tls.certresolver=letsencrypt" + - "traefik.http.routers.auth.middlewares=auth-strip" + - "traefik.http.middlewares.auth-strip.stripprefix.prefixes=/api/auth" # Only strip /api/auth, not /login + - "traefik.http.services.auth.loadbalancer.server.port=8081" + networks: + - web + depends_on: + - users-api + + todos-api: + build: ./todos-api + container_name: todos_api + expose: + - "8082" + env_file: + - .env + labels: + - "traefik.enable=true" + - "traefik.http.routers.todos.rule=Host(`nemyred.xyz`) && PathPrefix(`/api/todos`)" + - "traefik.http.routers.todos.entrypoints=websecure" + - "traefik.http.routers.todos.tls=true" + - "traefik.http.routers.todos.tls.certresolver=letsencrypt" + - "traefik.http.routers.todos.middlewares=todos-strip" + - "traefik.http.middlewares.todos-strip.stripprefix.prefixes=/api/todos" + - "traefik.http.services.todos.loadbalancer.server.port=8082" + networks: + - web + depends_on: + - redis + + users-api: + build: ./users-api + container_name: users_api + expose: + - "8083" + env_file: + - .env + environment: + - SPRING_REDIS_HOST=redis + - SPRING_REDIS_PORT=6379 + labels: + - "traefik.enable=true" + - "traefik.http.routers.users.rule=Host(`nemyred.xyz`) && PathPrefix(`/api/users`)" + - "traefik.http.routers.users.entrypoints=websecure" + - "traefik.http.routers.users.tls=true" + - "traefik.http.routers.users.tls.certresolver=letsencrypt" + - "traefik.http.routers.users.middlewares=users-strip" + - "traefik.http.middlewares.users-strip.stripprefix.prefixes=/api/users" + - "traefik.http.services.users.loadbalancer.server.port=8083" + networks: + - web + depends_on: + - redis + + log-message-processor: + build: ./log-message-processor + container_name: log_processor + env_file: + - .env + networks: + - web + depends_on: + - redis + + redis: + image: redis:alpine + container_name: devops-stage-4-redis-1 + networks: + - web + +networks: + web: + external: true diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 00000000..4fc01ea0 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,15 @@ +FROM node:12 as build-stage + +WORKDIR /app + +COPY package*.json ./ +RUN npm install + +COPY . . + +RUN npm run build + +FROM nginx:alpine +COPY --from=build-stage /app/dist /usr/share/nginx/html +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] diff --git a/log-message-processor/Dockerfile b/log-message-processor/Dockerfile new file mode 100644 index 00000000..21b31afd --- /dev/null +++ b/log-message-processor/Dockerfile @@ -0,0 +1,17 @@ +FROM python:3.9 + +# Set the working directory +WORKDIR /app + +# Copy the requirements file +COPY requirements.txt . + +# Upgrade pip and install dependencies +RUN pip install --upgrade pip && \ + pip install redis>=5.0.0 requests>=2.31.0 thriftpy2>=0.4.16 py_zipkin --upgrade + +# Copy the application code +COPY . . + +# Run the application +CMD ["python", "main.py"] diff --git a/log-message-processor/requirements_backup.txt b/log-message-processor/requirements_backup.txt new file mode 100644 index 00000000..3cae0b2d --- /dev/null +++ b/log-message-processor/requirements_backup.txt @@ -0,0 +1,3 @@ +redis==2.10.6 +py_zipkin==0.11.0 +requests \ No newline at end of file diff --git a/todos-api/Dockerfile b/todos-api/Dockerfile new file mode 100644 index 00000000..142858b0 --- /dev/null +++ b/todos-api/Dockerfile @@ -0,0 +1,12 @@ +FROM node:16 + +WORKDIR /app + +COPY package*.json ./ +RUN npm install + +COPY . . + +EXPOSE 3000 + +CMD ["npm", "start"] diff --git a/traefik.yml b/traefik.yml new file mode 100644 index 00000000..6872c427 --- /dev/null +++ b/traefik.yml @@ -0,0 +1,31 @@ +api: + dashboard: true + insecure: true # For testing only (not recommended for production) + +entryPoints: + web: + address: ":80" + http: + redirections: + entryPoint: + to: websecure + scheme: https + websecure: + address: ":443" + +providers: + docker: + endpoint: "unix:///var/run/docker.sock" + exposedByDefault: false + network: web # Ensure Traefik uses the correct Docker network + +certificatesResolvers: + letsencrypt: + acme: + email: ndiwechi1@gmail.com + storage: /letsencrypt/acme.json + httpChallenge: + entryPoint: web + +log: + level: DEBUG # Enable debug logs for troubleshooting diff --git a/users-api/Dockerfile b/users-api/Dockerfile new file mode 100644 index 00000000..69b28dba --- /dev/null +++ b/users-api/Dockerfile @@ -0,0 +1,13 @@ +# Build stage +FROM maven:3.8.4-openjdk-8 AS build-stage +WORKDIR /app +COPY pom.xml . +COPY src ./src +RUN mvn package -DskipTests + +# Run stage +FROM openjdk:8-jre-slim +WORKDIR /app +COPY --from=build-stage /app/target/users-api-0.0.1-SNAPSHOT.jar ./users-api.jar +EXPOSE 8083 +CMD ["java", "-jar", "users-api.jar"]