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

feature: deploy containers #87

Merged
merged 1 commit into from
Oct 26, 2023
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
85 changes: 17 additions & 68 deletions .github/workflows/deploy-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,21 @@ jobs:
- name: 'Check out repository'
uses: actions/checkout@v3

- name: 'Set up JDK'
uses: actions/setup-java@v3
- name: Log in to Docker Hub
uses: docker/login-action@v3.0.0
with:
java-version: '17'
distribution: 'temurin'
cache: 'gradle'
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: 'Grant execute permission for gradlew'
run: chmod +x gradlew

- name: 'Build and Generate JAR'
run: ./gradlew deploy --no-daemon -P version=${{github.ref_name}}
- name: Build and push Docker image
uses: docker/[email protected]
with:
context: .
file: ./Dockerfile
build-args: |
APP_VERSION=${{github.ref_name}}
push: ${{ github.event_name != 'pull_request' }}
tags: eduardoferro/capivara:${{ github.sha }},${{ github.event_name == 'release' && format('eduardoferro/capivara:latest,eduardoferro/capivara:{0}', github.ref_name) || '' }}

- name: 'Wait for SSH'
run: |
Expand All @@ -46,70 +49,16 @@ jobs:
env:
INSTANCE_IP: ${{ secrets.INSTANCE_IP }}

- name: 'Stop and Delete Previous App'
uses: appleboy/[email protected]
continue-on-error: true
with:
host: ${{ secrets.INSTANCE_IP }}
username: ${{ secrets.SSH_USERNAME }}
passphrase: ${{ secrets.VM_SSH_PRIVATE_KEY_PASSPHRASE }}
key: ${{ secrets.VM_SSH_PRIVATE_KEY }}
script: |
pkill -f 'java .* -jar .*CapivaraBot.*\.jar'
rm -rf /home/${{ secrets.SSH_USERNAME }}/capivara/CapivaraBot.jar

- name: 'Push Repo'
- name: 'Push start-container.sh'
uses: appleboy/[email protected]
with:
host: ${{ secrets.INSTANCE_IP }}
username: ${{ secrets.SSH_USERNAME }}
passphrase: ${{ secrets.VM_SSH_PRIVATE_KEY_PASSPHRASE }}
key: ${{ secrets.VM_SSH_PRIVATE_KEY }}
source: "./build/libs/CapivaraBot.jar"
source: "./start-container.sh"
target: /home/${{ secrets.SSH_USERNAME }}/capivara/
strip_components: 3

- name: 'Create main.properties'
uses: appleboy/[email protected]
with:
host: ${{ secrets.INSTANCE_IP }}
username: ${{ secrets.SSH_USERNAME }}
passphrase: ${{ secrets.VM_SSH_PRIVATE_KEY_PASSPHRASE }}
key: ${{ secrets.VM_SSH_PRIVATE_KEY }}
script: |
cd /home/${{ secrets.SSH_USERNAME }}/capivara

echo 'spring.datasource.url=jdbc:postgresql://localhost:5432/capivara' > main.properties
echo 'spring.datasource.driverClassName=org.postgresql.Driver' >> main.properties
echo 'spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL95Dialect' >> main.properties
echo 'spring.datasource.username=${{ secrets.DATABASE_USERNAME }}' >> main.properties
echo 'spring.datasource.password=${{ secrets.DATABASE_PASSWORD }}' >> main.properties
echo 'hibernate.hbm2ddl.auto=update' >> main.properties
echo 'token=${{ secrets.DISCORD_BOT_TOKEN }}' >> main.properties
echo 'log.channel.id=${{ secrets.DISCORD_LOG_CHANNEL_ID }}' >> main.properties
echo 'log.directory=/home/${{ secrets.SSH_USERNAME }}/capivara/logs/' >> main.properties

- name: 'Create start.sh'
uses: appleboy/[email protected]
with:
host: ${{ secrets.INSTANCE_IP }}
username: ${{ secrets.SSH_USERNAME }}
passphrase: ${{ secrets.VM_SSH_PRIVATE_KEY_PASSPHRASE }}
key: ${{ secrets.VM_SSH_PRIVATE_KEY }}
script: |
cd /home/${{ secrets.SSH_USERNAME }}/capivara

echo '#!/bin/bash' > start.sh
echo 'source "/home/${{ secrets.SSH_USERNAME }}/.sdkman/bin/sdkman-init.sh"' >> start.sh

echo 'DIRECTORY=/home/${{ secrets.SSH_USERNAME }}/capivara' >> start.sh
echo 'FILENAME=CapivaraBot.jar' >> start.sh
echo 'FULLPATH=${DIRECTORY}/${FILENAME}' >> start.sh
echo 'JAVA_ARGS=-Xmx300M' >> start.sh

echo 'cd $DIRECTORY' >> start.sh

echo 'java $JAVA_ARGS -jar $FULLPATH --spring.config.location=file:/home/${{ secrets.SSH_USERNAME }}/capivara/main.properties --curupira.reset=${1-true}' >> start.sh
strip_components: 1

- name: 'Start BOT'
uses: appleboy/[email protected]
Expand All @@ -120,4 +69,4 @@ jobs:
key: ${{ secrets.VM_SSH_PRIVATE_KEY }}
script: |
cd /home/${{ secrets.SSH_USERNAME }}/capivara
nohup bash start.sh > nohup.out 2> nohup.err < /dev/null &
DISCORD_TOKEN=${{ secrets.DISCORD_BOT_TOKEN }} LOG_CHANNEL_ID=${{ secrets.DISCORD_LOG_CHANNEL_ID }} CURUPIRA_RESET=true DATABASE_DRIVER=org.postgresql.Driver DATABASE_DIALECT=org.hibernate.dialect.PostgreSQL95Dialect DATABASE_URL=jdbc:postgresql://localhost:5432/capivara DATABASE_USERNAME=${{ secrets.DATABASE_USERNAME }} DATABASE_PASSWORD=${{ secrets.DATABASE_PASSWORD }} JAVA_ARGS=-Xmx200M /bin/bash start-container.sh
41 changes: 41 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
FROM docker.io/eclipse-temurin:17-jdk-alpine as builder

WORKDIR /app
ADD . /tmp

ARG APP_VERSION="invalid"

RUN cd /tmp && \
chmod +x gradlew && \
./gradlew deploy -P version=$APP_VERSION --no-daemon && \
mv build/libs/CapivaraBot.jar /app && \
rm -rf /tmp/*

FROM docker.io/eclipse-temurin:17-jre-alpine

WORKDIR /app
COPY --from=builder /app .

ENV JAVA_ARGS="-Xmx300M"
ENV LOG_DIRECTORY="/app/logs"
ENV SPRING_CONFIG_LOCATION="/app/main.properties"
ENV DISCORD_TOKEN="invalid"
ENV CURUPIRA_RESET="true"
ENV LOG_CHANNEL_ID="invalid"
ENV DATABASE_DRIVER="org.postgresql.Driver"
ENV DATABASE_DIALECT="org.hibernate.dialect.PostgreSQL95Dialect"
ENV DATABASE_URL="jdbc:postgresql://localhost:5432/capivara"
ENV DATABASE_USERNAME="database-username"
ENV DATABASE_PASSWORD="database-password"

ENTRYPOINT java ${JAVA_ARGS} -jar CapivaraBot.jar \
--token=${DISCORD_TOKEN} \
--spring.config.location=file:${SPRING_CONFIG_LOCATION} \
--curupira.reset=${CURUPIRA_RESET} \
--log.directory=${LOG_DIRECTORY} \
--log.channel.id=${LOG_CHANNEL_ID} \
--spring.datasource.driverClassName=${DATABASE_DRIVER} \
--spring.jpa.database-platform=${DATABASE_DIALECT} \
--spring.datasource.url=${DATABASE_URL} \
--spring.datasource.username=${DATABASE_URL} \
--spring.datasource.password=${DATABASE_URL}
67 changes: 67 additions & 0 deletions start-container.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
if [ -z "${1}" ]; then
echo "Missing container repository and tag"
exit 1;
else
echo "Container repository and tag: $1"
fi
CONTAINER_REPOSITORY=${1}

if [[ -z "${DISCORD_TOKEN}" ]] || [[ -z "${LOG_CHANNEL_ID}" ]] ; then
echo 'Missing required environment variable: DISCORD_TOKEN, LOG_CHANNEL_ID'
exit 1
fi

CONTAINER_NAME="capivara_bot"
OLD_CONTAINER_ID=$(podman ps --all --quiet --filter "name=$CONTAINER_NAME")

if [[ -z "${OLD_CONTAINER_ID}" ]]; then
echo "Container not found"
else
echo "Found container $OLD_CONTAINER_ID"
echo "Stopping..."
WAIT=10 # seconds
podman stop $OLD_CONTAINER_ID -t $WAIT || { echo 'Failed to stop container'; exit 1; }
echo "Removing..."
podman rm --force $OLD_CONTAINER_ID || { echo 'Failed to remove container'; exit 1; }
fi

echo "Starting container..."
podman run -d \
-e DISCORD_TOKEN=$DISCORD_TOKEN \
-e LOG_CHANNEL_ID=$LOG_CHANNEL_ID \
-e CURUPIRA_RESET=${CURUPIRA_RESET:-false} \
-e DATABASE_DRIVER=${DATABASE_DRIVER:-org.h2.Driver} \
-e DATABASE_DIALECT=${DATABASE_DIALECT:-org.hibernate.dialect.H2Dialect} \
-e DATABASE_URL=${DATABASE_URL:-jdbc:h2:file:./banco_h2;DB_CLOSE_DELAY=-1} \
-e DATABASE_USERNAME=${DATABASE_USERNAME:-sa} \
-e DATABASE_PASSWORD=${DATABASE_PASSWORD:-sa} \
-e JAVA_ARGS=${JAVA_ARGS:--Xmx200M} \
--cpus 0.5 \
--memory 200M \
--name $CONTAINER_NAME \
--restart always \
$CONTAINER_REPOSITORY || { echo 'Failed to start container failed'; exit 1; }


SLEEP=10
CHECKS=0
MAX_CHECKS=3
echo "Starting 'healthcheck'"
while true; do
NEW_CONTAINER_ID=$(podman ps --quiet --filter "name=$CONTAINER_NAME")
if [[ -z "${NEW_CONTAINER_ID}" ]]; then
echo "Container died? exiting"
exit 1
fi

if [[ CHECKS -eq MAX_CHECKS ]]; then
break
fi
((CHECKS += 1))
sleep $SLEEP
done;

echo "Container should be alive"

echo "Cleaning images..."
podman image prune -a -f || { echo 'Failed to start clean images'; exit 1; }