mirror of
https://code.castopod.org/adaures/castopod
synced 2025-04-19 13:01:19 +00:00
build(docker): add production-ready DockerFiles
- add docker images for app (castopod) and web-server (nginx) - ci: deploy images continuously to a docker hub using kaniko - ci: trigger docker-build-rolling on develop branch - move development DockerFile to docker directory closes #200
This commit is contained in:
parent
de8b1df948
commit
0c0730be69
@ -5,6 +5,7 @@ stages:
|
||||
- quality
|
||||
- bundle
|
||||
- release
|
||||
- build
|
||||
- deploy
|
||||
|
||||
php-dependencies:
|
||||
@ -151,3 +152,16 @@ documentation:
|
||||
only:
|
||||
changes:
|
||||
- docs/**/*
|
||||
|
||||
docker:
|
||||
stage: build
|
||||
trigger:
|
||||
include: docker/production/.gitlab-ci.yml
|
||||
strategy: depend
|
||||
variables:
|
||||
PARENT_PIPELINE_ID: $CI_PIPELINE_ID
|
||||
only:
|
||||
refs:
|
||||
- develop
|
||||
variables:
|
||||
- $CI_PROJECT_NAMESPACE == "adaures"
|
||||
|
@ -7,7 +7,7 @@ services:
|
||||
app:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
dockerfile: docker/development/Dockerfile
|
||||
container_name: app
|
||||
command: /bin/sh -c "crontab ./crontab && cron && service cron reload && php spark serve - 0.0.0.0"
|
||||
ports:
|
||||
|
20
docker/production/.gitlab-ci.yml
Normal file
20
docker/production/.gitlab-ci.yml
Normal file
@ -0,0 +1,20 @@
|
||||
stages:
|
||||
- build
|
||||
|
||||
docker-build-rolling:
|
||||
stage: build
|
||||
image:
|
||||
name: gcr.io/kaniko-project/executor:debug
|
||||
entrypoint: [""]
|
||||
variables:
|
||||
TAG: $CI_COMMIT_BRANCH
|
||||
script:
|
||||
- cp ${DOCKER_HUB_CONFIG} /kaniko/.docker/config.json
|
||||
- /kaniko/executor --context . --dockerfile docker/production/web-server/Dockerfile --destination ${DOCKER_IMAGE_WEB_SERVER}:${TAG}
|
||||
- /kaniko/executor --context . --dockerfile docker/production/app/Dockerfile --destination ${DOCKER_IMAGE_APP}:${TAG}
|
||||
needs:
|
||||
- pipeline: $PARENT_PIPELINE_ID
|
||||
job: bundle
|
||||
only:
|
||||
refs:
|
||||
- develop
|
40
docker/production/app/Dockerfile
Normal file
40
docker/production/app/Dockerfile
Normal file
@ -0,0 +1,40 @@
|
||||
FROM docker.io/alpine:3.13 AS ffmpeg-downloader
|
||||
|
||||
RUN apk add --no-cache curl && \
|
||||
curl https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz -o ffmpeg.tar.xz && \
|
||||
tar -xJf ffmpeg.tar.xz && \
|
||||
mv ffmpeg-5.0.1-amd64-static ffmpeg
|
||||
|
||||
FROM docker.io/php:8.0-fpm-alpine3.13
|
||||
|
||||
COPY docker/production/app/entrypoint.sh /entrypoint.sh
|
||||
|
||||
COPY docker/production/app/uploads.ini /usr/local/etc/php/conf.d/uploads.ini
|
||||
|
||||
RUN echo "* * * * * /usr/local/bin/php /opt/castopod/public/index.php scheduled-activities" > /crontab.txt && \
|
||||
echo "* * * * 10 /usr/local/bin/php /opt/castopod/public/index.php scheduled-video-clips" >> /crontab.txt && \
|
||||
echo "* * * * * /usr/local/bin/php /opt/castopod/public/index.php scheduled-websub-publish" >> /crontab.txt
|
||||
|
||||
RUN apk add --no-cache libpng icu-libs freetype libwebp libjpeg-turbo libxpm ffmpeg && \
|
||||
apk add --no-cache --virtual .php-ext-build-dep freetype-dev libpng-dev libjpeg-turbo-dev libwebp-dev zlib-dev libxpm-dev icu-dev && \
|
||||
docker-php-ext-configure gd --with-freetype --with-jpeg --with-webp --with-xpm && \
|
||||
docker-php-ext-install gd intl mysqli exif && \
|
||||
docker-php-ext-enable mysqli gd intl exif && \
|
||||
apk del .php-ext-build-dep
|
||||
|
||||
COPY castopod /opt/castopod
|
||||
COPY --from=ffmpeg-downloader /ffmpeg/ffmpeg /ffmpeg/ffprobe /ffmpeg/qt-faststart /usr/local/bin/
|
||||
|
||||
RUN chmod 544 /entrypoint.sh && \
|
||||
chmod 444 /crontab.txt && \
|
||||
/usr/bin/crontab /crontab.txt
|
||||
|
||||
WORKDIR /opt/castopod
|
||||
|
||||
VOLUME /opt/castopod/public/media
|
||||
|
||||
EXPOSE 9000
|
||||
|
||||
ENTRYPOINT [ "sh", "-c" ]
|
||||
|
||||
CMD [ "/entrypoint.sh" ]
|
150
docker/production/app/entrypoint.sh
Normal file
150
docker/production/app/entrypoint.sh
Normal file
@ -0,0 +1,150 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "${CP_BASEURL}" ]
|
||||
then
|
||||
echo "CP_BASEURL must be set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "${CP_MEDIA_BASEURL}" ]
|
||||
then
|
||||
echo "CP_MEDIA_BASEURL is empty, leaving empty by default"
|
||||
fi
|
||||
|
||||
if [ -z "${CP_ADMIN_GATEWAY}" ]
|
||||
then
|
||||
echo "CP_ADMIN_GATEWAY is empty, using default"
|
||||
CP_ADMIN_GATEWAY="cp-admin"
|
||||
fi
|
||||
|
||||
if [ -z "${CP_AUTH_GATEWAY}" ]
|
||||
then
|
||||
echo "CP_AUTH_GATEWAY is empty, using default"
|
||||
CP_AUTH_GATEWAY="cp-auth"
|
||||
fi
|
||||
|
||||
if [ -z "${CP_ANALYTICS_SALT}" ]
|
||||
then
|
||||
echo "CP_ANALYTICS_SALT is empty, this is mandatory, generate a new one with tr -dc \\!\\#-\\&\\(-\\[\\]-\\_a-\\~ </dev/urandom | head -c 64"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "${CP_DATABASE_HOSTNAME}" ]
|
||||
then
|
||||
echo "CP_DATABASE_HOSTNAME is empty, using default"
|
||||
CP_DATABASE_HOSTNAME="mariadb"
|
||||
fi
|
||||
|
||||
if [ -z "${CP_DATABASE_PREFIX}" ]
|
||||
then
|
||||
echo "CP_DATABASE_PREFIX is empty, using default"
|
||||
CP_DATABASE_PREFIX="cp_"
|
||||
fi
|
||||
|
||||
if [ -z "${CP_DATABASE_NAME}" ]
|
||||
then
|
||||
if [ -z "${MYSQL_DATABASE}" ]
|
||||
then
|
||||
echo "When CP_DATABASE_NAME is empty, MYSQL_DATABASE must be set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "CP_DATABASE_NAME is empty, using mysql variable"
|
||||
CP_DATABASE_NAME="${MYSQL_DATABASE}"
|
||||
fi
|
||||
|
||||
if [ -z "${CP_DATABASE_USERNAME}" ]
|
||||
then
|
||||
if [ -z "${MYSQL_USER}" ]
|
||||
then
|
||||
echo "When CP_DATABASE_USERNAME is empty, MYSQL_USER must be set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "CP_DATABASE_USERNAME is empty, using mysql variable"
|
||||
CP_DATABASE_USERNAME="${MYSQL_USER}"
|
||||
fi
|
||||
|
||||
if [ -z "${CP_DATABASE_PASSWORD}" ]
|
||||
then
|
||||
if [ -z "${MYSQL_PASSWORD}" ]
|
||||
then
|
||||
echo "When CP_DATABASE_PASSWORD is empty, MYSQL_PASSWORD must be set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "CP_DATABASE_PASSWORD is empty, using mysql variable"
|
||||
CP_DATABASE_PASSWORD="${MYSQL_PASSWORD}"
|
||||
fi
|
||||
|
||||
if [ ! -z "${CP_REDIS_HOST}" ]
|
||||
then
|
||||
echo "Using redis cache handler"
|
||||
CP_CACHE_HANDLER="redis"
|
||||
if [ -z "${CP_REDIS_PASSWORD}" ]
|
||||
then
|
||||
echo "CP_REDIS_PASSWORD is empty, using default"
|
||||
CP_REDIS_PASSWORD="null"
|
||||
else
|
||||
CP_REDIS_PASSWORD="\"${CP_REDIS_PASSWORD}\""
|
||||
fi
|
||||
|
||||
if [ -z "${CP_REDIS_PORT}" ]
|
||||
then
|
||||
echo "CP_REDIS_PORT is empty, using default"
|
||||
CP_REDIS_PORT="6379"
|
||||
fi
|
||||
|
||||
if [ -z "${CP_REDIS_DATABASE}" ]
|
||||
then
|
||||
echo "CP_REDIS_DATABASE is empty, using default"
|
||||
CP_REDIS_DATABASE="0"
|
||||
fi
|
||||
else
|
||||
echo "Using file cache handler"
|
||||
CP_CACHE_HANDLER="file"
|
||||
fi
|
||||
|
||||
cat << EOF > /opt/castopod/.env
|
||||
app.baseURL="${CP_BASEURL}"
|
||||
app.mediaBaseURL="${CP_MEDIA_BASEURL}"
|
||||
EOF
|
||||
|
||||
if [ "${CP_DISABLE_HTTPS}" == "1" ]
|
||||
then
|
||||
echo "HTTPS redirection is disabled for test purpose, please enable it in production mode"
|
||||
echo "app.forceGlobalSecureRequests=false" >> /opt/castopod/.env
|
||||
else
|
||||
echo "HTTPS redirection is enabled by default (mandatory to federate with the fediverse), use CP_DISABLE_HTTPS=1 to disable it for test purpose"
|
||||
fi
|
||||
|
||||
cat << EOF >> /opt/castopod/.env
|
||||
admin.gateway="${CP_ADMIN_GATEWAY}"
|
||||
auth.gateway="${CP_AUTH_GATEWAY}"
|
||||
|
||||
analytics.salt="${CP_ANALYTICS_SALT}"
|
||||
|
||||
database.default.hostname="${CP_DATABASE_HOSTNAME}"
|
||||
database.default.database="${CP_DATABASE_NAME}"
|
||||
database.default.username="${CP_DATABASE_USERNAME}"
|
||||
database.default.password="${CP_DATABASE_PASSWORD}"
|
||||
database.default.DBPrefix="${CP_DATABASE_PREFIX}"
|
||||
|
||||
cache.handler="${CP_CACHE_HANDLER}"
|
||||
EOF
|
||||
|
||||
if [ "${CP_CACHE_HANDLER}" == "redis" ]
|
||||
then
|
||||
cat << EOF >> /opt/castopod/.env
|
||||
cache.redis.host="${CP_REDIS_HOST}"
|
||||
cache.redis.password=${CP_REDIS_PASSWORD}
|
||||
cache.redis.port=${CP_REDIS_PORT}
|
||||
cache.redis.database=${CP_REDIS_DATABASE}
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo "Using config:"
|
||||
cat /opt/castopod/.env
|
||||
|
||||
/usr/sbin/crond -f /crontab.txt -L /dev/stdout &
|
||||
/usr/local/sbin/php-fpm
|
5
docker/production/app/uploads.ini
Normal file
5
docker/production/app/uploads.ini
Normal file
@ -0,0 +1,5 @@
|
||||
file_uploads = On
|
||||
memory_limit = 512M
|
||||
upload_max_filesize = 500M
|
||||
post_max_size = 512M
|
||||
max_execution_time = 300
|
20
docker/production/web-server/Dockerfile
Normal file
20
docker/production/web-server/Dockerfile
Normal file
@ -0,0 +1,20 @@
|
||||
FROM docker.io/nginx:1.21-alpine
|
||||
|
||||
VOLUME /var/www/html/media
|
||||
|
||||
EXPOSE 80
|
||||
|
||||
WORKDIR /var/www/html
|
||||
|
||||
COPY docker/production/web-server/entrypoint.sh /entrypoint.sh
|
||||
|
||||
RUN chmod +x /entrypoint.sh && \
|
||||
apk add --no-cache curl
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=3s CMD curl --fail http://localhost || exit 1
|
||||
|
||||
COPY docker/production/web-server/nginx.conf /etc/nginx/nginx.conf
|
||||
|
||||
COPY castopod/public /var/www/html
|
||||
|
||||
CMD ["/entrypoint.sh"]
|
9
docker/production/web-server/entrypoint.sh
Normal file
9
docker/production/web-server/entrypoint.sh
Normal file
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
if [ -z "${CP_HOST_BACK}" ]
|
||||
then
|
||||
echo "CP_HOST_BACK is empty, using default"
|
||||
CP_HOST_BACK="back"
|
||||
fi
|
||||
|
||||
sed -i "s/CP_HOST_BACK/${CP_HOST_BACK}/" /etc/nginx/nginx.conf
|
||||
nginx -g "daemon off;"
|
76
docker/production/web-server/nginx.conf
Normal file
76
docker/production/web-server/nginx.conf
Normal file
@ -0,0 +1,76 @@
|
||||
worker_processes auto;
|
||||
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
sendfile on;
|
||||
|
||||
keepalive_timeout 65;
|
||||
|
||||
set_real_ip_from 10.0.0.0/8;
|
||||
set_real_ip_from 172.16.0.0/12;
|
||||
set_real_ip_from 192.168.0.0/16;
|
||||
real_ip_header X-Real-IP;
|
||||
|
||||
upstream php-handler {
|
||||
server CP_HOST_BACK:9000;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
root /var/www/html;
|
||||
|
||||
index index.php index.html index.htm;
|
||||
|
||||
client_max_body_size 1G;
|
||||
fastcgi_buffers 64 4K;
|
||||
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_comp_level 4;
|
||||
gzip_min_length 256;
|
||||
gzip_types application/atom+xml application/javascript audio/mpeg application/rss+xml image/bmp image/png image/jpeg image/webp image/svg+xml image/x-icon video/mp4 text/css text/plain text/html;
|
||||
|
||||
location ~ /.*\.(png|ico|txt|js|js\.map)$ {
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location ~ /(assets|media)/.*$ {
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location /.well-known/GDPR.yml {
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
location / {
|
||||
fastcgi_param SCRIPT_FILENAME /opt/castopod/public/index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_pass php-handler;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
try_files $uri =404;
|
||||
fastcgi_param SCRIPT_FILENAME /opt/castopod/public/$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_pass php-handler;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user