-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathMakefile
More file actions
172 lines (156 loc) · 6.66 KB
/
Copy pathMakefile
File metadata and controls
172 lines (156 loc) · 6.66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# Makefile for Docker build, test, and run workflow
# By Jason Gegere <jason@htmlgraphic.com>
# Variables
IMAGE_NAME := htmlgraphic/apache
TAG := 2.1.0
REGISTRY := docker.io
CONTAINER_NAME := apache
ENV_FILE := .env
PLATFORM := linux/arm64
INSTALL_DEV_TOOLS ?= true
BUILD_ARGS := --build-arg INSTALL_DEV_TOOLS=$(INSTALL_DEV_TOOLS)
COMPOSE_DEV := docker compose -f docker-compose.local.yml
COMPOSE_PROD := docker compose -f docker-compose.yml
NODE_ENV := $(shell grep -E '^NODE_ENVIRONMENT=' $(ENV_FILE) | cut -d '=' -f 2-)
# Load environment variables from .env
ifneq (,$(wildcard $(ENV_FILE)))
include $(ENV_FILE)
export
endif
# Default environment
NODE_ENVIRONMENT ?= dev
.PHONY: all help env build test run start stop state logs push clean
# Default target
all: env help
# Help menu
help:
@echo ""
@echo "-- Help Menu for $(IMAGE_NAME):$(TAG)"
@echo ""
@echo " make build - Build Image"
@echo " make clean - Remove images and prune system"
@echo " make env - Create and list .env variables"
@echo " make build INSTALL_DEV_TOOLS=false - Build production image without dev utilities"
@echo " make logs - View logs"
@echo " make push - Push $(IMAGE_NAME):$(TAG) to public Docker repo"
@echo " make run - Run docker-compose and create local environment"
@echo " make start - Start the EXISTING $(CONTAINER_NAME) container"
@echo " make state - View state of $(CONTAINER_NAME) container"
@echo " make stop - Stop running containers"
@echo " make test - Test components in existing $(CONTAINER_NAME) container"
# Create .env if missing
env:
@[ ! -f $(ENV_FILE) ] && echo " .env file does not exist, copying template\n" && cp .env.example $(ENV_FILE) || echo " .env file exists\n"
@echo "The following environment variables exist:"
@echo $(shell sed 's/=.*//' $(ENV_FILE))
@echo ''
# Build the Docker image
build:
@echo "Building Docker image $(IMAGE_NAME):$(TAG)..."
@if [ -n "$$(docker images -q $(IMAGE_NAME):$(TAG))" ]; then \
echo "Image $(IMAGE_NAME):$(TAG) already exists."; \
printf "Do you want to rebuild the image? (y/N): "; \
read confirm; \
if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
echo "Rebuilding Docker image $(IMAGE_NAME):$(TAG)..."; \
docker build --no-cache --platform $(PLATFORM) $(BUILD_ARGS) -t $(IMAGE_NAME):$(TAG) .; \
else \
echo "Skipping build."; \
fi; \
else \
echo "Image does not exist, building..."; \
docker build --platform $(PLATFORM) $(BUILD_ARGS) -t $(IMAGE_NAME):$(TAG) .; \
fi
# Test the existing container
test:
@echo "Testing components in existing $(CONTAINER_NAME) container"
@for i in $$(seq 1 60); do \
CONTAINER_STATUS=$$(docker inspect --format='{{.State.Status}}' $(CONTAINER_NAME) 2>/dev/null || echo "not_found"); \
if [ "$$CONTAINER_STATUS" = "running" ]; then \
if docker exec $(CONTAINER_NAME) sh -c "[ -f /etc/supervisord.conf ]" 2>/dev/null; then \
if docker exec $(CONTAINER_NAME) sh -c "[ -S /var/run/supervisor.sock ]" 2>/dev/null; then \
echo "Container and supervisor socket are ready"; \
break; \
else \
echo "Waiting for supervisor socket ($$i/60)"; \
sleep 2; \
fi; \
else \
echo "Error: Supervisor configuration file /etc/supervisord.conf not found"; \
exit 1; \
fi; \
elif [ "$$CONTAINER_STATUS" = "restarting" ]; then \
echo "Container is restarting, waiting ($$i/60)"; \
sleep 2; \
elif [ "$$CONTAINER_STATUS" = "not_found" ]; then \
echo "Error: Container $(CONTAINER_NAME) is not running. Run 'make run' or 'make start' first."; \
exit 1; \
else \
echo "Error: Container $(CONTAINER_NAME) is in unexpected state: $$CONTAINER_STATUS"; \
exit 1; \
fi; \
if [ $$i -eq 60 ]; then \
echo "Error: Container failed to stabilize or supervisor socket missing after 120 seconds"; \
exit 1; \
fi; \
done
@docker exec $(CONTAINER_NAME) apache2ctl configtest || { echo "apache2 config test failed"; exit 1; }
@docker exec $(CONTAINER_NAME) supervisorctl -c /etc/supervisord.conf status | grep -E 'apache2.*RUNNING|postfix.*RUNNING' | wc -l | grep -q 2 || { echo "supervisorctl status test failed: not all processes are RUNNING"; docker exec $(CONTAINER_NAME) supervisorctl -c /etc/supervisord.conf status; exit 1; }
@docker exec $(CONTAINER_NAME) composer --version || { echo "composer test failed"; exit 1; }
@if [ "$(NODE_ENVIRONMENT)" = "dev" ]; then \
docker exec $(CONTAINER_NAME) git --version || { echo "git test failed"; exit 1; }; \
docker exec $(CONTAINER_NAME) vim --version || { echo "vim test failed"; exit 1; }; \
docker exec $(CONTAINER_NAME) ping -V || { echo "ping test failed"; exit 1; }; \
docker exec $(CONTAINER_NAME) wget --version || { echo "wget test failed"; exit 1; }; \
fi
@docker exec $(CONTAINER_NAME) mysql --version || { echo "mysql test failed"; exit 1; }
@docker exec $(CONTAINER_NAME) php -m | grep redis || { echo "php redis module test failed"; exit 1; }
@docker exec $(CONTAINER_NAME) dpkg -l | grep -E 'mailutils|locales' || { echo "dpkg test failed"; exit 1; }
# Run the containers
run:
@make env
@echo "Setting environment variables...\n"
@echo "Checking initial directory structure\n"
@if [ "$(NODE_ENVIRONMENT)" = "dev" ]; then \
if [ ! -d "$(HOME)/SITES/docker" ]; then \
echo " Creating project folders\n" && mkdir -p "$(HOME)/SITES/docker" && chmod 777 "$(HOME)/SITES/docker"; \
fi \
fi
@echo "\033[1mRun the following on the MySQL container to setup a GLOBAL admin:\033[00m\n"
@echo " The password for \033[1m$(MYSQL_USER)\033[00m is loaded from $(ENV_FILE)."
@echo ''
@echo " docker exec -it db /bin/bash\n \
mysql -p\n \
GRANT ALL PRIVILEGES ON *.* TO '$(MYSQL_USER)'@'%' WITH GRANT OPTION;\n"
$(COMPOSE_DEV) up -d --remove-orphans
# Start (alias for run)
start: run
# Stop and remove containers
stop:
@echo "Stopping containers"
$(COMPOSE_DEV) down --remove-orphans
# View container state
state:
@docker ps -a | grep $(CONTAINER_NAME)
# View container logs
logs:
@echo "Viewing logs for $(CONTAINER_NAME)"
@if [ "$(NODE_ENVIRONMENT)" = "dev" ]; then \
docker logs $(CONTAINER_NAME); \
docker logs db; \
else \
docker logs $(CONTAINER_NAME)-web-1; \
docker logs $(CONTAINER_NAME)-db-1; \
fi
# Push the image to the registry
push:
@echo "Pushing $(IMAGE_NAME):$(TAG) to $(REGISTRY)"
@echo "Note: If the repository is an automated build, you may not be able to push"
docker tag $(IMAGE_NAME):$(TAG) $(REGISTRY)/$(IMAGE_NAME):$(TAG)
docker push $(REGISTRY)/$(IMAGE_NAME):$(TAG)
# Clean up images and cache
clean:
@echo "Cleaning up Docker images and cache"
docker rmi $(IMAGE_NAME):$(TAG) || true
docker rmi $(IMAGE_NAME):latest || true
docker system prune -f