Skip to content
Closed
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
87 changes: 87 additions & 0 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Deploy to Server

on:
push:
branches:
- deploytest

permissions:
packages: write

jobs:
commit-hash:
runs-on: ubuntu-latest
outputs:
commit_hash: ${{ steps.get_commit.outputs.commit_hash }}
steps:
- uses: actions/checkout@v4
- name: Get commit hash
id: get_commit
run: echo "::set-output name=commit_hash::$(git rev-parse HEAD)"

build-and-test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.22.x'
- name: Install dependencies
run: go get .
- name: Build
run: go build -v ./...
- name: Test with the Go CLI
run: go test

build-and-push-image:
needs:
- build-and-test
- commit-hash
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Set short git commit SHA
id: vars
run: |
calculatedSha=$(git rev-parse --short ${{ github.sha }})
echo "COMMIT_SHORT_SHA=$calculatedSha" >> $GITHUB_ENV

- name: Log in to the Container registry
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
registry: https://ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push Docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: .
push: true
tags: ghcr.io/dreamsofcode-io/guestbook:${{ needs.commit-hash.outputs.commit_hash }}

deploy:
runs-on: ubuntu-latest
needs:
- build-and-push-image
- commit-hash

steps:
- name: Checkout code
uses: actions/checkout@v2
- name: create env file
run: |
echo "GIT_COMMIT_HASH=${{ github.sha }}" >> env
- name: 'Docker Stack Deploy'
uses: cssnr/stack-deploy-action@v1
with:
name: 'guestbook'
file: 'docker-stack.yaml'
host: zenful.cloud
user: deploytest
ssh_key: ${{ secrets.DEPLOY_SSH_KEY }}
env_file: './env'
39 changes: 22 additions & 17 deletions compose.prod.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
services:
watchtower:
image: containrrr/watchtower
command:
- "--label-enable"
- "--interval"
- "30"
- "--rolling-restart"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
reverse-proxy:
image: traefik:v3.1
command:
Expand All @@ -27,12 +18,27 @@ services:
- letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock
guestbook:
image: ghcr.io/dreamsofcode-io/guestbook:prod
image: ghcr.io/dreamsofcode-io/guestbook:${GIT_COMMIT_HASH:-prod}
labels:
- "traefik.enable=true"
- "traefik.http.routers.guestbook.rule=Host(`zenful.cloud`)"
- "traefik.http.middlewares.guestbook-ratelimit.ratelimit.average=20"
- "traefik.http.routers.guestbook.rule=Host(`zenful.cloud`) && !Method(`POST`)"
- "traefik.http.services.guestbook.loadbalancer.server.port=8080"
- "traefik.http.routers.guestbook.entrypoints=websecure"
- "traefik.http.routers.guestbook.tls.certresolver=myresolver"
- "traefik.http.routers.guestbook.middlewares=guestbook-ratelimit"
# Define separate router for POST methods
- "traefik.http.middlewares.guestbook-ratelimit-post.ratelimit.average=1"
- "traefik.http.middlewares.guestbook-ratelimit-post.ratelimit.period=1m"
- "traefik.http.routers.guestbook-post.rule=Host(`zenful.cloud`) && Method(`POST`)"
- "traefik.http.routers.guestbook-post.middlewares=guestbook-ratelimit-post"
- "traefik.http.routers.guestbook-post.entrypoints=websecure"
- "traefik.http.routers.guestbook-post.tls.certresolver=myresolver"
# Proxy
- "traefik.http.routers.proxy.rule=Host(`proxy.dreamsofcode.io`)"
- "traefik.http.routers.proxy.entrypoints=websecure"
- "traefik.http.routers.proxy.tls.certresolver=myresolver"
# Enable watchtower
- "com.centurylinklabs.watchtower.enable=true"
secrets:
- db-password
Expand All @@ -48,16 +54,15 @@ services:
replicas: 3
restart: always
depends_on:
db:
condition: service_healthy
- db
db:
image: postgres
image: postgres:16
restart: always
user: postgres
secrets:
- db-password
volumes:
- db-data:/var/lib/postgresql/data
secrets:
- db-password
environment:
- POSTGRES_DB=guestbook
- POSTGRES_PASSWORD_FILE=/run/secrets/db-password
Expand All @@ -73,4 +78,4 @@ volumes:
letsencrypt:
secrets:
db-password:
file: db/password.txt
external: true
87 changes: 87 additions & 0 deletions docker-stack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
services:
reverse-proxy:
image: traefik:v3.1
command:
- "--providers.docker"
- "--providers.docker.exposedbydefault=false"
- "--entryPoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
- "--certificatesresolvers.myresolver.acme.email=elliott@zenful.cloud"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
ports:
- mode: host
protocol: tcp
published: 80
target: 80
- mode: host
protocol: tcp
published: 443
target: 443
volumes:
- letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock
guestbook:
image: ghcr.io/dreamsofcode-io/guestbook:${GIT_COMMIT_HASH:-prod}
labels:
- "traefik.enable=true"
- "traefik.http.middlewares.guestbook-ratelimit.ratelimit.average=20"
- "traefik.http.routers.guestbook.rule=Host(`zenful.cloud`) && !Method(`POST`)"
- "traefik.http.services.guestbook.loadbalancer.server.port=8080"
- "traefik.http.routers.guestbook.entrypoints=websecure"
- "traefik.http.routers.guestbook.tls.certresolver=myresolver"
- "traefik.http.routers.guestbook.middlewares=guestbook-ratelimit"
# Define separate router for POST methods
- "traefik.http.middlewares.guestbook-ratelimit-post.ratelimit.average=1"
- "traefik.http.middlewares.guestbook-ratelimit-post.ratelimit.period=1m"
- "traefik.http.routers.guestbook-post.rule=Host(`zenful.cloud`) && Method(`POST`)"
- "traefik.http.routers.guestbook-post.middlewares=guestbook-ratelimit-post"
- "traefik.http.routers.guestbook-post.entrypoints=websecure"
- "traefik.http.routers.guestbook-post.tls.certresolver=myresolver"
# Proxy
- "traefik.http.routers.proxy.rule=Host(`proxy.dreamsofcode.io`)"
- "traefik.http.routers.proxy.entrypoints=websecure"
- "traefik.http.routers.proxy.tls.certresolver=myresolver"
# Enable watchtower
- "com.centurylinklabs.watchtower.enable=true"
secrets:
- db-password
environment:
- POSTGRES_HOST=db
- POSTGRES_PASSWORD_FILE=/run/secrets/db-password
- POSTGRES_USER=postgres
- POSTGRES_DB=guestbook
- POSTGRES_PORT=5432
- POSTGRES_SSLMODE=disable
deploy:
mode: replicated
replicas: 3
restart: always
depends_on:
- db
db:
image: postgres:16
restart: always
user: postgres
volumes:
- db-data:/var/lib/postgresql/data
secrets:
- db-password
environment:
- POSTGRES_DB=guestbook
- POSTGRES_PASSWORD_FILE=/run/secrets/db-password
expose:
- 5432
healthcheck:
test: [ "CMD", "pg_isready" ]
interval: 10s
timeout: 5s
retries: 5
volumes:
db-data:
letsencrypt:
secrets:
db-password:
external: true
Loading