Deploying app on Docker with Tomcat and PostgreSQL - postgresql

I have an testApp.war which I'd like to deploy on Tomcat through docker (docker is on 10.0.2.157). My testApp will work properly only with postgres DB and specified user testUser and password testUserPasswd. I built such a structure:
.
├── db
│   ├── Dockerfile
│   ├── pg_hba.conf
│   └── postgresql.conf
├── docker-compose.yml
└── web
├── context.xml
├── Dockerfile
├── software
│   └── testApp.war
└── tomcat-users.xml
Content of all these files are attached below. I start my containers with command:
docker-compose up -d
However when I go to Tomcat on webbrowser (http://10.0.2.157:8282/manager/html) and try to start my testApp I got:
HTTP Status 404 – Not Found
Type Status Report
Message /testApp/
Description The origin server did not find a current representation
for the target resource or is not willing to disclose that one exists.
Apache Tomcat/8.5.20
What I'm doing wrong? Could you help me with this?
db/Dockerfile
FROM postgres:9.5
MAINTAINER riwaniak
ENV POSTGRES_USER testUser
ENV POSTGRES_PASSWORD testUserPasswd
ENV POSTGRES_DB testUser
ADD pg_hba.conf /etc/postgresql/9.5/main/
ADD postgresql.conf /etc/postgresql/9.5/main/
db/pg_hba.conf
local all all trust
host all all 127.0.0.1/32 md5
host all all 0.0.0.0/0 md5
host all
db/postgresql.conf
listen_addresses='*'
web/context.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context antiResourceLocking="false" privileged="true" >
<!--
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
-->
</Context>
web/Dockerfile
FROM tomcat:8.5.20-jre8
MAINTAINER riwaniak
COPY ./software /usr/local/tomcat/webapps/
CMD ["catalina.sh", "run"]
web/tomcat-users.xml
<?xml version="1.0" encoding="UTF-8"?>
<tomcat-users xmlns="http://tomcat.apache.org/xml"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
version="1.0">
<role rolename="tomcat"/>
<role rolename="admin-gui"/>
<role rolename="manager-gui"/>
<user username="tomcat" password="tomcat" roles="tomcat,admin-gui,manager-gui"/>
</tomcat-users>
and finally docker-compose.yml
version: '2'
services:
testApp:
build: ./web
volumes:
- /path/to/tomcat/folder/web/tomcat-users.xml:/usr/local/tomcat/conf/tomcat-users.xml
- /path/to/tomcat/folder/web/context.xml:/usr/local/tomcat/webapps/HelpdeskApp/META-INF/context.xml
- /path/to/tomcat/folder/web/context.xml:/usr/local/tomcat/webapps/host-manager/META-INF/context.xml
- /path/to/tomcat/folder/web/context.xml:/usr/local/tomcat/webapps/manager/META-INF/context.xml
ports:
- "8282:8080"
links:
- testAppdb
networks:
- testAppnet
testAppdb:
build: ./db
ports:
- "5555:5432"
volumes:
- /srv/docker/postgresql:/var/lib/postgresql
- /path/to/tomcat/folder/db/postgresql.conf:/etc/postgresql/9.5/main/postgresql.conf
- /path/to/tomcat/folder/db/pg_hba.conf:/etc/postgresql/9.5/main/pg_hba.conf
command: postgres -c config_file=/etc/postgresql/9.5/main/postgresql.conf
networks:
- testAppnet
networks:
testAppnet:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.28.0.0/16

OK, I got the solution!
Thanks #Tarun Lalwani for supporting and suggestion.
I had wrong application.yml configuration in Tomcat container. Docker mapped ip addresses of my containers but I shouldn't write just "10.0.2.157" but name of containers. So in my example I've got smth like below:
(...)
environments:
development:
dataSource:
dbCreate: update
url: jdbc:postgresql://10.0.2.157:5432/helpdesk_dev
(...)
However right solution was to map name of postgres container (testAppdb), so correct conf is:
(...)
environments:
development:
dataSource:
dbCreate: update
url: jdbc:postgresql://testAppdb:5432/test_dev
(...)

Related

Docker stack isn't updating the folder structure with new image

Recently I have changed my dockerfile to use a cleaner folder structure but this isn't being updated in the stack deploy
My folder structure:
├── Dockerfile.dev
├── Dockerfile.prod
├── env/
├── requirements.txt
├── src
│   ├── app
│   │   ├── __init__.py
│   │   ├── modules
│   │   ├── __pycache__
│   │   ├── services
│   │   └── util
│   ├── __init__.py
│   └── main.py
└── version.conf
Docker compose file (recorder api part):
api-recorder:
image: img-api-recorder:latest
build:
context: ../api-recorder-python/
dockerfile: Dockerfile.${DOCKER_ENV}
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [node.role == manager]
volumes:
- ${BASE_DIR}api-recorder-python:${WORKDIR}
depends_on:
- zookeeper
environment:
PYTHON_ENV: ${DOCKER_ENV}
Old Dockerfile:
FROM python:3
WORKDIR /usr/src/app
RUN apt-get update
RUN pip install --upgrade pip
RUN pip install kafka-python
RUN pip install python-dotenv
RUN pip install pymongo pymongo[srv]
RUN pip install psycopg2
RUN ln -snf /usr/share/zoneinfo/America/Sao_Paulo \
/etc/localtime && \
echo "America/Sao_Paulo" > /etc/timezone
COPY . .
CMD ["python3", "-u", "src/main.py"]
So what I did was create the requirements.txt and changed the COPY command
New Dockerfile:
FROM python:3
WORKDIR /usr/src
COPY ./requirements.txt ./
RUN apt-get update
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
RUN ln -snf /usr/share/zoneinfo/America/Sao_Paulo \
/etc/localtime && \
echo "America/Sao_Paulo" > /etc/timezone
COPY ./src ./
# CMD ["python3", "-u", "main.py"]
CMD ["python3", "-m", "http.server"]
The weird thing is that the new Dockerfile is being built correctly in a new image because if I run docker run -it [image_name]:latest bash and list the directories I receive this:
which is the new structure made by the new Dockerfile on the other hand if I run the stack deploy and enter inside the container I will be in the /usr/src path and it will have a wrong structure:
The content inside the app folder is wrong, it should have the program code inside it
How can I clean it? I already tried delete all the volumes, images, containers, I even reinstalled docker, I don't know what else to do.
Your docker compose has both an image and build section. Precedence is given to the image so that is being used not the build.
You probably want:
api-recorder:
build:
context: ../api-recorder-python/
dockerfile: Dockerfile.${DOCKER_ENV}
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [node.role == manager]
volumes:
- ${BASE_DIR}api-recorder-python:${WORKDIR}
depends_on:
- zookeeper
environment:
PYTHON_ENV: ${DOCKER_ENV}
I discovered what is happening.
In my docker-compose file I was setting a volume that was overwriting my path, this is happening because my WORKDIR environment is set to /usr/src/app which is the same path that I set in my dockerfile but in the docker-compose this path is being mirrored to my api-recorder-python folder structure
So the only thing that I did was change the volume to ${BASE_DIR}api-recorder-python/src:${WORKDIR} and I changed my WORKDIR to /usr/src and all worked fine
Here:
api-recorder:
image: img-api-recorder:latest
build:
context: ../api-recorder-python/
dockerfile: Dockerfile.${DOCKER_ENV}
deploy:
mode: replicated
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [node.role == manager]
volumes:
- ${BASE_DIR}api-recorder-python/src:${WORKDIR}
depends_on:
- zookeeper
environment:
PYTHON_ENV: ${DOCKER_ENV}

Multiple dockerised PHP-FPM and Nginx applications

my goal is to get multiple PHP services running. So that I can use the same framework I would copy the code from framework to each service (1 & 2).
tree
├── Framework
│ └── frw.class.php
├── CodeService1
│ └── index.php (rescue frw.class.php)
├── CodeService2
│ └── index.php (rescue frw.class.php)
├── docker-compose.yml
├── nginx
├──conf
└── myapp.conf
version: '2'
services:
phpfpm:
image: 'bitnami/php-fpm:8.0.2'
container_name: project1
networks:
- app-tier
volumes:
- ./Framework:/app
- ./CodeService1:/app/service1
service2:
image: 'bitnami/php-fpm:8.0.2'
container_name: Service1
networks:
- app-tier
volumes:
- ./Framework:/app
- ./CodeService2:/app/service2
nginx:
image: 'bitnami/nginx:latest'
depends_on:
- phpfpm
- service2
networks:
- app-tier
ports:
- '80:8080'
- '443:8443'
volumes:
- ./nginx/conf/myapp.conf:/opt/bitnami/nginx/conf/server_blocks/myapp.conf
networks:
app-tier:
driver: bridge
currently the index-files looks like
CodeService1\index.php
<?php declare (strict_types = 1);
echo ("Service1</br>");
CodeService2\index.php
<?php declare (strict_types = 1);
echo ("Service2</br>");
But this won't work. I also tried to outsource the part of create the service (image and copy files) to separates Dockerfiles. but this also won't run.
i call localshost/service1 or localshost/service1 or .
thanks a lot
Most probable is that in your nginx host you set upstream to phpfpm
set $upstream phpfpm
and that's why CodeService1 only is resolved.
You can set upstream conditionaly, e.g:
# set default to codeservice1
set $upstream phpfpm:9000;
# if service2 url, resolve from service2
if ($request_uri ~ "(^/service2)"){
set $upstream service2:9000
}
fastcgi_pass $upstream;

Docker-compose.yml Volummes: and -mount command not the same results

I have been searching for over a week on this issue with no solution.
I am trying to mount a volume from the docker-compose.yml
Here is my directory structure:
-docker-compose.yml
-api
-dockerfile
-frontend
-dockerfile
-models
I have want the models shared between the api service, and the frontend service. first I attempt to get the models into the container. In the container's /usr/src/models directory along with all of its contents. This command works GREAT
docker run -it --mount src="$(pwd)/models",target=/usr/src/models,type=bind -p 3000:3000 website_api
and an important thing to note is that it produces this, when I inspect the docker container in VS code:
website_api.json:
"Mounts": [
{
"Type": "bind",
"Source": "/home/kevin/source/repos/cropwatch/website/models",
"Target": "/usr/src/models"
}
],
This is inside of the json file with lots of other stuff.
however, when I run my docker-compose, that is setup like so:
version: "3.8"
services:
api:
container_name: api
restart: always
build:
context: ./
dockerfile: ./api/dockerfile
ports:
- "3000:3000"
- "3001:3001"
volumes:
- type: bind
source: "./models"
target: "/usr/src/models"
the mounts path in the json file displays as so:
"Mounts": [],
and the /usr/src/models directory in my container is empty...
So these two things do not do the same thing as I seemed to believe before.
Any ideas as to what I am doing wrong in my docker-compose.yml file?
This should do the job:
tree
.
├── api
│   └── dockerfile
├── docker-compose.yml
└── models
└── someFile
cat docker-compose.yml
version: "3.8"
services:
api:
container_name: api
restart: always
build:
context: ./
dockerfile: ./api/dockerfile
volumes:
- ./models:/usr/src/models
docker-compose up -d
docker exec 5ea0c49003f6 sh -c "ls -la /usr/src/models"
total 8
drwxr-xr-x 2 1000 1000 4096 Aug 3 20:09 .
drwxr-xr-x 1 root root 4096 Aug 3 20:15 ..
-rw-r--r-- 1 1000 1000 0 Aug 3 20:09 someFile
docker container inspect --format '{{.Mounts}}' 5ea0c49003f6
[{bind /home/neo/so-playground/mounts-63236400/models /usr/src/models rw true rprivate}]

Docker compose mirroring folder

I'm trying to create a mongodb service that runs in a docker container. My purpose is persist all the data inside container in the host machine. For this I have a docker-compose.yml file, whose content is:
version: '3.2'
services:
mongodb:
image: mongo:latest
environment:
MONGO_INITDB_ROOT_USERNAME: myrootmongousername
MONGO_INITDB_ROOT_PASSWORD: myrootmongopassword
MONGO_INITDB_DATABASE: dbnameiwanttocreate
ports:
- '27010:27017'
volumes:
- 'mongodata:/data'
As you can see, my volumes section declares to drop all content of /data folder inside container into mongodata folder in host. I created a folder named mongodata just at the same height that my docker-compose.yml file.
myprojectfolder
|__docker-compose.yml
|__mongodata
When I do docker-compose up it creates a container and I can connect and so on. However, my mongodata folder is completely empty. That's cannot be true, because if I go inside docker container (docker exec -it <container-id> bash) and explore /data folder, it is not empty at all.
What is my mistake here?
Thanks!
The following Docker compose file works for the directory structure below on ubuntu 18.04, check if docker has permissions to write into the local folder mongodata
If that doesn't work paste logs by running docker-compose logs will update answer specific to the issue.
version: '3.2'
services:
mongodb:
image: mongo:latest
environment:
MONGO_INITDB_ROOT_USERNAME: myrootmongousername
MONGO_INITDB_ROOT_PASSWORD: myrootmongopassword
MONGO_INITDB_DATABASE: dbnameiwanttocreate
ports:
- '27010:27017'
volumes:
- './mongodata:/data'
├── docker-compose.yml
└── mongodata
├── configdb
└── db

Including vars into an Ansible playbook

I wanted to give deploying django projects with ansible a shot but I'm stuck on what seems to be a pretty basic issue.
I've created a basic playbook to deploy my Postgres server.
---
- hosts: default
remote_user: myusername
become: yes
become_method: sudo
become_user: postgres
vars:
- include: vars/databases.yml
tasks:
- name: Ensure Postgres server is running
service: name=postgresql state=started enabled=yes
- name: Create postgres database
postgresql_db:
name: '{{ db_name }}'
state: present
encoding: 'UTF-8'
I run the playbook and I get this error
fatal: [default]: FAILED! => {"failed": true, "msg": "'db_name' is undefined"}
In order to keep all of my passwords and such out of version control I've created a directory vars. It's located in my project structure like this with all my ansible yaml files in deploy and all my vars files in the vars subdirectory.
..
├── deploy
│   └── vars
..
├── myproject
├── manage.py
└── utils
# var/databases.yml
db_name: <database name>
What's going on here?
Update: Added contents of var/databases.yml as requested.
The variable db_name must be assigned a value before trying to create a database. the error clearly stating that <"'db_name' is undefined">, the variable db_name is undefined/unassigned.
See below sample code for an example
vars:
dbname: myapp
dbuser: django
dbpassword: mysupersecretpassword
tasks:
- name: ensure database is created
postgresql_db: name={{dbname}}
Can you change the the vars with vars_files like this:
vars_files:
- vars/databases.yml