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

Developer docker setup #683

Merged
merged 7 commits into from
Jan 28, 2025
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
69 changes: 51 additions & 18 deletions .github/workflows/dockerhub.yml
Original file line number Diff line number Diff line change
@@ -1,37 +1,70 @@
name: Publish Docker image
name: Publish Docker Images

on:
push:
tags:
- "v*"
branches:
- main
paths:
- "api/**"
- "client/**"
- "docker/**"
- "docker-compose*.yml"
workflow_dispatch:

permissions:
contents: read
packages: write

jobs:
push_to_registry:
name: Push Docker image to Docker Hub
name: Push Docker images to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Get tag name
- name: Get version info
run: |
(
echo "TAG_NAME=${GITHUB_REF#refs/*/v}";
echo "DOCKER_UI_REPO=${{secrets.DOCKER_UI_REPO}}"
echo "DOCKER_API_REPO=${{secrets.DOCKER_API_REPO}}"
) >> $GITHUB_ENV
if [[ $GITHUB_REF == refs/tags/* ]]; then
echo "VERSION=${GITHUB_REF#refs/*/v}" >> $GITHUB_ENV
echo "API_TAGS=${{secrets.DOCKER_API_REPO}}:latest,${{secrets.DOCKER_API_REPO}}:${GITHUB_REF#refs/*/v}" >> $GITHUB_ENV
echo "UI_TAGS=${{secrets.DOCKER_UI_REPO}}:latest,${{secrets.DOCKER_UI_REPO}}:${GITHUB_REF#refs/*/v}" >> $GITHUB_ENV
else
echo "VERSION=dev" >> $GITHUB_ENV
echo "API_TAGS=${{secrets.DOCKER_API_REPO}}:dev" >> $GITHUB_ENV
echo "UI_TAGS=${{secrets.DOCKER_UI_REPO}}:dev" >> $GITHUB_ENV
fi

- name: Check out the repo
uses: actions/checkout@v3

- name: Log in to Docker Hub
run: docker login -u "${{ secrets.DOCKER_USERNAME }}" -p "${{ secrets.DOCKER_ACCESS_TOKEN }}"
- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Build docker api image
run: docker build -f docker/Dockerfile.api . -t $DOCKER_API_REPO:latest -t $DOCKER_API_REPO:$TAG_NAME
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Build docker ui image
run: docker build -f docker/Dockerfile.client . -t $DOCKER_UI_REPO:latest -t $DOCKER_UI_REPO:$TAG_NAME
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}

- name: Push Docker api image
run: docker push $DOCKER_API_REPO:latest && docker push $DOCKER_API_REPO:$TAG_NAME
- name: Build and push API image
uses: docker/build-push-action@v5
with:
context: .
file: docker/Dockerfile.api
platforms: linux/amd64,linux/arm64
push: true
build-args: |
APP_ENV=${{ env.VERSION == 'dev' && 'local' || 'production' }}
tags: ${{ env.API_TAGS }}

- name: Push Docker ui image
run: docker push $DOCKER_UI_REPO:latest && docker push $DOCKER_UI_REPO:$TAG_NAME
- name: Build and push Client image
uses: docker/build-push-action@v5
with:
context: .
file: docker/Dockerfile.client
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ env.UI_TAGS }}
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,14 @@ public/.DS_Store
*.DS_Store
docker-compose.override.yml
/.make.*

# Environment files
.env
api/.env
client/.env
.env.*
api/.env.*
client/.env.*
!.env.example
!api/.env.example
!client/.env.example
77 changes: 77 additions & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
services:
api: &api-base
image: jhumanj/opnform-api:dev
build:
context: .
dockerfile: docker/Dockerfile.api
args:
APP_ENV: local
volumes:
- ./api:/usr/share/nginx/html:delegated
- /usr/share/nginx/html/vendor # Exclude vendor directory from the mount
- ./api/storage:/usr/share/nginx/html/storage:delegated # Mount storage directory directly
environment:
DB_HOST: db
REDIS_HOST: redis
DB_DATABASE: ${DB_DATABASE:-forge}
DB_USERNAME: ${DB_USERNAME:-forge}
DB_PASSWORD: ${DB_PASSWORD:-forge}
DB_CONNECTION: ${DB_CONNECTION:-pgsql}
FILESYSTEM_DISK: local
LOCAL_FILESYSTEM_VISIBILITY: public
APP_ENV: local
PHP_IDE_CONFIG: "serverName=Docker"
XDEBUG_MODE: "${XDEBUG_MODE:-off}"
XDEBUG_CONFIG: "client_host=host.docker.internal"
APP_URL: "http://localhost"
depends_on:
db:
condition: service_healthy

ui:
image: jhumanj/opnform-client:dev
build:
context: .
dockerfile: docker/Dockerfile.client
command: sh -c "npm install && NITRO_HOST=0.0.0.0 NITRO_PORT=3000 npm run dev"
volumes:
- ./client:/app:delegated
- /app/node_modules # Keep container's node_modules
environment:
NODE_ENV: development
NUXT_PUBLIC_APP_ENV: development
HOST: "0.0.0.0"
PORT: 3000
# HMR settings
CHOKIDAR_USEPOLLING: "true"
WATCHPACK_POLLING: "true"
VITE_HMR_HOST: "localhost"
VITE_HMR_PORT: 24678
# API settings
NUXT_PUBLIC_APP_URL_BASE: "http://localhost"
NUXT_PUBLIC_API_BASE: "http://localhost/api"
extra_hosts:
- "host.docker.internal:host-gateway"
ports:
- "3000:3000" # Main dev server
- "24678:24678" # Vite HMR port

ingress:
volumes:
- ./docker/nginx.dev.conf:/etc/nginx/templates/default.conf.template
environment:
NGINX_HOST: localhost
NGINX_PORT: 80
ports:
- "80:80"
depends_on:
- api
- ui

api-worker:
<<: *api-base
environment:
IS_API_WORKER: "true"
depends_on:
db:
condition: service_healthy
9 changes: 9 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ services:
build:
context: .
dockerfile: docker/Dockerfile.api
args:
APP_ENV: production
environment: &api-environment # Add this anchor
DB_HOST: db
REDIS_HOST: redis
Expand All @@ -24,6 +26,8 @@ services:
build:
context: .
dockerfile: docker/Dockerfile.api
args:
APP_ENV: production
command: php artisan queue:work
environment:
<<: *api-environment
Expand All @@ -50,6 +54,11 @@ services:
POSTGRES_DB: ${DB_DATABASE:-forge}
POSTGRES_USER: ${DB_USERNAME:-forge}
POSTGRES_PASSWORD: ${DB_PASSWORD:-forge}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USERNAME:-forge}"]
interval: 5s
timeout: 5s
retries: 5
volumes:
- postgres-data:/var/lib/postgresql/data

Expand Down
66 changes: 43 additions & 23 deletions docker/Dockerfile.api
Original file line number Diff line number Diff line change
@@ -1,44 +1,64 @@
FROM php:8.3-fpm
# Stage 1: Composer dependencies
FROM composer:latest as composer
WORKDIR /app
COPY api/composer.* ./

ARG APP_ENV=production
RUN if [ "$APP_ENV" = "production" ]; then \
composer install --ignore-platform-req=php --no-dev --optimize-autoloader; \
else \
composer install --ignore-platform-req=php --optimize-autoloader; \
fi

# syntax=docker/dockerfile:1.3-labs
# Stage 2: Final image
FROM php:8.3-fpm

# Install system dependencies and PHP extensions
RUN apt-get update && apt-get install -y \
libzip-dev \
git \
curl \
libpng-dev \
postgresql-client \
libonig-dev \
libxml2-dev \
zip \
unzip \
libpq-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
ENV COMPOSER_ALLOW_SUPERUSER=1
RUN docker-php-ext-install pdo pgsql pdo_pgsql gd bcmath zip \
&& docker-php-ext-install pdo_pgsql mbstring exif pcntl bcmath gd \
&& pecl install redis \
&& docker-php-ext-enable redis

WORKDIR /usr/share/nginx/html/
# Install xdebug if not in production
ARG APP_ENV=production
RUN if [ "$APP_ENV" != "production" ]; then \
pecl install xdebug && \
docker-php-ext-enable xdebug; \
fi

# Combine multiple ADD commands into one
COPY api/composer.json api/composer.lock api/artisan ./
COPY api/app ./app
# Configure PHP
COPY docker/php/php.ini /usr/local/etc/php/conf.d/app.ini
COPY docker/php/php-fpm.conf /usr/local/etc/php-fpm.d/www.conf

WORKDIR /usr/share/nginx/html

# Copy application files
COPY api/artisan artisan
COPY api/bootstrap ./bootstrap
COPY api/config ./config
COPY api/app ./app
COPY api/database ./database
COPY api/public ./public
COPY api/routes ./routes
COPY api/tests ./tests
COPY api/resources ./resources
COPY api/storage ./storage

RUN sed 's_@php artisan package:discover_/bin/true_;' -i composer.json \
&& composer install --ignore-platform-req=php --no-dev --optimize-autoloader \
&& composer clear-cache \
&& php artisan package:discover --ansi \
&& chmod -R 775 storage \
&& chown -R www-data:www-data storage \
&& mkdir -p storage/framework/sessions storage/framework/views storage/framework/cache \
&& chown -R www-data:www-data storage \
&& chmod -R 775 storage
# Copy vendor directory from composer stage
COPY --from=composer /app/vendor ./vendor

# Set permissions
RUN chmod -R 775 storage \
&& chmod -R 775 bootstrap/cache \
&& chown -R www-data:www-data /usr/share/nginx/html

COPY docker/php-fpm-entrypoint /usr/local/bin/opnform-entrypoint
RUN chmod a+x /usr/local/bin/*
Expand Down
54 changes: 26 additions & 28 deletions docker/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,36 @@ map $original_uri $api_uri {
}

server {
listen 80;
server_name opnform;
root /app/public;
listen 80;
server_name opnform;
root /usr/share/nginx/html/public;

access_log /dev/stdout;
error_log /dev/stderr error;
access_log /dev/stdout;
error_log /dev/stderr error;

index index.html index.htm index.php;
index index.html index.htm index.php;

location / {
proxy_http_version 1.1;
proxy_pass http://ui:3000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
location / {
proxy_http_version 1.1;
proxy_pass http://ui:3000;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}

location ~/(api|open|local\/temp|forms\/assets)/ {
set $original_uri $uri;
try_files $uri $uri/ /index.php$is_args$args;
}
location ~/(api|open|local\/temp|forms\/assets)/ {
try_files $uri $uri/ /index.php?$query_string;
}

location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass api:9000;
fastcgi_index index.php;
include fastcgi_params;
#fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/$fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/public/index.php;
fastcgi_param REQUEST_URI $api_uri;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass api:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/public/index.php;
fastcgi_param REQUEST_URI $api_uri;
}
}

Loading
Loading