I am trying to setup a development environment for upgrading old php applications with docker. I've tried to create a docker-compose.yml file with the following content:
version: "3"
services:
mysql:
image: mysql:5.7
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=dev
- MYSQL_USER=dev
- MYSQL_PASSWORD=dev
- MYSQL_DATABASE=todo
volumes:
- ./storage/mysql:/var/lib/mysql
nginx:
image: nginx:latest
ports:
- "8080:80"
volumes:
- ./../src:/var/www
- ./site.conf:/etc/nginx/conf.d/site.conf
links:
- php
php:
image: tommylau/php-5.2
volumes:
- ./../src:/var/www
depends_on:
- mysql
There may be additional issues within my yml file but at first i'm facint two problems here:
1) what about links?
when using
$ docker stack deploy -c docker-compose.yml phpdev
i'm getting the following output saying the links option is unssupported and i don't see why
Ignoring unsupported options: links
Creating network phpdev_default
Creating service phpdev_nginx
Creating service phpdev_php
Creating service phpdev_mysql
2) nothing on localhost:8080
any hints on solving my two problems?
Related
I want to preface this by saying this question is more about system design and is somewhat open-ended. There isn't anything, in particular, I need help with. But I would appreciate some guidance. I will provide a copy of my docker-compose.yml so it's easier to visualize what I'm working with.
I'm looking to dockerize an older LAMP stack application. This app is currently deployed in a CentOS 6.10 VM, running PHP 5.4, MySQL 5.7, and Apache 2.2.15.
I wonder how I might go about dockerizing while minimizing the number of modifications I have to make to the underlying codebase.
I was playing with aliasing deprecated functions and redefining them with an updated API, but, it's been quite the hassle. Here's an example:
if (!function_exists('mysql_num_rows')) {
function mysql_num_rows($result)
{
return mysqli_num_rows($result);
}
}
Here's my docker-compose.yml:
version: "3.8"
x-common-variables: &common-variables
MYSQL_ROOT_PASSWORD: root
MYSQL_USER: ...
MYSQL_PASSWORD: ...
volumes:
mysql:
driver: local
services:
mysql:
platform: linux/x86_64
image: mysql:5.7
container_name: mysql_container
environment:
<<: *common-variables
ports:
- 3306:3306
restart: unless-stopped
volumes:
- mysql:/var/lib/mysql
- ./docker/init.sql:/docker-entrypoint-initdb.d/init.sql
phpmyadmin:
depends_on:
- mysql
image: phpmyadmin:latest
container_name: phpadmin_container
environment:
<<: *common-variables
PMA_HOST: mysql
links:
- mysql:mysql
ports:
- 8080:81
restart: always
apache:
container_name: apache_container
depends_on:
- mysql
build: ./bootstrap
environment:
<<: *common-variables
extra_hosts:
- "app1.localhost.com:127.0.0.1" # This is configured in local hosts file
- "app2.localhost.com:127.0.0.1"
ports:
- 443:443 # App requires SSL - using a self-signed cert locally
- 80:80
volumes:
- ./bootstrap/httpd.conf:/etc/apache2/sites-enabled/000-default.conf
- ./bootstrap/php.ini:/usr/local/etc/php/php.ini
- ./:/var/www
links:
- mysql:mysql
I'm using the php:7.4-apache image for the apache service (not shown here, it's in the Dockerfile).
As I was writing this question, I realized I could probably use a centos image and install the older versions of software required for the project. However, I'm still going to post because any insight would be helpful.
Let me know if there's any more info I can provide!
Can someone please help.
I was running successfully my Symfony project via Docker containers. Suddenly when I access http://localhost/ I get the File not found. error?
I now that it means that system can not locate my files, but I am not sure what happened.
I see that my containers are built and running okay.
Also the same message I get when I try to test app endpoints through Postman.
I am on Mac Monterey 12.4.
Everything was working fine couple of hours ago. I just switched branches to change something, then switched back. The problem was on both branches..
Can someone help, I do not know what to do?
Docker config:
services:
db:
image: postgres:${POSTGRES_VERSION:-12}-alpine
environment:
POSTGRES_DB: ${POSTGRES_DB:-name}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-pass}
POSTGRES_USER: ${POSTGRES_USER:-postgres}
volumes:
- $PWD/postgres-data:/var/lib/postgresql/data:rw
profiles:
- db-in-docker
ports:
- "5432:5432"
networks:
- symfony
redis:
image: "redis:alpine"
command: redis-server /usr/local/etc/redis/redis.conf
ports:
- "6379:6379"
volumes:
- $PWD/redis-data:/var/lib/redis
- $PWD/redis/redis.conf:/usr/local/etc/redis/redis.conf
environment:
- REDIS_REPLICATION_MODE=master
networks:
- symfony
php:
container_name: "backend_php"
build:
context: ..
dockerfile: docker/php/Dockerfile
target: dev
args:
TIMEZONE: ${TIMEZONE}
volumes:
- symfony_docker_app_sync:/var/www/symfony/
depends_on:
- redis
networks:
- symfony
nginx:
build:
context: ./nginx
volumes:
- ../:/var/www/symfony/
ports:
- 80:80
depends_on:
- php
networks:
- symfony
env_file:
- .env.nginx.local
First of all: Why do you donĀ“t use the built in symfony server for local development? However - how looks your docker container configuration for your webserver?
Can a services running in two different docker stack communicate ?
This is what I have tried and not able to achieve it.
Created a stack (stack1) running nginx and php-fpm its running great.
Created another stack (stack2) running mysql database.
Now I want to make the stack1 service able to communicate with stack2 such that it can access the database service.
I though this might help and created a external network and trying to
add the service in stack1 and stack2 to it such that they can
communicate with each others too
Mystack1 docker-compose file
version: "3.4"
networks:
apps-net:
db-net:
external:
name: db-net
services:
web:
image: nginx:latest
ports:
- "9080:80"
volumes:
- ./code:/code
- ./site.conf:/etc/nginx/conf.d/default.conf
depends_on:
- php
networks:
- apps-net
- db-net
deploy:
mode: replicated
replicas: 1
php:
image: php:7-fpm
volumes:
- ./code:/code
networks:
- apps-net
- db-net
deploy:
mode: replicated
replicas: 1
MY stack2 docker-compose file
version: '3.3'
networks:
db-net:
external:
name: db-net
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: wordpress
MYSQL_USER: root
MYSQL_PASSWORD: password
networks:
- db-net
volumes:
db_data:
I created a swarm scope network with docker network create db-net command
OUTPUT:
The nginx and php is working fine but I added the database connection
codes in the index.php which resulted in error message.Is the error
because they are not connected? I have installed php-mysql extensions
too but it has the error. How can I make sure the services are
communicating successfully.
nginx and php working
Fatal error: Uncaught Error: Call to undefined function mysqli_connect() in /code/index.php:11 Stack trace: #0 {main} thrown in /code/index.php on line 11
Instead of networks (which I often see asked here on stack as not working like expected) try using external_links which is well explained here.
Try removing all custom network configurations and simply modify your application compose file like this:
version: "3.4"
# removed all custom networks configuration
services:
web:
image: nginx:latest
external_links:
- mysql_1:mysql
[..]
php:
image: php:7-fpm
external_links:
- mysql_1:mysql
[..]
where mysql_1 is a actual container name create by your latter compose file, and mysql is a alias by which your service will be available inside php and web containers
Links are a legacy option in v3 and Docker suggests using networks instead.
I'll post a edit about swarm deployment as approach would be totally different because Docker ignores links when deploying swarm.
Since volumes_from disappear when Docker Compose change it's compose file version I am a bit lost in how to share a volume between different containers.
See the example below where a PHP application is living in a PHP-FPM container and Nginx is living in a second one.
version: '3.3'
services:
php:
build:
context: ./docker/php7-fpm
args:
TIMEZONE: ${TIMEZONE}
env_file: .env
volumes:
- shared-volume:/var/www
nginx:
build: ./docker/nginx
ports:
- 81:80
depends_on:
- php
volumes:
- shared-volume:/var/www
volumes:
shared-volume:
driver_opts:
type: none
device: ~/sources/websocket
o: bind
In order to make the application works of course somehow Nginx has to access the PHP files and there is where volumes_from help us a lot. Now that option is gone.
When I try the command docker-compose up it ends with the following message:
ERROR: for websocket_php_1 Cannot create container for service php:
error while mounting volume with options: type='none'
device='~/sources/websocket' o='bind': no such file or directory
How do I properly share the same host volume between the two containers?
Why would you not use a bind mount? This is just source code that each needs to see, correct? I added the :ro (read-only) option which assumes no code generation is happening.
services:
php:
build:
context: ./docker/php7-fpm
args:
TIMEZONE: ${TIMEZONE}
env_file: .env
volumes:
# User-relative path
- ~/sources/websocket:/var/www:ro
nginx:
build: ./docker/nginx
ports:
- 81:80
depends_on:
- php
volumes:
# User-relative path
- ~/sources/websocket:/var/www:ro
At the moment I'm building my own dev environment because I want to get rid of MAMP.
I created a docker-compose file with a nginx proxy and it's basically working. My problem is, that several old php projects require different php versions.
Here is how far I already got with my compose file:
version: '2'
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
project1:
build: ./config/5.3.29/nginx/
container_name: project1
volumes:
- ./project1/:/var/www/html
links:
- php-5.3.29:php
environment:
- "VIRTUAL_HOST=project1.org"
expose:
- "8080"
project2:
build: ./config/5.6/nginx/
container_name: project2
volumes:
- ./project2/:/var/www/html
links:
- php-5.6:php
environment:
- "VIRTUAL_HOST=project2.de"
expose:
- "8081"
php-5.3.29:
build: ./config/5.3.29/php/
container_name: php-5.3.29
ports:
- 9000:9000
php-5.6:
build: ./config/5.6/php/
container_name: php-5.6
ports:
- 9001:9000
As you can see, I have two projects. The PHP containers require to volume from the the same path as the project does. Is there a way to generate the path dynamically? Project 3 will also use php 5.6.
Or am I using the wrong way to go in general? In the end there will be around 10 Magento online shops.
Thank you for your help!
Thank you for your answer!
Today I was able to solve my problem with this docker-compose file:
version: '2'
services:
nginx:
build: ./config/nginx/
container_name: nginx
volumes_from:
- www_data
links:
- php-5.3.29
- php-5.5
ports:
- 80:80
php-5.3.29:
build: ./config/5.3.29/
container_name: php-5.3.29
volumes_from:
- www_data
php-5.5:
build: ./config/5.5/
container_name: php-5.5
volumes_from:
- www_data
php-5.6:
build: ./config/5.6/
container_name: php-5.6
volumes_from:
- www_data
www_data:
image: tianon/true
volumes:
- .:/var/www/html
I removed the proxy and used the nginx config to handle the different websites. Then I was able to include the different php versions like this:
fastcgi_pass php-5.5:9000;
You can reference directories above the compose file like ../sites:/var/www/html or similar. Not sure when you say "dynamically" if you need additional logic to generate the paths.
In general it seems like your naming is a bit too specific, which might be fine for an initial workstation, but as things start to change, it's going to be harder to maintain.