Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
FROM node:lts-alpine
FROM node:lts-alpine AS builder

WORKDIR /app

COPY package*.json .
COPY pnpm-lock.yaml .

RUN npm install

COPY . .

# Generate the Prisma client and types
RUN npx prisma generate

RUN npm run build

FROM node:lts-alpine AS runner

WORKDIR /app

# Copy package.json and node_modules (includes @prisma/client)
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/pnpm-lock.yaml ./
COPY --from=builder /app/node_modules ./node_modules

# Copy built app files (dist folder)
COPY --from=builder /app/dist ./dist

EXPOSE 8393

CMD ["npm", "run", "start:prod"]
33 changes: 16 additions & 17 deletions terraform/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

90 changes: 67 additions & 23 deletions terraform/main.tf
Original file line number Diff line number Diff line change
@@ -1,39 +1,83 @@
terraform {
required_providers {
docker = {
source = "kreuzwerker/docker"
version = "~> 3.0"
azurerm = {
source = "hashicorp/azurerm"
version = "~> 4.31.0"
}
}
}

provider "docker" {}
provider "azurerm" {
features {}
subscription_id = var.subscription_id
}

resource "docker_image" "app_image" {
name = var.image_name
keep_locally = true
resource "azurerm_resource_group" "rg" {
name = "${var.app_name}-rg"
location = var.location
}

resource "docker_container" "app_container" {
name = var.container_name
image = docker_image.app_image.image_id
restart = "unless-stopped"
resource "azurerm_log_analytics_workspace" "log" {
name = "${var.app_name}-log"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
retention_in_days = 30
}

dynamic "ports" {
for_each = var.ports
content {
internal = ports.value.internal
external = ports.value.external
}
resource "azurerm_container_app_environment" "env" {
name = "${var.app_name}-env"
location = azurerm_resource_group.rg.location
resource_group_name = azurerm_resource_group.rg.name
log_analytics_workspace_id = azurerm_log_analytics_workspace.log.id
}

resource "azurerm_container_app" "app" {
name = "${var.app_name}-app"
resource_group_name = azurerm_resource_group.rg.name
container_app_environment_id = azurerm_container_app_environment.env.id
revision_mode = "Single"

registry {
server = "ghcr.io"
username = var.registry_username
password_secret_name = "ghcr-pat"
}

env = var.env_vars
secret {
name = "ghcr-pat"
value = var.registry_password_secret
}

template {
container {
name = var.container_name
image = var.image_name
cpu = 1.0
memory = "2.0Gi"

dynamic "env" {
for_each = var.env_vars
content {
name = env.value["name"]
value = env.value["value"]
}
}

# Override the PORT environment variable to ensure the app listens on port 80
env {
name = "PORT"
value = "80"
}
}
}

dynamic "volumes" {
for_each = var.volumes
content {
host_path = volumes.value.host_path
container_path = volumes.value.container_path
ingress {
allow_insecure_connections = false
external_enabled = true
target_port = 80
traffic_weight {
percentage = 100
latest_revision = true
}
}
}
3 changes: 3 additions & 0 deletions terraform/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "azurerm_container_app_url" {
value = azurerm_container_app.app.latest_revision_fqdn
}
49 changes: 31 additions & 18 deletions terraform/variables.tf
Original file line number Diff line number Diff line change
@@ -1,33 +1,46 @@
variable "image_name" {
description = "Docker image name with tag"
variable "subscription_id" {
description = "Azure subscription ID"
type = string
}

variable "app_name" {
description = "Name of the application"
type = string
}

variable "location" {
description = "Azure region for the resources"
type = string
default = "Italy North"
}

variable "registry_username" {
description = "Username for the container registry"
type = string
}

variable "registry_password_secret" {
description = "Secret for the container registry password"
type = string
sensitive = true
}

variable "container_name" {
description = "Docker container name"
description = "Server's docker container name"
type = string
default = "server"
}

variable "ports" {
description = "List of ports to expose"
type = list(object({
internal = number
external = number
}))
default = []
variable "image_name" {
description = "Docker image name with tag"
type = string
}

variable "env_vars" {
description = "Environment variables"
type = list(string)
default = []
}

variable "volumes" {
description = "Volumes to mount"
type = list(object({
host_path = string
container_path = string
name = string
value = string
}))
default = []
}
Loading