diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..d7a63892b --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,102 @@ +name: main workflow + +on: + push: + branches: + - main + - staging + - development + pull_request: + branches: + - main + - staging + - development + +env: + GIT_COMMIT: ${{ github.sha }} + KUBECONFIG: ${{ github.workspace }}/kubeconfig + +jobs: + Build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.21.12' + + - name: Build backend + run: | + cd backend + go build . + + - name: Build frontend + run: | + cd frontend + go build . + + - name: Test frontend + run: | + cd frontend + go test ./... + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push Docker images + run: | + docker build -t ghcr.io/albla20/backend:latest backend + docker push ghcr.io/albla20/backend:latest + + docker build -t ghcr.io/albla20/frontend:latest frontend + docker push ghcr.io/albla20/frontend:latest + + - name: Pull docker images + run: | + docker pull ghcr.io/albla20/backend:latest + docker pull ghcr.io/albla20/frontend:latest + + + - name: Set up kubeconfig + run: | + echo "${{ secrets.KUBECONFIG }}" | base64 -d > kubeconfig + export KUBECONFIG=$PWD/kubeconfig + + - name: Select environment + id: env + run: | + if [[ "${GITHUB_REF##*/}" == "main" ]]; then + echo "ENV=production" >> $GITHUB_ENV + elif [[ "${GITHUB_REF##*/}" == "staging" ]]; then + echo "ENV=staging" >> $GITHUB_ENV + else + echo "ENV=development" >> $GITHUB_ENV + fi + echo "Deploying to $ENV environment" + + - name: Deploy to Kubernetes + run: | + MANIFEST_DIR="k8s/${ENV}" + if [ -d "$MANIFEST_DIR" ]; then + echo "Applying manifests in $MANIFEST_DIR" + kubectl apply -f "$MANIFEST_DIR" + kubectl rollout status deployment/backend -n $ENV || true + kubectl rollout status deployment/frontend -n $ENV || true + else + echo "No manifests found for $ENV, skipping deployment." + fi + + + + + + diff --git a/Manifests/backend-pod.yaml b/Manifests/backend-pod.yaml new file mode 100644 index 000000000..e8fc93925 --- /dev/null +++ b/Manifests/backend-pod.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: backend +spec: + containers: + - name: backend + image: mathiasoverby/backend:latest + ports: + - containerPort: 9000 diff --git a/Manifests/frontend-pod.yaml b/Manifests/frontend-pod.yaml new file mode 100644 index 000000000..f4453a6fd --- /dev/null +++ b/Manifests/frontend-pod.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Pod +metadata: + name: frontend +spec: + containers: + - name: frontend + image: mathiasoverby/frontend:latest + ports: + - containerPort: 8080 diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 000000000..1e027a454 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,8 @@ +# Build stage +FROM golang:1.21 +WORKDIR /app +COPY . . +RUN go mod download +RUN go build -o backend . +EXPOSE 9000 +CMD ["./backend", "run", "go"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..879d45717 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ +services: + redis: + image: redis:7-alpine + restart: always + volumes: + - redis_data:/data + + backend: + image: ghcr.io/albla20/backend:latest + environment: + - REDIS_DNS=redis + ports: + - "9000:9000" # for host access (not needed for containers to talk) + # IMPORTANT: backend must listen on 0.0.0.0:9000 inside the container + + frontend: + image: ghcr.io/albla20/frontend:latest + environment: + - BACKEND_DNS=backend + - BACKEND_PORT=9000 + ports: + - "8080:8080" + depends_on: + - backend + +volumes: + redis_data: diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 000000000..50258b790 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,6 @@ +FROM golang:1.21 +WORKDIR /app +COPY . . +RUN go build -o frontend . +EXPOSE 8080 +CMD ["/app/frontend"] diff --git a/frontend/main.go b/frontend/main.go index bede472b4..27f4da2a4 100644 --- a/frontend/main.go +++ b/frontend/main.go @@ -101,5 +101,5 @@ func main() { http.Handle("/", http.FileServer(http.Dir("./static"))) err := http.ListenAndServe(":8080", nil) - fmt.Println("%v", err) + fmt.Printf("%v", err) } diff --git a/test_app.sh b/test_app.sh new file mode 100644 index 000000000..ed57f0373 --- /dev/null +++ b/test_app.sh @@ -0,0 +1,16 @@ +set -e + +URL=${1:-http://localhost:8080} + +echo "🚀 Waiting for service to be up at $URL..." +for i in {1..15}; do + if curl -s --head "$URL" | grep "200 OK" > /dev/null; then + echo "✅ Service is reachable!" + exit 0 + fi + echo "⏳ Attempt $i: Service not ready yet..." + sleep 2 +done + +echo "❌ Service did not respond in time" +exit 1