{"id":1870,"date":"2021-05-22T17:42:43","date_gmt":"2021-05-22T16:42:43","guid":{"rendered":"https:\/\/www.codingfriends.com\/?p=1870"},"modified":"2021-05-22T17:46:19","modified_gmt":"2021-05-22T16:46:19","slug":"docker-composer-postgres-pgadmin-nginx-php-fpm-with-different-php-versions","status":"publish","type":"post","link":"https:\/\/www.codingfriends.com\/index.php\/2021\/05\/22\/docker-composer-postgres-pgadmin-nginx-php-fpm-with-different-php-versions\/","title":{"rendered":"Docker composer &#8211; postgres \/ pgadmin \/ nginx \/ php-fpm with different php versions"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">This post is using the default docker files that have already been pre-defined, the second post will use an <a rel=\"noreferrer noopener\" href=\"https:\/\/alpinelinux.org\/downloads\/\" target=\"_blank\">alpine mini root file system<\/a> as a base and then add on the additional packages for each part of this setup.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Folder listings<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">My folder listing for the below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/nginx:\nconf.d  Dockerfile  nginx.conf  sites\n\n.\/nginx\/conf.d:\ndefault.conf\n\n.\/nginx\/sites:\ndefault.conf\n\n.\/php-fpm:\nDockerfile  xdebug.ini\n\n(extras are for the logs \/ postgres volumne mounted data)\n.\/logs\n\n.\/posgtres-data\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Enviornment file<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To start with, I like to create a env(ironment) file that will denote internal settings used within the docker file builds.  This file below will denote the php version that I wish to use and also since we are using php-fpm in this development environment, then might as well enable xdebug as well.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Below is the local.env &#8212; please save as that as well, shall include a git repo below.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PHP_VERSION=8.0\n\nPOSTGRES_PASSWORD= example\nPOSTGRES_USER= postgres\n      \nPGADMIN_DEFAULT_PASSWORD= example\nPGADMIN_DEFAULT_EMAIL=ian@codingfriends.com\n\nXDEBUG_PORT=9000<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This starts of with the PHP version, follows onto the postgres default details with also the PGADMIN default login details with the tail of the environment details having the xdebug_port defined.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Docker-composer file<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The next part is the docker-composer file, this describes how the containers will either rely on each other (depends_on within the docker composer file) networks to use and also the ports to expose.  As a side thing, I always found the ports to be funny way around so it is &lt;outside of the container&gt;:&lt;internal to the container&gt; so port 8080:80 will expose the interal port 80 (websites that aren&#8217;t using SSL run on this port for example) to the outside world on port 8080 e.g. to host you can do http:\/\/localhost:8080 to view the containers port 80 service.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Also, if you are not altering the base docker files that are being pulled down from the docker repo (shall do another post about altering this to a local repo or <a rel=\"noreferrer noopener\" href=\"https:\/\/aws.amazon.com\/ecr\/\" target=\"_blank\">AWS ECS<\/a>) then there is no build descriptions akin to the db container description below, but for php-fpm \/ nginx there are some extra build steps required for this demo hence the Dockerfile(s) in those areas.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Use postgres\/example user\/password credentials\nversion: '3.1'\n\nservices:\n\n  db:\n    image: postgres\n    restart: always\n    hostname: postgresDB\n    container_name: postgresDB\n    environment:\n      POSTGRES_PASSWORD: $POSTGRES_PASSWORD\n      POSTGRES_USER: $POSTGRES_USER\n    volumes:\n      - .\/postgres-data:\/var\/lib\/postgresql\/data\n    ports:\n      - 5432:5432\n    networks:\n      - iKnowNW\n\n  pgdamin4:\n    image: dpage\/pgadmin4\n    hostname: pgadmin4\n    container_name: pgadmin4\n    depends_on:\n      - db \n    restart: always\n    environment:\n      PGADMIN_DEFAULT_PASSWORD: $PGADMIN_DEFAULT_PASSWORD\n      PGADMIN_DEFAULT_EMAIL: $PGADMIN_DEFAULT_EMAIL\n    ports:\n      - 8080:80\n    networks:\n      - iKnowNW\n\n  php-fpm:\n    build:\n      context: .\/php-fpm\n      args:\n          - PHP_VERSION=${PHP_VERSION}\n          - XDEBUG_PORT=${XDEBUG_PORT}\n    depends_on:\n      - db\n    environment:\n      - XDEBUG_CONFIG=client_port=${XDEBUG_PORT}\n    volumes:\n      - ..\/src:\/var\/www\n      - .\/logs:\/var\/logs\n      - .\/php-fpm\/xdebug.ini:\/usr\/local\/etc\/php\/conf.d\/xdebug.ini\n    networks:\n      - iKnowNW      \n\n  nginx:\n    build: \n      context: .\/nginx\n    volumes:\n      - ..\/src:\/var\/www\n      - .\/nginx\/nginx.conf:\/etc\/nginx\/nginx.conf\n      - .\/nginx\/conf.d\/:\/etc\/nginx\/conf.d\n      - .\/nginx\/sites\/:\/etc\/nginx\/sites-available\n      - .\/logs:\/var\/log\n    depends_on:\n      - php-fpm\n    ports:\n      - 8081:80\n    networks:\n      - iKnowNW        \n\nnetworks:\n  iKnowNW:\n      driver: bridge<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">PHP-FPM<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">So the main things are within the php-fpm confirguration above <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">args:<br>&#8211; PHP_VERSION=${PHP_VERSION})<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">environment:<br>&#8211; XDEBUG_CONFIG=client_port=${XDEBUG_PORT}<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Both of these are import, because they will pass details (arguments \/ enviornment variables) to the php-fpm DockerFile build process, so lets start with that &#8212; below is the php-fpm Dockerfile<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\nARG PHP_VERSION\nARG XDEBUG_PORT \n\nFROM php:${PHP_VERSION}-fpm-alpine\n\nRUN apk --update --no-cache add git postgresql-dev\nRUN apk add --no-cache $PHPIZE_DEPS\nRUN pecl install xdebug \nRUN docker-php-ext-install pdo pdo_pgsql \nRUN docker-php-ext-enable xdebug\n\nWORKDIR \/var\/www\nEXPOSE ${XDEBUG_PORT}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">So the ARG variable is what was passed in from the docker-composer file within this instance it would be 8.0 denoting the php version to use.  Also with exposing the xdebug port to the outside world of the container.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Additional xdebug settings are included in the xdebug.ini file below, this will be &#8220;copied&#8221; into the container during the build process.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>xdebug.start_with_request=yes\nxdebug.mode=debug\nxdebug.log=\/var\/logs\/xdebug\/xdebug.log\nxdebug.discover_client_host=1<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Nginx<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This one is the biggest folder, as the following steps will take place<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Insert the nginx.conf file &#8212; this is the service configuration  &#8212; into the container<\/li><li>Insert the default site configuration that uses the php-fpm container using the fast cgi protocol.<\/li><li>Insert the configuration of the php-upstream of the php-fpm container<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Lets start with the nginx.conf file, it just describes the nginx service with connections \/ logs and where the http configurations are placed etc.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>user  nginx;\nworker_processes  4;\ndaemon off;\n\nerror_log  \/var\/log\/nginx\/error.log debug;\npid        \/var\/run\/nginx.pid;\n\nevents {\n    worker_connections  1024;\n}\n\n\nhttp {\n    include       \/etc\/nginx\/mime.types;\n    default_type  application\/octet-stream;\n    access_log  \/var\/log\/nginx\/access.log;\n    sendfile        on;\n    keepalive_timeout  65;\n\n    include \/etc\/nginx\/conf.d\/*.conf;\n    include \/etc\/nginx\/sites-available\/*.conf;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The default.conf is the default site, as from above it is placed into the \/etc\/nginx\/sites-available folder.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server {\n    listen 80 default_server;\n    listen &#91;::]:80 default_server ipv6only=on;\n\n    server_name localhost;\n    root \/var\/www\/public;\n    index index.php index.html index.htm;\n\n    location \/ {\n         try_files $uri $uri\/ \/index.php$is_args$args;\n    }\n\n    location ~ \\.php$ {\n        try_files $uri \/index.php =404;\n        fastcgi_pass php-upstream;\n        fastcgi_index index.php;\n        fastcgi_buffers 16 16k;\n        fastcgi_buffer_size 32k;\n        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n        fastcgi_read_timeout 600;\n        include fastcgi_params;\n    }\n\n    location ~ \/\\.ht {\n        deny all;\n    }\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The most important part here is the &#8220;root&#8221; key value pair above, this is where the local php folder needs to be mounted for the site to work.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The last part is php-fpm upstream service (conf.d\/default.conf)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>upstream php-upstream {\n    server php-fpm:9000;\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Literally, the php-fpm value above matches the container name from the docker-compose file above.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And then the actually Dockerfile is very small!!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>FROM nginx:alpine\nWORKDIR \/var\/www\nCMD &#91;\"nginx\"]\nEXPOSE 80<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Literally describing where to get the nginx base container from e.g. nginx repository with the tag of alpine.  Then define the WORKDIR (working directory) for where a container is &#8220;cd&#8221; into for the command (CMD) to be executed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Final part!<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create the subdirectories<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>logs<\/li><li>postgres-data<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">To store the containers data that isn&#8217;t lost after the container has been stopped \/ killed (containers are in theory ephemeral &#8212; short existence)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Last step is to run the build process and then view your code that you have within your ..\/src directory (this is where the PHP hosting code will be &#8212; I am using the a sub folder within there called public e.g. ..\/src\/public\/ will be where the website viewable code controllers etc after a symfony creation script)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To view the PGADMIN page &#8212; just goto <a rel=\"noreferrer noopener\" href=\"http:\/\/localhost:8080\/\" target=\"_blank\">http:\/\/localhost:8080\/<\/a> <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To view the PHP hosting code &#8212; just goto <a href=\"http:\/\/localhost:8081\/\" target=\"_blank\" rel=\"noreferrer noopener\">http:\/\/localhost:8081\/<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Have fun &#8212; if there are any issues, please contact me!! but here is my start.sh script to either build \/run the container setup above.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#\/bin\/bash\n## place your local enviornment file name here\nENV=local.env\n\ncase \"$1\" in \nstart)\n   echo \"STARTING\"\n   docker-compose --env-file=$ENV -f docker-compose.yml up\n   ;;\nstop)\n   echo \"STOPPING\"\n   docker-compose --env-file=$ENV -f docker-compose.yml down\n   ;;\nrestart)\n   $0 stop\n   $0 start\n   ;;\nrebuild)\n   echo \"REBUILD\"\n   docker-compose --env-file=$ENV -f docker-compose.yml up --build\n   ;;\nupgarde)\n   echo \"UPGRADING CONTAINERS\"\n   docker-compose pull\n   ;;\n\n*)\n   echo \"Usage: $0 {start|stop|rebulid|upgrade}\"\nesac\n\nexit 0 <\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This post is using the default docker files that have already been pre-defined, the second post will use an alpine mini root file system as a base and then add on the additional packages for each part of this setup. Folder listings My folder listing for the below. Enviornment file To start with, I like &hellip; <a href=\"https:\/\/www.codingfriends.com\/index.php\/2021\/05\/22\/docker-composer-postgres-pgadmin-nginx-php-fpm-with-different-php-versions\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Docker composer &#8211; postgres \/ pgadmin \/ nginx \/ php-fpm with different php versions<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[415,416],"tags":[],"class_list":["post-1870","post","type-post","status-publish","format-standard","hentry","category-containers","category-docker"],"_links":{"self":[{"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/posts\/1870","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/comments?post=1870"}],"version-history":[{"count":4,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/posts\/1870\/revisions"}],"predecessor-version":[{"id":1875,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/posts\/1870\/revisions\/1875"}],"wp:attachment":[{"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/media?parent=1870"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/categories?post=1870"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/tags?post=1870"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}