Why Does PHP Return “Resource Id #2” Or “Resource Id #3”?

Problem scenario
In a LAPP stack deployment, a PHP variable is displaying a value "Resource id #2" or "Resource id #3."  You are expecting a different value.  The PHP variable having the problem is the result of a SQL command ran against a PostgreSQL database.  What should you do?

Solution
Assuming that $var1 is displaying the undesirable "Resource id #2" or "Resource id #3", do something like this:

   $var1 = pg_query($query);
   $rowa = pg_fetch_row($var1);
   $rowb = current($rowa);

Now use $rowb in the capacity you were trying to use $var1.  It should display a human readable value.

How Do You Troubleshoot “docker attach” Commands That Hang?

Problem scenario
You are using RedHat Linux in AWS.  You have installed Docker and have a running container.  You notice that "docker attach <docker ID>" commands are hanging.  What do you to get inside the container?

Solution
Use "docker ps -a" to find the Docker container's name.  Then use a modified version of this draft of a command:

docker exec -it docker-name bash

#Replace "docker-name" above with the name of the Docker container as found from a "docker ps -a"command.

How Do You Edit Text inside a Docker Container?

Problem scenario
The server you have is a RHEL (RedHat Enterprise Linux) or Ubuntu instance.  You are in a Docker container that you pulled from the internet for Nginx.  Inside this Docker container you cannot use vi because it is not a recognized command.  What do you do to install a text editor in the Docker container?

Solution for non-SUSE Linux
#1  Inside the Docker container, even if the server is a RedHat or SUSE distribution, run these two commands:
apt-get -y update
apt-get -y install vim

#2  Ignore errors like these if they appear:

"update-alternatives: warning: skip creation of /usr/share/man/ru/man1/editor.1.gz because associated file /usr/share/man/ru/man1/vim.1.gz (of link group editor) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/ja/man1/editor.1.gz because associated file /usr/share/man/ja/man1/vim.1.gz (of link group editor) doesn't exist
update-alternatives: warning: skip creation of /usr/share/man/man1/editor.1.gz because associated file /usr/share/man/man1/vim.1.gz (of link group editor) doesn't exist"

#3  Now vi should work.  You can use a semicolon between the above two commands and press enter only once (e.g., "apt-get update; apt-get -y install vim").

Solution for SUSE Linux
In our experience, apt-get commands will not work in a Docker container from a SUSE Docker host.

Step #1  Download four .deb files:
curl http://security.debian.org/debian-security/pool/updates/main/v/vim/vim_7.3.547-7+deb7u4_amd64.deb > vim_7.3.547-7+deb7u4_amd64.deb
curl http://security.debian.org/debian-security/pool/updates/main/v/vim/vim-common_7.3.547-7+deb7u4_amd64.deb > vim-common_7.3.547-7+deb7u4_amd64.deb
curl http://security.debian.org/debian-security/pool/updates/main/v/vim/vim-runtime_7.3.547-7+deb7u4_all.deb > vim-runtime_7.3.547-7+deb7u4_all.deb
curl http://ftp.us.debian.org/debian/pool/main/g/gpm/libgpm2_1.20.4-6_amd64.deb > libgpm2_1.20.4-6_amd64.deb

Step #2  Find the Docker container ID that you want to have a text editor.  To do this, run this command:  docker ps -a

Step #3  Copy the .deb files into the Docker container.  In the below commands replace <containerID> with the alphanumeric container ID as found in the above command.

docker cp vim_7.3.547-7+deb7u4_amd64.deb <containerID>:/tmp/vim_7.3.547-7+deb7u4_amd64.deb
docker cp vim-common_7.3.547-7+deb7u4_amd64.deb <containerID>:/tmp/vim-common_7.3.547-7+deb7u4_amd64.deb
docker cp vim-runtime_7.3.547-7+deb7u4_all.deb <containerID>:/tmp/vim-runtime_7.3.547-7+deb7u4_all.deb
docker cp libgpm2_1.20.4-6_amd64.deb <containerID>:/tmp/libgpm2_1.20.4-6_amd64.deb

Step #4  Enter the Docker container by running a command like this:  docker exec -it <containerID> bash

Step #5  Install the four .deb packages
cd /tmp/
dpkg -i *.deb

How Do You Get Nginx in a Docker Container to Log Web Server Activity to a Regular File inside the Container?

Problem scenario
Normally the Nginx web service logs operations (e.g., a user going to a website with a web browser).  By default Nginx Docker containers do not have good logging for web server usage.  You want regular Nginx logging inside the Docker container.  What do you do?

Solution
1.  Go inside the Docker container (e.g., docker exec -it <containerName> bash).  Go to /etc/nginx/

2.  Modify the nginx.conf file.  Find the "access_log" and "error_log" stanzas.  Change the file name to a file that does not yet exist.  Keep the location (/var/log/nginx/) the same in the stanzas.

3.  Restart the Docker container.  

4.  Now you will get regular logging of Nginx activity in the Docker container (e.g., someone accesses the web services from the front end, e.g., opening a web browser and going to the web page that the Nginx in Docker container supports).

“No Day Shall Erase You From the Memory of Time”

While this quote from Virgil's Aeneid is controversial in its 9/11 Museum usage, it is an interesting idea that people may be remembered no matter what happens in the future.

On Patriot Day, also known as the National Day of Service and Rememberance, we have the opportunity to reflect on Americans who have given the full measure of devotion to our country.  The United States of America is a great country with the greatest technology companies in the world.  We recommend everyone make one trip to the 9/11 Museum in his/her lifetime.  To learn more about the terrorist attacks, you may want to read The National Commission's authorized report.

How Do You Find the IP Address Assigned to a Docker Container When It Was Created?

Problem scenario
You have inherited several Docker containers to manage.  They were assigned IP addresses and assigned user-defined networks when they were created.  You do not know what IP addresses that they were given.  You want to know the IP addresses so you can add them to a load balancer.  The external IP address of the Docker host combined with identifying port numbers of the containers can create sockets that are unique.  But you want the internal IP addresses of each of the Docker containers.  How do you find them?

Solution
Run a command like this but substitute "8debfc9b4c32" for the container ID as found in the results of a "docker ps -a" command:

docker inspect 8debfc9b4c32 | grep IPAddress | tail -n 1

How Do You Troubleshoot the Docker Error “User specified IP address is supported only when connecting to networks with user configured subnets.”?

Problem scenario
You are trying to create a Docker image and assign it an IP address with the --ip flag. But you get this error: "/usr/bin/docker-current: Error response from daemon: User specified IP address is supported only when connecting to networks with user configured subnets."  How do you get your Docker command to work and resolve this problem?

Solution
#1  From the Linux server, run this command:  ip addr show

#2  Look at the results for eth0.  Find its "inet" IP address and subnet mask (e.g., 172.31.38.151/20). This is the internal IP address of the Docker server and its subnet mask in shorthand notation.  To determine the IP address of this Docker network you will create, mentally increment the last octet's integer value by 1 and keep the subnet mask for the construction of a command below.  If the calculated number is above 255, find an addressable IP number not being used and within the subnet mask for the server's IP address.

#3  Run a command like the following, however you may want to substitute "isolated_nw1" with the name of your choice for this user-defined network.  You must substitute x.x.x.x in the draft of the command below with the IP address this network will have (possibly as simple as one greater than the last octet of the server's internal IP address).  You will likely substitute 20 with the subnet mask short hand notation that the server's internal IP address has.  

docker network create --driver bridge isolated_nw1 --subnet x.x.x.x/20

The result may look like this:

docker network create --driver bridge isolated_nw1 --subnet 172.31.38.152/20

Take a note of this IP address and mentally increment the last octet one more time.  You'll use that IP address later for a Docker container.  But now you should have a user-defined Docker network with a subnet mask.

How to Do You Install Apache Tomcat on Ubuntu Linux?

Problem scenario
You want to install Apache Tomcat on Ubuntu Linux.  How do you do this?

Solution
There are three separate ways of doing this.
Possible solution #1: Run this command: sudo apt-get -y install tomcat8
Possible solution #2: See this posting.
Possible solution #3:  Use these directions with one modification:  Step #3 has a URL that needs to be replaced with this URL:  http://apache.mirrors.ionfish.org/tomcat/tomcat-8/v8.5.58/bin/apache-tomcat-8.5.58.tar.gz

How Do You Deploy Apache Tomcat in a Docker Instance in an AWS Ubuntu Linux Server?

Problem scenario
You want to deploy Apache Tomcat in a Docker container on an AWS instance of Ubuntu Linux.  How do you do this?

Solution
1.  Install Docker.  See this link if you need assistance.
2.  Start the Docker service with this command:  sudo service docker start
3.  Run these two commands:

docker pull consol/tomcat-8.0
docker run consol/tomcat-8.0

4.  The second of the above commands will appear to hang.  Start a new Putty session to the Ubuntu server.  Continue with the directions below and leave both Putty instances up.

docker ps -a  #get the alphanumeric Docker container ID
docker inspect -f format='{{.NetworkSettings.IPAddress}}' abcd1234

#where abcd1234 is the container ID found above

# Note the IP address of the second of the above commands  You will use it again soon.

5.  Optional step if you want to use the web UI of Tomcat.  Create a second Docker container with Nginx inside it, and configure Nginx as a load balancer to distribute traffic to the Tomcat instance.  Follow these directions if you want to do this.  For step #6.d. in those directions refers to IP addresses where you want the traffic to go to.  You will have one IP address to add in the upstream block.  It will appear after the word "server", and it will be a socket for the IP address obtained in step #4 above with a :8080 at the end.  For example, step 6.d. in the Nginx in a Docker Container as an HTTP Load Balancer directions will leave you with something like this at the end of the default.conf file:

upstream {
   server 172.17.0.2:8080;
}

6.  Optional step if you did step #5 above.  You'll need to stop and start the Nginx Docker container for it to take effect.  Test it by opening a web browser and going to the external IP address of the server with these docker containers.  To find this, on the back-end of the server and outside of a Docker container, run the command "curl http://icanhazip.com".  Open a web browser on a desktop that has access to this server, and go to the IP address obtained from the curl command above.

How Do You Configure Nginx in a Docker Container to Be an HTTP Load Balancer?

Updated on 11/7/17

Problem scenario

You want a computer server (e.g., an AWS instance) to be a reverse proxy (a type of landing page users do not see that acts as a portal).  You want it to relay traffic to other IP addresses.  How do you get a server with Docker to distribute traffic to other IP endpoints?

Solution
Prerequisites
This assumes that Docker has already been installed.  To install Docker on RedHat, see this link.  To install Docker on Ubuntu, see this link.  To install Docker on Linux SUSE, run this command "sudo zypper -n in docker".  If you need more directions for installing Docker, see this posting.

The caveat with Docker on Ubuntu (as of 9/6/17) is that the web servers on the back end must not be other Nginx instances in Docker.  If the servers the HTTP load balancer (running via Nginx in a Docker container) distributes to are Apache web servers, Tomcat instances in Docker, or other Nginx servers not running in Docker or Nginx in Docker containers running on a different Docker host, then there will not be a problem.

The Docker service should be running and have access to the internet.  You will need the FQDN or IP address of one or more of the web servers that the soon-to-be-created HTTP load balancer will distribute to.

Procedures
1.  Run a command like this to create the Docker container for the distributor (or HTTP load balancer) Nginx instance:

docker run --name docker-nginxbalancer --net=host nginx

2.  Use the command "docker ps -a" to find the Docker ID of the container created by the above command.

3.  Start the Docker container (e.g., with "docker start abcd1234" where abcd1234 is the container ID).

4.  Enter the Docker container with a command like this:  docker exec -it docker-nginxbalancer bash

5.  Once inside the container, use this command to enable text-editing capabilities: apt-get update; apt-get -y install vim

6.  Modify the default.conf file.
  a) vi /etc/nginx/conf.d/default.conf
  b) In the server {} section, underneath the "location / {" subsection, comment out these lines like this:

  # root /usr/share/nginx/html;
  # index index.html index.htm;

  c)  Do not comment out the "location / {" stanza itself.  Now add a new line under this stanza near the two commented-out lines (as seen above) with this content indented the same way as the original lines above were indented:

  proxy_pass http://backend;

  d) At the very bottom of the file, add these lines (but replace the IP addresses with the FQDNs or IP addresses you want traffic to go to) .

  upstream backend {
     server 10.10.0.1;
     server 10.10.0.2;
     server 10.10.0.3;
   }

  e)  You can have as few as one server stanza above.  The IP addresses can include port numbers (that is the IP address could be a socket) or be FQDNs instead of IP addresses or sockets.  The endpoints (corresponding to the IP addresses, sockets or FQDNs) can be Apache web servers, Nginx web servers, or Apache Tomcat servers. 

If the Docker host and web servers are all AWS instances, we recommend using the servers internal IP addresses (or single IP address if you only add one server to the default.conf upstream {} block).  The Docker container may be lost (inaccessible and will not start again until an AWS Security Group change is made) if you use an external IP address instead of an internal IP address.  The reason is that the Security Group(s) involved may not allow connections to external IP addresses from the external IP addresses.  Internal IP addresses are exempt from this potential Security Group problem.

Save the changes to the file (/etc/nginx/conf.d/default.conf) when you are done.  Then exit the Docker container.

7.  Stop the Docker container with Nginx. Start the Docker container.

FFR
If you want to need to troubleshoot problems with your Nginx load balancer, see this link.