Skip to content

Commit ee25c55

Browse files
Merge pull request #4 from CogitoNTNU/deployment
Deployment
2 parents 1ac4a3e + 1a7f72e commit ee25c55

File tree

7 files changed

+187
-17
lines changed

7 files changed

+187
-17
lines changed

.github/workflows/cd.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: CD Pipeline
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
7+
jobs:
8+
deploy:
9+
runs-on:
10+
group: OpenStack
11+
labels: self-hosted
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Login to GitHub Container Registry
16+
uses: docker/login-action@v2
17+
with:
18+
registry: ghcr.io
19+
username: cogitontnu
20+
password: ${{ secrets.GITHUB_TOKEN }}
21+
22+
- name: Build Image and push to GitHub Container Registry
23+
uses: docker/build-push-action@v4
24+
with:
25+
context: .
26+
push: true
27+
tags: ghcr.io/cogitontnu/cogi-go:latest

Dockerfile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# Build stage
2+
FROM golang:1.24-alpine AS builder
3+
4+
WORKDIR /app
5+
6+
# Copy go mod files
7+
COPY go.mod go.sum ./
8+
9+
# Download dependencies
10+
RUN go mod download
11+
12+
# Copy source code
13+
COPY . .
14+
15+
# Build the application
16+
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main ./cmd/main.go
17+
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o migrations ./cmd/migrations/main.go
18+
19+
# Final stage
20+
FROM alpine:latest
21+
22+
RUN apk --no-cache add ca-certificates
23+
24+
WORKDIR /root/
25+
26+
# Copy the binaries from builder
27+
COPY --from=builder /app/main .
28+
COPY --from=builder /app/migrations .
29+
30+
# Copy migration files
31+
COPY --from=builder /app/internal/repository/db/migrations ./internal/repository/db/migrations
32+
33+
# Copy misc files (for fonts used in the application)
34+
COPY --from=builder /app/misc ./misc
35+
36+
# Expose port 8080
37+
EXPOSE 8080
38+
39+
# Copy entrypoint script and use it
40+
COPY entrypoints.sh /usr/local/bin/entrypoints.sh
41+
RUN chmod +x /usr/local/bin/entrypoints.sh
42+
43+
ENTRYPOINT ["/usr/local/bin/entrypoints.sh"]
44+
CMD ["./main"]

docker-compose.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
services:
22
cogigo_db:
33
container_name: cogigo_db
4-
image: postgres:latest
4+
image: postgres:18.1
55
environment:
66
POSTGRES_USER: postgres
77
POSTGRES_PASSWORD: postgres
@@ -11,10 +11,10 @@ services:
1111
interval: 5s
1212
timeout: 3s
1313
retries: 20
14+
volumes:
15+
- 'cogigo_data:/var/lib/postgresql/18/docker'
1416
ports:
1517
- "5432:5432"
16-
volumes:
17-
- 'cogigo_data:/var/lib/postgresql/data'
1818

1919
volumes:
2020
cogigo_data: {}

entrypoints.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/sh
2+
set -e
3+
4+
echo "Running migrations..."
5+
./migrations
6+
7+
echo "Starting application..."
8+
exec "$@"

internal/repository/db/db.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"database/sql"
66
"errors"
77
"fmt"
8+
"strconv"
89

910
"github.com/CogitoNTNU/cogi-go/internal/config"
1011
"github.com/CogitoNTNU/cogi-go/internal/util/env"
@@ -19,7 +20,13 @@ func InitDb(e *env.EnvConfig, logger *logrus.Entry, ctx context.Context) (db *sq
1920
cfg := config.NewLocalDbConfig(config.WithDbHost("localhost"), config.WithDbPort(5432), config.WithDbUser("postgres"), config.WithDbPassword("postgres"), config.WithDbName("postgres"))
2021
db, err = connectDb(ctx, logger, cfg)
2122
case env.PROD:
22-
// TODO: implement PROD DB
23+
host := e.Read("SQL_HOST")
24+
port, _ := strconv.Atoi(e.Read("SQL_PORT"))
25+
user := e.Read("SQL_USER")
26+
password := e.Read("SQL_PASSWORD")
27+
dbname := e.Read("SQL_DATABASE")
28+
cfg := config.NewLocalDbConfig(config.WithDbHost(host), config.WithDbPort(port), config.WithDbUser(user), config.WithDbPassword(password), config.WithDbName(dbname))
29+
db, err = connectDb(ctx, logger, cfg)
2330
default:
2431
return nil, errors.New("unknown environment mode")
2532
}

internal/util/env/env.go

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import "github.com/sirupsen/logrus"
44

55
import (
66
"github.com/spf13/viper"
7+
"os"
78
)
8-
99
var (
1010
PROD string = "PRODUCTION"
1111
DEV string = "DEVELOPMENT"
@@ -17,23 +17,31 @@ type EnvConfig struct {
1717
}
1818

1919
func Configure(path string) *EnvConfig {
20-
return &EnvConfig{env_path: path}
20+
return &EnvConfig{
21+
env_path: path,
22+
logger: logrus.New(),
23+
}
2124
}
2225

2326
func (p *EnvConfig) Read(key string) (value string) {
24-
logger := p.logger
25-
viper.SetConfigFile(p.env_path)
26-
err := viper.ReadInConfig()
27+
logger := p.logger
28+
29+
if value := os.Getenv(key); value != "" {
30+
return value
31+
}
32+
33+
viper.SetConfigFile(p.env_path)
34+
err := viper.ReadInConfig()
2735

28-
if err != nil {
29-
logger.WithError(err).Fatal("Couldn't intialize and find environmental variable.")
30-
}
36+
if err != nil {
37+
logger.WithError(err).Fatal("Couldn't intialize and find environmental variable.")
38+
}
3139

32-
value, ok := viper.Get(key).(string)
40+
value, ok := viper.Get(key).(string)
3341

34-
if !ok {
35-
logger.Fatal("Invalid type assertion on value from env.")
36-
}
42+
if !ok {
43+
logger.Fatal("Invalid type assertion on value from env.")
44+
}
3745

38-
return
46+
return value
3947
}

prod-docker-compose.yml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
services:
2+
cogigo_db:
3+
container_name: cogigo_db
4+
image: postgres:18.1
5+
environment:
6+
POSTGRES_USER: postgres
7+
POSTGRES_PASSWORD: postgres
8+
POSTGRES_DB: postgres
9+
healthcheck:
10+
test: [ "CMD-SHELL", "pg_isready -U postgres -d postgres" ]
11+
interval: 5s
12+
timeout: 3s
13+
retries: 20
14+
volumes:
15+
- 'cogigo_data:/var/lib/postgresql/18/docker'
16+
networks:
17+
- proxy
18+
adminer:
19+
container_name: adminer
20+
image: adminer:latest
21+
networks:
22+
- proxy
23+
restart: unless-stopped
24+
environment:
25+
ADMINER_DEFAULT_SERVER: postgres
26+
labels:
27+
- "traefik.enable=true"
28+
- "traefik.http.routers.adminer.entrypoints=http"
29+
- "traefik.http.routers.adminer.rule=Host(`adminer.cogito-ntnu.no`)"
30+
- "traefik.http.routers.adminer.service=adminer"
31+
- "traefik.http.middlewares.adminer-https-redirect.redirectscheme.scheme=https"
32+
- "traefik.http.routers.adminer.middlewares=adminer-https-redirect"
33+
- "traefik.http.routers.adminer-secure.entrypoints=https"
34+
- "traefik.http.routers.adminer-secure.rule=Host(`adminer.cogito-ntnu.no`)"
35+
- "traefik.http.routers.adminer-secure.tls=true"
36+
- "traefik.http.routers.adminer-secure.tls.certresolver=cloudflare"
37+
- "traefik.http.routers.adminer-secure.service=adminer"
38+
- "traefik.http.services.adminer.loadbalancer.server.port=8080"
39+
40+
cogito_backend:
41+
container_name: cogito_backend
42+
image: ghcr.io/cogitontnu/cogi-go:latest
43+
entrypoint: ["/bin/sh","-lc"]
44+
command: "./main"
45+
environment:
46+
ENVIRONMENT: "PRODUCTION"
47+
SQL_HOST: cogigo_db
48+
SQL_PORT: 5432
49+
SQL_USER: postgres
50+
SQL_PASSWORD: postgres
51+
SQL_DATABASE: postgres
52+
networks:
53+
- proxy
54+
labels:
55+
- "traefik.enable=true"
56+
- "traefik.http.routers.backend.entrypoints=http"
57+
- "traefik.http.routers.backend.rule=Host(`backend.cogito-ntnu.no`)"
58+
- "traefik.http.routers.backend.service=cogito"
59+
- "traefik.http.middlewares.backend-https-redirect.redirectscheme.scheme=https"
60+
- "traefik.http.routers.backend.middlewares=backend-https-redirect"
61+
- "traefik.http.routers.backend-secure.entrypoints=https"
62+
- "traefik.http.routers.backend-secure.rule=Host(`backend.cogito-ntnu.no`)"
63+
- "traefik.http.routers.backend-secure.tls=true"
64+
- "traefik.http.routers.backend-secure.tls.certresolver=cloudflare"
65+
- "traefik.http.routers.backend-secure.service=cogito"
66+
- "traefik.http.services.cogito.loadbalancer.server.port=8080"
67+
depends_on:
68+
cogigo_db:
69+
condition: service_healthy
70+
71+
volumes:
72+
cogigo_data: {}
73+
74+
networks:
75+
proxy:
76+
external: true

0 commit comments

Comments
 (0)