Skip to content

Commit

Permalink
chore: dockerize app
Browse files Browse the repository at this point in the history
  • Loading branch information
christyjacob4 committed Sep 26, 2023
1 parent 830925b commit 834bbb5
Show file tree
Hide file tree
Showing 7 changed files with 303 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
.git
.gitignore
*.md
dist
Empty file.
78 changes: 78 additions & 0 deletions .github/workflows/staging.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: Staging deployment

on:
push:
branches:
- dev
- main

env:
REGISTRY: ghcr.io
IMAGE_NAME: appwrite/homepage
TAG: ${{ github.sha }}
STACK_FILE: docker-stack.yml
NAMESPACE: homepage
REPOSITORY: homepage

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout the repo
uses: actions/checkout@v2

- name: Login to DockerHub
uses: docker/login-action@v1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v2
with:
build-args: |
VERSION=${{ env.TAG }}
context: .
push: true
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.TAG }}

deploy:
needs: build
runs-on: ubuntu-latest
steps:
- name: Execute SSH commands
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.STG_SSH_HOST }}
username: ${{ secrets.STG_SSH_USERNAME }}
key: ${{ secrets.STG_SSH_KEY }}
script: |
url="https://${{ github.actor }}:${{ secrets.GITHUB_TOKEN }}@github.com/appwrite/${{ env.REPOSITORY }}.git"
if ! git clone "${url}" "${{ env.REPOSITORY }}" 2>/dev/null && [ -d "${{ env.REPOSITORY }}" ] ; then
echo "Clone failed because the folder ${{ env.REPOSITORY }} exists"
fi
cd ${{ env.REPOSITORY }}
git reset --hard HEAD
git remote set-url origin $url
git fetch origin
git checkout ${{ env.TAG }}
rm -f .env
echo "_APP_ENV=${{ secrets.STG_APP_ENV }}" >> .env
echo "_APP_VERSION=${{ env.TAG }}" >> .env
echo "_APP_DOMAIN=${{ secrets.STG_APP_DOMAIN }}" >> .env
echo "_APP_MAILGUN_DOMAIN=${{ secrets._APP_MAILGUN_DOMAIN }}" >> .env
echo "_APP_MAILGUN_KEY=${{ secrets._APP_MAILGUN_KEY }}" >> .env
echo "_APP_SMTP_PASSWORD=${{ secrets._APP_SMTP_PASSWORD }}" >> .env
echo "_APP_SMTP_USERNAME=${{ secrets._APP_SMTP_USERNAME }}" >> .env
echo "_APP_SYSTEM_SECURITY_EMAIL_ADDRESS=${{ secrets._APP_SYSTEM_SECURITY_EMAIL_ADDRESS }}" >> .env
echo "_APP_HOMERUN_API_KEY=${{ secrets._APP_HOMERUN_API_KEY }}" >> .env
echo "_APP_LOGGING_PROVIDER=${{ secrets._APP_LOGGING_PROVIDER }}" >> .env
echo "_APP_LOGGING_CONFIG=${{ secrets._APP_LOGGING_CONFIG }}" >> .env
echo "SEMATEXT_TOKEN=${{ secrets.SEMATEXT_TOKEN }}" >> .env
echo ${{ secrets.GH_REGISTRY_TOKEN }} | docker login ghcr.io --username ${{ github.actor }} --password-stdin
docker-compose -f ${{ env.STACK_FILE }} config
docker stack deploy --with-registry-auth -c <(docker-compose -f ${{ env.STACK_FILE }} config) ${{ env.NAMESPACE }}
11 changes: 11 additions & 0 deletions .gitpod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# This configuration file was automatically generated by Gitpod.
# Please adjust to your needs (see https://www.gitpod.io/docs/introduction/learn-gitpod/gitpod-yaml)
# and commit this file to your remote git repository to share the goodness with others.

# Learn more from ready-to-use templates: https://www.gitpod.io/docs/introduction/getting-started/quickstart

tasks:
- init: pnpm install && pnpm run build
command: pnpm run dev


30 changes: 30 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM node:20-slim AS build

ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"

RUN corepack enable
COPY . /app

WORKDIR /app

# RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
# RUN pnpm run build

FROM base AS prod-deps
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile

FROM base AS build
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
RUN pnpm run build

FROM base
COPY --from=prod-deps /app/node_modules /app/node_modules
COPY --from=build /app/dist /app/dist

# FROM caddy:alpine as serve
# COPY --from=build /app/dist /app/dist

# EXPOSE 80

# CMD [ "caddy", "file-server", "--root /app/dist"]
54 changes: 54 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
version: '3.8'

services:
traefik:
image: traefik:2.9
command:
- --log.level=DEBUG
- --api.insecure=true
- --providers.docker=true
- --providers.docker.watch=true
- --providers.docker.swarmMode=true
- --providers.docker.exposedByDefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --providers.docker.constraints=Label(`traefik.constraint-label-stack`,`appwrite`)
- --certificatesresolvers.myresolver.acme.httpchallenge=true
- --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
- --certificatesresolvers.myresolver.acme.email=$_APP_SYSTEM_SECURITY_EMAIL_ADDRESS
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/${_APP_DOMAIN}.json
- --accesslog=true
ports:
- 80:80
- 8080:8080
volumes:
- /letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock
networks:
- homepage

appwrite:
image: homepage-dev
build:
context: .
networks:
- homepage
labels:
- traefik.enable=true
- traefik.constraint-label-stack=appwrite
- traefik.http.services.appwrite_api.loadbalancer.server.port=80
#http
- traefik.http.routers.appwrite.entrypoints=web
- traefik.http.routers.appwrite.rule=Host(`$_APP_DOMAIN`) || Host(`www.$_APP_DOMAIN`)
- traefik.http.routers.appwrite.service=appwrite_api
# https
- traefik.http.routers.appwrite_secure.entrypoints=websecure
- traefik.http.routers.appwrite_secure.rule=Host(`$_APP_DOMAIN`) || Host(`www.$_APP_DOMAIN`)
- traefik.http.routers.appwrite_secure.service=appwrite_api
- traefik.http.routers.appwrite_secure.tls=true
- traefik.http.routers.appwrite_secure.tls.certresolver=myresolver

networks:
homepage:
125 changes: 125 additions & 0 deletions docker/docker-stack.stage.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
x-logging: &x-logging
logging:
driver: 'json-file'
options:
max-file: '5'
max-size: '20m'

x-update-config: &x-update-config
update_config:
order: start-first
failure_action: rollback
parallelism: 2
delay: 5s
rollback_config:
failure_action: pause
monitor: 5s
parallelism: 2
order: start-first

version: '3.8'

services:
traefik:
image: traefik:2.9
<<: *x-logging
command:
- --log.level=DEBUG
- --api.insecure=true
- --providers.docker=true
- --providers.docker.watch=true
- --providers.docker.swarmMode=true
- --providers.docker.exposedByDefault=false
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --entrypoints.web.http.redirections.entrypoint.to=websecure
- --entrypoints.web.http.redirections.entrypoint.scheme=https
- --providers.docker.constraints=Label(`traefik.constraint-label-stack`,`appwrite`)
- --certificatesresolvers.myresolver.acme.httpchallenge=true
- --certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web
- --certificatesresolvers.myresolver.acme.email=$_APP_SYSTEM_SECURITY_EMAIL_ADDRESS
- --certificatesresolvers.myresolver.acme.storage=/letsencrypt/${_APP_DOMAIN}.json
- --accesslog=true
ports:
- 80:80
- 443:443
- 8080:8080
volumes:
- /letsencrypt:/letsencrypt
- /var/run/docker.sock:/var/run/docker.sock
networks:
- cloud
deploy:
replicas: 1
<<: *x-update-config
placement:
max_replicas_per_node: 1
constraints:
- node.role == manager

appwrite:
image: ghcr.io/appwrite/homepage:$_APP_VERSION
<<: *x-logging
networks:
- cloud
deploy:
<<: *x-update-config
mode: global
placement:
constraints:
- node.role == worker
labels:
- traefik.enable=true
- traefik.constraint-label-stack=appwrite
- traefik.http.services.appwrite_api.loadbalancer.server.port=80
#http
- traefik.http.routers.appwrite.entrypoints=web
- traefik.http.routers.appwrite.rule=Host(`$_APP_DOMAIN`) || Host(`www.$_APP_DOMAIN`)
- traefik.http.routers.appwrite.service=appwrite_api
# https
- traefik.http.routers.appwrite_secure.entrypoints=websecure
- traefik.http.routers.appwrite_secure.rule=Host(`$_APP_DOMAIN`) || Host(`www.$_APP_DOMAIN`)
- traefik.http.routers.appwrite_secure.service=appwrite_api
- traefik.http.routers.appwrite_secure.tls=true
- traefik.http.routers.appwrite_secure.tls.certresolver=myresolver
environment:
_APP_SMTP_PORT: 587
_APP_SMTP_SECURE: tls
_APP_SMTP_HOST: smtp.mailgun.org
_APP_ENV:
_APP_MAILGUN_DOMAIN:
_APP_MAILGUN_KEY:
_APP_SMTP_PASSWORD:
_APP_SMTP_USERNAME:
_APP_HOMERUN_API_KEY:
_APP_LOGGING_PROVIDER:
_APP_LOGGING_CONFIG:

janitor:
image: appwrite/docker-janitor
deploy:
mode: global
volumes:
- /var/run/docker.sock:/var/run/docker.sock

sematext-agent:
image: sematext/agent:latest
environment:
REGION: EU
INFRA_TOKEN: $SEMATEXT_TOKEN
deploy:
mode: global
restart_policy:
condition: any
volumes:
- /:/hostfs:ro
- /etc/passwd:/etc/passwd:ro
- /etc/group:/etc/group:ro
- /sys:/host/sys:ro
- /dev:/hostfs/dev:ro
- /var/run:/var/run
- /sys/kernel/debug:/sys/kernel/debug

networks:
cloud:
driver: overlay

0 comments on commit 834bbb5

Please sign in to comment.