diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7a261164612449f9af8229b7be65929191b8d6e6
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,167 @@
+stages:
+  - build
+  - deploy
+
+docker_build:
+  stage: build
+  image: quay.io/podman/stable
+  only:
+    - master
+    - main
+  script:
+    - podman build --tag $CI_REGISTRY_IMAGE:latest --file $CI_PROJECT_DIR/MyPortfolio/Dockerfile $CI_PROJECT_DIR
+    - podman push --creds "${CI_REGISTRY_USER}:${CI_JOB_TOKEN}" $CI_REGISTRY_IMAGE:latest "docker://${CI_REGISTRY_IMAGE}"
+
+kube_deploy:
+  stage: deploy
+  image: bitnami/kubectl
+  environment:
+    name: production
+    url: http://${CI_PROJECT_PATH_SLUG}.kubernetes-public.it.liu.se/
+  only:
+    - master
+    - main
+  script:
+    - |
+      if [[ "$CI_DEPLOY_USER" == "" ]]
+      then
+        echo "Du har inte skapat ett deploy token i GitLab!"
+        exit 1
+      fi
+    - CONTEXT=${CI_PROJECT_PATH_SLUG%-*}
+    - |
+      # Ensures that the configuration still works in case we don't have access to a context
+      if kubectl config use-context ${CONTEXT}/infrastructure:${CONTEXT}
+      then
+        kubectl config set-context --current --namespace=${CI_PROJECT_PATH_SLUG}
+      fi
+    - CI_DEPLOY_AUTH=$(echo -n $CI_DEPLOY_USER:$CI_DEPLOY_PASSWORD | base64)
+    - |
+      # Deploy environment with kubectl apply
+      kubectl apply -f - <<EOF
+      apiVersion: v1
+      kind: Secret
+      metadata:
+        name: gitlab-docker-creds
+      type: kubernetes.io/dockerconfigjson
+      stringData:
+        .dockerconfigjson: |
+          {
+            "auths" : {
+              "${CI_REGISTRY}" : {
+                "username" : "${CI_DEPLOY_USER}",
+                "password" : "${CI_DEPLOY_PASSWORD}",
+                "auth" : "${CI_DEPLOY_AUTH}"
+              }
+            }
+          }
+      ---
+      apiVersion: apps/v1
+      kind: Deployment
+      metadata:
+        annotations:
+          se.liu.gitlab/commit: $CI_COMMIT_SHA
+          app.gitlab.com/app: $CI_PROJECT_PATH_SLUG
+          app.gitlab.com/env: $CI_ENVIRONMENT_SLUG
+        labels:
+          app: ${CI_PROJECT_PATH_SLUG}
+          environment: $CI_ENVIRONMENT_SLUG
+        name: ${CI_PROJECT_PATH_SLUG}
+      spec:
+        replicas: 1
+        revisionHistoryLimit: 1
+        selector:
+          matchLabels:
+            app: ${CI_PROJECT_PATH_SLUG}
+            environment: $CI_ENVIRONMENT_SLUG
+        template:
+          metadata:
+            annotations:
+              app.gitlab.com/app: $CI_PROJECT_PATH_SLUG
+              app.gitlab.com/env: $CI_ENVIRONMENT_SLUG
+            labels:
+              commit: $CI_COMMIT_SHA
+              app: ${CI_PROJECT_PATH_SLUG}
+              environment: $CI_ENVIRONMENT_SLUG
+          spec:
+            imagePullSecrets:
+            - name: gitlab-docker-creds
+            containers:
+            - env:
+              - name: http_proxy
+                value: http://squid-proxy.kube-system.svc:3128/
+              - name: https_proxy
+                value: http://squid-proxy.kube-system.svc:3128/
+              command: ["flask", "run", "-h", "0", "-p", "3000"]
+              image: $CI_REGISTRY_IMAGE:latest
+              imagePullPolicy: Always
+              name: ${CI_PROJECT_PATH_SLUG}
+              ports:
+              - containerPort: 3000
+                protocol: TCP
+              readinessProbe:
+                tcpSocket:
+                  port: 3000
+              resources:
+                limits:
+                  cpu: 100m
+                  memory: 80Mi
+                requests:
+                  cpu: 15m
+                  memory: 42Mi
+      ---
+      apiVersion: v1
+      kind: Service
+      metadata:
+        labels:
+          commit: $CI_COMMIT_SHA
+          app: ${CI_PROJECT_PATH_SLUG}
+          environment: $CI_ENVIRONMENT_SLUG
+        name: ${CI_PROJECT_PATH_SLUG}
+      spec:
+        ports:
+        - name: web
+          port: 80
+          protocol: TCP
+          targetPort: 3000
+        selector:
+          app: ${CI_PROJECT_PATH_SLUG}
+        type: ClusterIP
+      EOF
+    - |
+      [ "$CI_ENVIRONMENT_SLUG" == "production" ] && echo "Publicerar till https://$CI_PROJECT_PATH_SLUG.kubernetes-public.it.liu.se/"
+    - |
+      # Deploy production ingress only on the production environment
+
+      [ "$CI_ENVIRONMENT_SLUG" == "production" ] && kubectl apply -f - <<EOF || true
+      ---
+      apiVersion: networking.k8s.io/v1
+      kind: Ingress
+      metadata:
+        name: ${CI_PROJECT_PATH_SLUG}
+        annotations:
+          kubernetes.io/ingress.class: nginx-public
+          kubernetes.io/tls-acme: "true"
+          traefik.ingress.kubernetes.io/router.middlewares: traefik-https-redirect@kubernetescrd
+        labels:
+          app: ${CI_PROJECT_PATH_SLUG}
+          environment: $CI_ENVIRONMENT_SLUG
+      spec:
+        rules:
+        - host: ${CI_PROJECT_PATH_SLUG}.kubernetes-public.it.liu.se
+          http:
+            paths:
+            - backend:
+                service:
+                  name: ${CI_PROJECT_PATH_SLUG}
+                  port:
+                    number: 80
+              path: /
+              pathType: Prefix
+        tls:
+        - hosts:
+          - '*.kubernetes-public.it.liu.se'
+          secretName: portfolio-public-tls
+      EOF
+  variables:
+    GIT_STRATEGY: none