Install Apache + PHP + MySQL via Docker

So..  I understand how to install each of these as separate containers..  This means I can start and stop each container, however, I would prefer all three of these be in one container.. Is that possible?  I plan to spin up a custom .php web app using it's dedicated mySQL instance.. I'll end up with 3 or 4 of these on the same Docker host..  Each having different php versions and mysql versions...  How can I do this?
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Pallavi GodseSr. Digital Marketing ExecutiveCommented:
Here's how you can install Apache + PHP + MySQL via Docker -

Hope this will help you.
David FavorLinux/LXD/WordPress/Hosting SavantCommented:
Use LXD. That's the difference between LXD + Docker.

I host 100s of client sites in LXD containers.

Each container is a separate bootable OS install. I use Ubuntu at machine level + container level, because LXD development use Ubuntu, so questions about Ubuntu have instantly known answers, from deep experience by developers.

Just spin up an LXD container + install your OS + LAMP Stack + your done.

Here's my container level install sequence. Using the ondrej PPAs, you can install PHP versions 5.6 + 7.0 + 7.1 + 7.2 simultaneously + just switch between them as you like.

# Container level
apt-get -y install software-properties-common
add-apt-repository ppa:ubuntu-lxc/lxd-stable < /dev/null

# Setup latest stable
LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/php </dev/null
LC_ALL=C.UTF-8 add-apt-repository ppa:ondrej/apache2 </dev/null

add-apt-repository ppa:pdoes/dovecot </dev/null

apt-key adv --recv-keys --keyserver hkp:// 0xF1656F24C74CD1D8
echo "deb [arch=amd64,i386] $(lsb_release -sc) main" > /etc/apt/sources.list.d/mariadb-$(lsb_release -sc).list

# Freshen local package caches
apt-get update
# Ensure latest versions correct
apt-cache policy apache2 php7.1 mariadb-server dovecot-core openssl

# Ensure fail2ban is running
apt-get install fail2ban

# Install LAMP
apt-get purge libapache2-mod-php7.1

apt-get install mariadb-server mariadb-client libmysqlclient-dev

apt-get install php7.1-fpm php7.1-cli php7.1-mbstring php7.1-zip \
                php7.1-mysql php7.1-curl php7.1-xml php7.1-xmlrpc php7.1-gd php7.1-soap \
                php7.1-sqlite3 php7.1-mcrypt php7.1-tidy php7.1-xsl php7.1-bz2 php7.1-gmp \
                php7.1-tidy php7.1-bcmath php7.1-bz2 php7.1-dba php7.1-pspell \
                php-xdebug libphp7.1-embed

# update PHP CLI, when multiple versions installed
update-alternatives --set php /usr/bin/php7.1
# Ensure HTTP2 working + FPM overrides an previous libapache2-mod-$ver installation
apt-get install apache2
a2dismod mpm_prefork cgi
a2enmod mpm_event proxy_fcgi setenvif alias cgid ssl http2 expires headers include rewrite
# handle /etc/apache2/mods-available/expires.conf
a2enconf php7.1-fpm
apachectl -t && service apache2 restart

# tune: opcache.ini + xdebug.ini
cd /etc/php/7.1/mods-available

# tune: FPM Pool
cd /etc/php/7.1/fpm/pool.d

# restart
service php7.1-fpm restart

Open in new window

This approach allows you to for example, install 5.6 + 7.1 + run with 5.6 using phpcs to clean up 7.1 incompatibilities + then switch to 7.1 to test + revert back, if testing fails.

You can also just clone a copy of a container + do similar work.

Makes upgrading old code very easy... with no production server downtime.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
gopher_49Author Commented:
Ok.. So..  A LXD container is basically a VM.  My host (Ubuntu 17.04 VM) becomes a hypervisor..  Once I have LXD containers spun up I can utilize it like a traditional VMs or even use docker in each LXD container / VM if desired?  That is amazing..  That is EXACTLY what I want..  The problem with traditional Docker containers is that they share the host IP address..  So.. Each MySQL instance will need a custom port mapping which gets messy..  I need the ability to have different IPs that are in different VLANs and IP networks..  So..  How would I accomplish that?  How do I control which vNIC is presented to the LXD container?  By default it uses shared bridge mode which defaults to the same network as my host.. Which typically is fine.. But.. Can I present a NIC to my host VM via ESXi and in return present it to the LXD environment?  So.. I assign the NIC from the host VM's setting in ESXi and pass that to the LXD container..  That way I can easily present all of the network / VLANs in my ESXi environment to my LXD environment and then assign them one by one to its respective container?
Acronis True Image 2019 just released!

Create a reliable backup. Make sure you always have dependable copies of your data so you can restore your entire system or individual files.

gopher_49Author Commented:
David Favor,

How do I set a static IP to my LXD container?
David FavorLinux/LXD/WordPress/Hosting SavantCommented:
LXD Networking GitHub Issue provides definitive guide for Ubuntu Zesty + below.

Artful + above is a completely different beast, as networking has changed from classic to netplan.

How you do this in LXD depends on container OS you're running. For Zesty + below, do something like the following...

1) Inside container. Change /etc/network/interfaces to this...

# Loopback
auto lo
iface lo inet loopback

# DHCP container to host connector
auto eth0 
iface eth0 inet dhcp 

# Public IP
auto eth0:1
iface eth0:1 inet static
    address IP

Open in new window

2) At machine level, route packets. By arranging for the following to run at reboot time, so /etc/rc.local or however you do this. Also, ensure this runs again after each LXD package update, as some types of package updates destroy routing.

ip -4 route add IP/mask dev lxdbr0 || /bin/true

Open in new window

The exact IP/mask you use will come from your hosting company. You'll run an ip command for every unique IP range on your machine.

So if you have 3 IP blocks, then you'll have 3 ip commands to run at reboot + LXD package update time.
gopher_49Author Commented:
I'm running Ubuntu 17.04..  I ended up doing the below to make it work.. Keep in mind my Ubuntu LXD host is a VM behing a firewall.. It's nested on ESXi as a VM..  It has a private IP on it's NIC and will be using private IP networks that I plan to have profiles associated per container..  Each container might be in different VLANs.. But..  I won't have to deal with VLANs tagging for the NIC will be untagged in that respective VLAN.  I'll simply use a dedicated NIC per VLAN.  Maybe your method is better?  Mine seems to work really well.. I'm also looking into OpenVSwitch.

On the LXD container changed the NIC to bridge mode via /etc/network/interfaces

changed the NIC to have:

# bridge interface - default NIC was called ens160 before.  Sometimes it's called eth0..
auto br0
iface br0 inet static
        bridge-ifaces ens160
        bridge-ports ens160
        up ifconfig ens160 up
iface ens160 inet manual

Then on the LXD host ran:

lxc profile edit default

Then find the old lxcbr0 and change to br0

On the LXC container ran this..

sudo nano /etc/network/interfaces.d

add static IP such as:

# The primary network interface - commented out for used bridge above
auto eth0
iface eth0 inet static

David FavorLinux/LXD/WordPress/Hosting SavantCommented:
And this worked?
gopher_49Author Commented:
Yes..  I statically assigned a internal IP to a container...  This being an Ubuntu 17.04 container.. It's able to access my LAN and I can access it..  There is no NAT or DHCP server anymore it's using my br0 interface that I created which placed it right on our LAN...  I converted my traditional NIC into a bridge NIC.  I'm thinking I'll create a series of bridge adapters .  Each in a different VLAN / IP Network...
David FavorLinux/LXD/WordPress/Hosting SavantCommented:
gopher_49Author Commented:
I'll try my different VLAN / IP bridged adapters setup in a bit.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.