Fix after test on test-repo
This commit is contained in:
@@ -3,12 +3,13 @@ name: CI
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
IMAGE_NAME: ${{ vars.IMAGE_NAME }}
|
||||
REGISTRY_LOCATION: ${{ vars.REGISTRY_LOCATION }}
|
||||
REGISTRY_ORGANIZATION: ${{ vars.REGISTRY_ORGANIZATION }}
|
||||
PORT: ${{ vars.PORT }}
|
||||
TEST_PORT: ${{ vars.TEST_PORT }}
|
||||
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
|
||||
@@ -16,6 +17,7 @@ env:
|
||||
DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }}
|
||||
PROD_SERVER_HOST: ${{ secrets.PROD_SERVER_HOST }}
|
||||
DEPLOY_USER: ${{ secrets.DEPLOY_USER }}
|
||||
BUILD_NUMBER: build-${{ gitea.run_number }}
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
@@ -31,10 +33,6 @@ jobs:
|
||||
echo "Basic HTML validation"
|
||||
test -f index.html
|
||||
|
||||
- name: 🐋 Validate Dockerfile
|
||||
run: |
|
||||
dockerfilelint Dockerfile || true
|
||||
|
||||
build:
|
||||
name: Build & Push Docker Image
|
||||
runs-on: ubuntu-latest
|
||||
@@ -44,14 +42,10 @@ jobs:
|
||||
- name: 📥 Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🔖 Set image metadata
|
||||
run: |
|
||||
echo "RUN_NUMBER=${GITEA_RUN_NUMBER}" >> $GITEA_ENV
|
||||
|
||||
- name: 🐋 Build Docker image
|
||||
run: |
|
||||
docker build \
|
||||
-t $IMAGE_NAME:$RUN_NUMBER \
|
||||
-t $IMAGE_NAME:$BUILD_NUMBER \
|
||||
-t $IMAGE_NAME:latest \
|
||||
.
|
||||
|
||||
@@ -65,13 +59,13 @@ jobs:
|
||||
|
||||
- name: 🏷️ Build images
|
||||
run: |
|
||||
docker tag $IMAGE_NAME:latest $REGISTRY_LOCATION/$IMAGE_NAME:latest
|
||||
docker tag $IMAGE_NAME:$RUN_NUMBER $REGISTRY_LOCATION/$IMAGE_NAME:build-$RUN_NUMBER
|
||||
docker tag $IMAGE_NAME:latest $REGISTRY_LOCATION/$REGISTRY_ORGANIZATION/$IMAGE_NAME:latest
|
||||
docker tag $IMAGE_NAME:$BUILD_NUMBER $REGISTRY_LOCATION/$REGISTRY_ORGANIZATION/$IMAGE_NAME:$BUILD_NUMBER
|
||||
|
||||
- name: 🚀 Push images
|
||||
run: |
|
||||
docker push $REGISTRY_LOCATION/$IMAGE_NAME:latest
|
||||
docker push $REGISTRY_LOCATION/$IMAGE_NAME:build-$RUN_NUMBER
|
||||
docker push $REGISTRY_LOCATION/$REGISTRY_ORGANIZATION/$IMAGE_NAME:latest
|
||||
docker push $REGISTRY_LOCATION/$REGISTRY_ORGANIZATION/$IMAGE_NAME:$BUILD_NUMBER
|
||||
|
||||
deploy:
|
||||
name: 🚀 Deploy image to prod
|
||||
@@ -86,26 +80,56 @@ jobs:
|
||||
chmod 600 ~/.ssh/id_rsa
|
||||
ssh-keyscan -H $PROD_SERVER_HOST >> ~/.ssh/known_hosts
|
||||
|
||||
- name: 🔑 Login to registry
|
||||
- name: 🗝️ Login to registry
|
||||
run: |
|
||||
echo "$REGISTRY_TOKEN" | docker login $REGISTRY_LOCATION \
|
||||
-u "$REGISTRY_USER" --password-stdin
|
||||
|
||||
- name: 🚢 Deploy container
|
||||
- name: 🔌 SSH into the prod server
|
||||
run: |
|
||||
ssh $DEPLOY_USER@$PROD_SERVER_HOST << 'EOF'
|
||||
set -e
|
||||
NEW_IMAGE_NAME="$REGISTRY_LOCATION/$IMAGE_NAME:build-$RUN_NUMBER"
|
||||
OLD_CONTAINER_NAME=$(docker inspect $IMAGE_NAME --format='{{.Config.Image}}')
|
||||
NEW_CONTAINER_IMAGE="$IMAGE_NAME:build-$RUN_NUMBER"
|
||||
sleep 5
|
||||
|
||||
echo "Pulling image $NEW_IMAGE_NAME"
|
||||
- name: 🚀 Deploy container to prod
|
||||
run: |
|
||||
set -e
|
||||
NEW_IMAGE_NAME="$REGISTRY_LOCATION/$REGISTRY_ORGANIZATION/$IMAGE_NAME:$BUILD_NUMBER"
|
||||
TEST_CONTAINER_NAME=test-$IMAGE_NAME
|
||||
OLD_IMAGE_NAME=$(docker inspect $IMAGE_NAME --format='{{.Config.Image}}')
|
||||
NEW_CONTAINER_IMAGE="$IMAGE_NAME:$BUILD_NUMBER"
|
||||
|
||||
echo "🏗️ Building functions"
|
||||
|
||||
# checks the health of the given container name $1
|
||||
# returns "healthy" or "unhealthy"
|
||||
is_container_healthy() {
|
||||
for i in {1..15}; do
|
||||
RETURN=$(docker inspect --format='{{.State.Health.Status}}' $1)
|
||||
[ "$RETURN" = "healthy" ] && break
|
||||
[ "$RETURN" = "unhealthy" ] && break
|
||||
sleep 2
|
||||
done
|
||||
echo "$RETURN"
|
||||
}
|
||||
|
||||
|
||||
echo "🎣 Pulling image $NEW_IMAGE_NAME"
|
||||
docker pull "$NEW_IMAGE_NAME"
|
||||
|
||||
|
||||
echo "🧪 Test the new container health"
|
||||
|
||||
# if old test container is running then stop and remove it
|
||||
if docker ps -a --format '{{.Names}}' | grep "^$TEST_CONTAINER_NAME$"; then
|
||||
echo "Container ${TEST_CONTAINER_NAME} is running. Stopping and removing..."
|
||||
docker stop $TEST_CONTAINER_NAME
|
||||
docker rm $TEST_CONTAINER_NAME
|
||||
fi
|
||||
|
||||
echo "Starting new test container"
|
||||
docker run -d \
|
||||
--name $NEW_CONTAINER_IMAGE \
|
||||
--health-cmd="wget -qO- http://localhost:$TEST_PORT/health || exit 1" \
|
||||
--name $TEST_CONTAINER_NAME \
|
||||
--health-cmd="curl -f http://$PROD_SERVER_HOST:$TEST_PORT/health || exit 1" \
|
||||
--health-interval=5s \
|
||||
--health-retries=5 \
|
||||
--health-timeout=2s \
|
||||
@@ -113,57 +137,73 @@ jobs:
|
||||
-p $TEST_PORT:80 \
|
||||
"$NEW_CONTAINER_IMAGE"
|
||||
|
||||
echo "Waiting for healthcheck..."
|
||||
for i in {1..15}; do
|
||||
STATUS=$(docker inspect --format='{{.State.Health.Status}}' $NEW_CONTAINER_IMAGE)
|
||||
[ "$STATUS" = "healthy" ] && break
|
||||
[ "$STATUS" = "unhealthy" ] && break
|
||||
sleep 2
|
||||
done
|
||||
TEST_CONTAINER_HEALTHCHECK=$(is_container_healthy $TEST_CONTAINER_NAME)
|
||||
|
||||
docker stop $NEW_CONTAINER_IMAGE
|
||||
docker image rm $NEW_CONTAINER_IMAGE
|
||||
docker stop $TEST_CONTAINER_NAME
|
||||
docker rm $TEST_CONTAINER_NAME
|
||||
|
||||
echo "🚚 Deploy the new image if healthy, otherwise rollback"
|
||||
if [ "$TEST_CONTAINER_HEALTHCHECK" = "healthy" ]; then
|
||||
echo "✅ Test Container is healthy - starting deployment"
|
||||
|
||||
# Stop previous prod running container if found
|
||||
if [ -n "$OLD_IMAGE_NAME" ]; then
|
||||
echo "Stopping previous prod running container"
|
||||
docker stop $IMAGE_NAME
|
||||
docker rm $IMAGE_NAME
|
||||
fi
|
||||
|
||||
if [ "$STATUS" = "healthy" ]; then
|
||||
echo "✅ Container is healthy - starting deployment"
|
||||
docker stop $OLD_CONTAINER_NAME
|
||||
docker run -d \
|
||||
--name $NEW_CONTAINER_IMAGE \
|
||||
--health-cmd="wget -qO- http://localhost:$PORT/health || exit 1" \
|
||||
--name $IMAGE_NAME \
|
||||
--health-cmd="curl -f http://$PROD_SERVER_HOST:$PORT/health || exit 1" \
|
||||
--health-interval=5s \
|
||||
--health-retries=5 \
|
||||
--health-timeout=2s \
|
||||
--health-start-period=5s \
|
||||
-p $PORT:80 \
|
||||
"$NEW_CONTAINER_IMAGE"
|
||||
sleep 10
|
||||
|
||||
DEPLOYMENT_STATUS=$(docker inspect --format='{{.State.Health.Status}}' $NEW_CONTAINER_IMAGE)
|
||||
PROD_CONTAINER_HEALTHCHECK=$(is_container_healthy $IMAGE_NAME)
|
||||
|
||||
if [ "$DEPLOYMENT_STATUS" != "healthy" ]; then
|
||||
if [ "$PROD_CONTAINER_HEALTHCHECK" != "healthy" ]; then
|
||||
echo "❌ Deployment failed — rolling back"
|
||||
docker logs $NEW_CONTAINER_IMAGE
|
||||
docker rm -f $NEW_CONTAINER_IMAGE
|
||||
docker logs $IMAGE_NAME
|
||||
docker stop $IMAGE_NAME
|
||||
docker rm -f $IMAGE_NAME
|
||||
docker image rm $NEW_CONTAINER_IMAGE
|
||||
|
||||
if [ -n "$OLD_CONTAINER_NAME" ]; then
|
||||
if [ -n "$OLD_IMAGE_NAME" ]; then
|
||||
docker run -d \
|
||||
--name $OLD_CONTAINER_NAME \
|
||||
--health-cmd="wget -qO- http://localhost:$PORT/health || exit 1" \
|
||||
--name $IMAGE_NAME \
|
||||
--health-cmd="curl -f http://$PROD_SERVER_HOST:$PORT/health || exit 1" \
|
||||
--health-interval=5s \
|
||||
--health-retries=5 \
|
||||
--health-timeout=2s \
|
||||
--health-start-period=5s \
|
||||
-p $PORT:80 \
|
||||
"$OLD_CONTAINER_NAME"
|
||||
"$OLD_IMAGE_NAME"
|
||||
|
||||
if [["$(is_container_healthy $IMAGE_NAME)" == "healthy" ]]; then
|
||||
echo "❌ Deployment failed — ✅ rollback successfull"
|
||||
else
|
||||
echo "❌ Deployment failed — ❌ rollback failed"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
echo "❌ Deployment failed — ❌ rollback not possible (no previous version was running)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
docker image rm $OLD_CONTAINER_NAME
|
||||
echo "✅ Deployment successfull"
|
||||
if [ -n "$OLD_IMAGE_NAME" ]; then
|
||||
docker image rm $OLD_IMAGE_NAME
|
||||
fi
|
||||
|
||||
echo "✅ Deployment successfull ($IMAGE_NAME)"
|
||||
exit 0
|
||||
else
|
||||
|
||||
docker image rm $NEW_CONTAINER_IMAGE
|
||||
echo "❌ Deployment failed — ❤️ healthcheck failed on the test container"
|
||||
exit 1
|
||||
fi
|
||||
EOF
|
||||
|
||||
18
README.md
18
README.md
@@ -24,12 +24,11 @@ It is designed to be **forked and reused** as a starting point for real-world de
|
||||
│ └── workflows/
|
||||
│ └── ci.yml
|
||||
├── assets/
|
||||
│ ├── scripts/
|
||||
│ └── styles/
|
||||
├── docker/
|
||||
│ ├── default.conf.template
|
||||
│ └── nginx.conf
|
||||
├── src/
|
||||
│ ├── css/
|
||||
│ └── js/
|
||||
├── Dockerfile
|
||||
├── index.html
|
||||
└── README.md
|
||||
@@ -94,12 +93,13 @@ Used by:
|
||||
The following secrets and variables **must be setup** inside the destination repository.
|
||||
|
||||
### Variables
|
||||
| Variable | Description |
|
||||
| ------------------- | --------------------------------------------------- |
|
||||
| `IMAGE_NAME` | Name of the docker image (built and deployed) |
|
||||
| `REGISTRY_LOCATION` | Location of the image registery |
|
||||
| `PORT` | Port on which the site will be exposed on |
|
||||
| `TEST_PORT` | Port on which the test container will be exposed on |
|
||||
| Variable | Description |
|
||||
| ----------------------- | --------------------------------------------------- |
|
||||
| `IMAGE_NAME` | Name of the docker image (built and deployed) |
|
||||
| `REGISTRY_LOCATION` | Location of the image registery |
|
||||
| `REGISTRY_ORGANIZATION` | Name of the organisation in the image registery |
|
||||
| `PORT` | Port on which the site will be exposed on |
|
||||
| `TEST_PORT` | Port on which the test container will be exposed on |
|
||||
|
||||
### Secrets
|
||||
| Secrets | Description |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
server {
|
||||
listen ${NGINX_PORT};
|
||||
server_name ${NGINX_SERVER_NAME};
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
Reference in New Issue
Block a user