Skip to content

Commit 811a11f

Browse files
author
Automation
committed
feat: production Docker image (nginx+php-fpm), docker-compose, GHCR publish workflow, and one-touch deploy.sh
1 parent d64d86b commit 811a11f

15 files changed

Lines changed: 268 additions & 1877 deletions

.dockerignore

Lines changed: 11 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,15 @@
1-
# Git
21
.git
32
.gitignore
4-
5-
# Documentation
6-
README.md
7-
DOCKER_README.md
8-
docs/
9-
10-
# Environment files
3+
node_modules
4+
vendor/bin
5+
vendor/composer/installed.json
6+
vendor/composer/installed.php
7+
vendor/composer/installed_dev.json
8+
vendor/composer/*autoload*
9+
docker-data
10+
logs/*
1111
.env
12-
.env.local
13-
.env.backup
14-
docker.env
15-
docker.env.example
16-
17-
# Logs
18-
*.log
19-
logs/
20-
21-
# IDE files
22-
.vscode/
23-
.idea/
24-
*.swp
25-
*.swo
26-
*~
27-
28-
# OS generated files
29-
.DS_Store
30-
.DS_Store?
31-
._*
32-
.Spotlight-V100
33-
.Trashes
34-
ehthumbs.db
35-
Thumbs.db
36-
37-
# Cache files
38-
*.cache
39-
cache/
40-
41-
# Temporary files
42-
tmp/
43-
temp/
44-
*.tmp
45-
46-
# Database files
47-
*.sqlite
48-
*.db
49-
50-
# Backup files
51-
*.bak
52-
*.backup
53-
54-
# Test files
55-
tests/
56-
test_*.php
57-
58-
# Docker
59-
Dockerfile
60-
docker-compose.yml
61-
.dockerignore
12+
config/.env
13+
**/.DS_Store
14+
**/Thumbs.db
6215

63-
# Scripts
64-
scripts/
65-
setup-env.sh
66-
start-docker.sh
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Build and Publish Docker image
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
packages: write
11+
12+
env:
13+
IMAGE_NAME: github-smart
14+
REGISTRY: ghcr.io
15+
OWNER: ${{ github.repository_owner }}
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
24+
- name: Log in to GitHub Container Registry
25+
uses: docker/login-action@v3
26+
with:
27+
registry: ${{ env.REGISTRY }}
28+
username: ${{ github.actor }}
29+
password: ${{ secrets.GITHUB_TOKEN }}
30+
31+
- name: Extract metadata (tags, labels)
32+
id: meta
33+
uses: docker/metadata-action@v5
34+
with:
35+
images: ${{ env.REGISTRY }}/${{ env.OWNER }}/${{ env.IMAGE_NAME }}
36+
tags: |
37+
type=ref,event=branch
38+
type=sha
39+
type=semver,pattern={{version}}
40+
41+
- name: Set up Buildx
42+
uses: docker/setup-buildx-action@v3
43+
44+
- name: Build and push
45+
uses: docker/build-push-action@v6
46+
with:
47+
context: .
48+
file: ./Dockerfile
49+
push: true
50+
tags: ${{ steps.meta.outputs.tags }}
51+
labels: ${{ steps.meta.outputs.labels }}
52+
53+

Dockerfile

Lines changed: 32 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,47 @@
1-
# Multi-stage build for production
2-
FROM composer:2.6 AS composer
1+
# Multi-service app image: Nginx + PHP-FPM + app code
32

4-
# Copy composer files
5-
COPY composer.json composer.lock ./
3+
FROM composer:2 AS vendor
4+
WORKDIR /app
65

7-
# Install dependencies
8-
RUN composer install --no-dev --optimize-autoloader --no-scripts
6+
# Only copy composer files first for better caching
7+
COPY composer.json composer.lock ./
8+
RUN composer install --no-dev --no-interaction --prefer-dist --no-scripts --no-progress
99

10-
# Production stage
11-
FROM php:8.1-apache
10+
# Final image
11+
FROM php:8.2-fpm-alpine
1212

13-
# Install system dependencies
14-
RUN apt-get update && apt-get install -y \
15-
libzip-dev \
16-
libpng-dev \
17-
libjpeg-dev \
18-
libfreetype6-dev \
19-
libxml2-dev \
20-
libcurl4-openssl-dev \
21-
git \
22-
unzip \
23-
curl \
24-
&& rm -rf /var/lib/apt/lists/*
13+
ENV APP_ENV=production \
14+
COMPOSER_ALLOW_SUPERUSER=1 \
15+
PHP_MEMORY_LIMIT=256M \
16+
PHP_OPCACHE_VALIDATE_TIMESTAMPS=0
2517

26-
# Install PHP extensions
27-
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
28-
&& docker-php-ext-install -j$(nproc) \
29-
pdo_mysql \
30-
zip \
31-
gd \
32-
curl \
33-
xml
18+
# Install system deps, nginx, supervisor, and PHP extensions
19+
RUN set -eux; \
20+
apk add --no-cache bash curl nginx supervisor; \
21+
docker-php-ext-install pdo pdo_mysql mysqli; \
22+
mkdir -p /run/nginx
3423

35-
# Set working directory
3624
WORKDIR /var/www/html
3725

38-
# Copy application files
39-
COPY . .
40-
41-
# Copy vendor directory from composer stage
42-
COPY --from=composer /app/vendor ./vendor
43-
44-
# Create logs directory if it doesn't exist
45-
RUN mkdir -p /var/www/html/logs
26+
# Copy app source
27+
COPY . /var/www/html
4628

47-
# Create config log file and set proper permissions (as root)
48-
RUN touch /var/www/html/config/app.log \
49-
&& chown -R www-data:www-data /var/www/html \
50-
&& chmod -R 755 /var/www/html \
51-
&& chmod -R 777 /var/www/html/logs \
52-
&& chmod 666 /var/www/html/config/app.log
29+
# Copy vendor from composer stage
30+
COPY --from=vendor /app/vendor /var/www/html/vendor
5331

54-
# Configure Apache document root
55-
ENV APACHE_DOCUMENT_ROOT=/var/www/html/public
56-
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf \
57-
&& sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
32+
# Nginx and Supervisor configuration
33+
COPY docker/nginx/default.conf /etc/nginx/conf.d/default.conf
34+
COPY docker/supervisord.conf /etc/supervisord.conf
5835

59-
# Enable mod_rewrite
60-
RUN a2enmod rewrite
36+
# Permissions
37+
RUN addgroup -g 1000 -S www && adduser -u 1000 -S www -G www; \
38+
chown -R www:www /var/www/html; \
39+
find /var/www/html -type f -exec chmod 0644 {} \; ; \
40+
find /var/www/html -type d -exec chmod 0755 {} \; ; \
41+
chmod -R 0775 /var/www/html/logs || true
6142

62-
# Security: Disable Apache version and server info
63-
RUN echo "ServerTokens Prod" >> /etc/apache2/apache2.conf \
64-
&& echo "ServerSignature Off" >> /etc/apache2/apache2.conf
65-
66-
# Create non-root user for security
67-
RUN useradd -m -s /bin/bash appuser \
68-
&& usermod -a -G www-data appuser
69-
70-
# Configure Apache to run as non-root user
71-
RUN sed -i 's/Listen 80/Listen 8080/' /etc/apache2/ports.conf \
72-
&& sed -i 's/<VirtualHost \*:80>/<VirtualHost *:8080>/' /etc/apache2/sites-available/000-default.conf
73-
74-
# Expose port 8080 (non-privileged port)
7543
EXPOSE 8080
7644

77-
# Health check
78-
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
79-
CMD curl -f http://localhost:8080/ || exit 1
45+
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
46+
8047

81-
# Start Apache as non-root user
82-
USER appuser
83-
CMD ["apache2-foreground"]

0 commit comments

Comments
 (0)