Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#246] Prepare a base image for backend to speed up current process of building application for deployment #274

5 changes: 3 additions & 2 deletions govtool/backend/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
FROM haskell:9.2-buster
ARG BASE_IMAGE_TAG
FROM 733019650473.dkr.ecr.eu-west-1.amazonaws.com/backend-base:$BASE_IMAGE_TAG
WORKDIR /src
COPY . .
RUN cabal update && cabal configure && cabal build
RUN cabal build
RUN cp dist-newstyle/build/x86_64-linux/ghc-9.2.8/vva-be-0.1.0.0/x/vva-be/build/vva-be/vva-be /usr/local/bin
10 changes: 10 additions & 0 deletions govtool/backend/Dockerfile.base
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# NOTE: This Dockerfile sets up an environment with precompiled dependencies for
# the GovTool Haskell backend project, streamlining the project's compilation
# process by ensuring it only needs to compile against these dependencies. This
# is a common practice in Haskell projects, as it can significantly reduce the
# time it takes to build the project.

FROM haskell:9.2-buster
WORKDIR /src
COPY . .
RUN cabal update && cabal configure && cabal install --only-dependencies && rm -rf /src/*
10 changes: 10 additions & 0 deletions infra/terraform/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ module "govtool-ecr-backend" {
repo_name = "backend"
}

module "govtool-ecr-backend-base" {
source = "./modules/ecr"
repo_name = "backend-base"
}

module "govtool-ecr-frontend" {
source = "./modules/ecr"
repo_name = "frontend"
Expand All @@ -33,6 +38,7 @@ resource "aws_iam_policy" "cicd_ecr" {
Effect = "Allow"
Resource = [
module.govtool-ecr-backend.repo_arn,
module.govtool-ecr-backend-base.repo_arn,
module.govtool-ecr-frontend.repo_arn
]
},
Expand Down Expand Up @@ -91,6 +97,10 @@ output "govtool-ecr-backend-url" {
value = module.govtool-ecr-backend.repo_url
}

output "govtool-ecr-backend-base-url" {
value = module.govtool-ecr-backend-base.repo_url
}

output "govtool-ecr-frontend-url" {
value = module.govtool-ecr-frontend.repo_url
}
Expand Down
42 changes: 29 additions & 13 deletions scripts/govtool/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ docker_user := ubuntu
ssh_url := $(docker_user)@$(docker_host)
docker_compose_file := docker-compose.$(env).yml
compose_stack_name := govtool-$(env)-$(cardano_network)
base_backend_image_tag := $(shell git hash-object ../../govtool/backend/vva-be.cabal)

# helper function for checking undefined variables
check_defined = \
Expand Down Expand Up @@ -64,17 +65,32 @@ upload-config: prepare-config
rsync -av -e 'ssh -o StrictHostKeyChecking=no' config/target/. $(ssh_url):config

.PHONY: build-backend
build-backend:
build-backend: build-backend-base
@:$(call check_defined, cardano_network)
@:$(call check_defined, env)
$(docker) build --tag "$(repo_url)/backend:$(tag)" ../../govtool/backend
$(docker) build --build-arg BASE_IMAGE_TAG=$(base_backend_image_tag) --tag "$(repo_url)/backend:$(tag)" ../../govtool/backend

.PHONY: build-backend-base
build-backend-base:
@:$(call check_defined, cardano_network)
@:$(call check_defined, env)
docker manifest inspect "$(repo_url)/backend-base:$(base_backend_image_tag)" || \
$(docker) build --file ../../govtool/backend/Dockerfile.base --tag "$(repo_url)/backend-base:$(base_backend_image_tag)" ../../govtool/backend
@echo "Using backend-base image: $(repo_url)/backend-base:$(base_backend_image_tag)"

.PHONY: push-backend
push-backend:
push-backend: docker-login push-backend-base
@:$(call check_defined, cardano_network)
@:$(call check_defined, env)
$(docker) push $(repo_url)/backend:$(tag)

.PHONY: push-backend-base
push-backend-base: docker-login
@:$(call check_defined, cardano_network)
@:$(call check_defined, env)
docker manifest inspect "$(repo_url)/backend-base:$(base_backend_image_tag)" || \
$(docker) push $(repo_url)/backend-base:$(base_backend_image_tag)

.PHONY: build-frontend
build-frontend:
@:$(call check_defined, cardano_network)
Expand All @@ -90,13 +106,13 @@ build-frontend:
../../govtool/frontend

.PHONY: push-frontend
push-frontend:
push-frontend: docker-login
@:$(call check_defined, cardano_network)
@:$(call check_defined, env)
$(docker) push $(repo_url)/frontend:$(tag)

.PHONY: deploy-stack
deploy-stack:
deploy-stack: docker-login
@:$(call check_defined, cardano_network)
@:$(call check_defined, env)
@:$(call check_defined, grafana_admin_password)
Expand All @@ -106,8 +122,8 @@ deploy-stack:
export GRAFANA_ADMIN_PASSWORD=$(grafana_admin_password); \
export TAG=$(tag); \
ssh-keyscan $(docker_host) 2>/dev/null >> ~/.ssh/known_hosts; \
docker compose -f $(docker_compose_file) -p $(compose_stack_name) pull; \
docker compose -f $(docker_compose_file) -p $(compose_stack_name) up -d
$(docker) compose -f $(docker_compose_file) -p $(compose_stack_name) pull; \
$(docker) compose -f $(docker_compose_file) -p $(compose_stack_name) up -d

.PHONY: destroy-cardano-node-and-dbsync
destroy-cardano-node-and-dbsync:
Expand All @@ -120,9 +136,9 @@ destroy-cardano-node-and-dbsync:
ssh-keyscan $(docker_host) 2>/dev/null >> ~/.ssh/known_hosts; \
containers="$$(docker container ls --no-trunc --format '{{.Names}}' -f name=cardano-node -f name=cardano-db-sync -f name=postgres)"; \
volumes="$$(docker volume ls --format '{{.Name}}' -f name=db-sync-data -f name=node-db -f name=node-ipc -f name=postgres)"; \
docker container stop $${containers}; \
docker container rm $${containers}; \
docker volume rm $${volumes}
$(docker) container stop $${containers}; \
$(docker) container rm $${containers}; \
$(docker) volume rm $${volumes}

.PHONY: toggle-maintenance
toggle-maintenance:
Expand All @@ -134,8 +150,8 @@ toggle-maintenance:
export DOCKER_HOST=ssh://$(ssh_url); \
export TAG=$(tag); \
ssh-keyscan $(docker_host) 2>/dev/null >> ~/.ssh/known_hosts; \
if [[ "$(maintenance)" = "enable" ]]; then docker compose -f $(docker_compose_file) -p $(compose_stack_name) exec frontend touch /var/run/maintenance_enabled; \
else docker compose -f $(docker_compose_file) -p $(compose_stack_name) exec frontend rm /var/run/maintenance_enabled; fi
if [[ "$(maintenance)" = "enable" ]]; then $(docker) compose -f $(docker_compose_file) -p $(compose_stack_name) exec frontend touch /var/run/maintenance_enabled; \
else $(docker) compose -f $(docker_compose_file) -p $(compose_stack_name) exec frontend rm /var/run/maintenance_enabled; fi

.DEFAULT_GOAL := info
.PHONY: info
Expand Down Expand Up @@ -178,4 +194,4 @@ docker:
export GRAFANA_ADMIN_PASSWORD=$(grafana_admin_password); \
export TAG=$(tag); \
ssh-keyscan $(docker_host) 2>/dev/null >> ~/.ssh/known_hosts; \
docker compose -f $(docker_compose_file) -p $(compose_stack_name) $(cmd)
$(docker) compose -f $(docker_compose_file) -p $(compose_stack_name) $(cmd)