docker file tomcat configuration with docker file - docker

i want to create a docker file with tomcat server .
i have two war files war 1 and war 2.
i copied war1.xml into /usr/local/tomcat/conf/Catalina/localhost/
i copied war2.xml into /usr/local/tomcat/conf/Catalina/localhost/
here is the context of war1.xml
<Resources>
<Resource
name="jdbc/app1"
type="javax.sql.DataSource"
auth="Container"
username="root"
password="toto"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306">
</Resource>
<PreResources className="org.apache.catalina.webresources.DirResourceSet" base="/app/ml/ts/config/"
webAppMount="/WEB-INF/classes"/>
<ResourceLink global="app1" name="app1" type="javax.sql.DataSource"/>
</Resources>
here are my docker files :
FROM tomcat:8.0-jre8-alpine
COPY app1/target/war1.war /usr/local/tomcat/webapps/
COPY app2/target/app2.war /usr/local/tomcat/webapps/
COPY app1/src/main/resources/conf/app1.xml /usr/local/tomcat/conf/Catalina/localhost/
COPY app2/src/main/resources/app2/conf/app2.xml /usr/local/tomcat/conf/Catalina/localhost/
COPY app1/src/main/resources/app1/scripts/*
EXPOSE 8080
CMD ["catalina.sh","run"]
here is mysql docker file :
FROM mysql:5.7
# Add a database
ENV MYSQL_DATABASE MyDb
ENV MYSQL_ROOT_PASSWORD toto
# Add the content of the sql-scripts/ directory to your image
# All scripts in docker-entrypoint-initdb.d/ are automatically
# executed during container startup
COPY app-livraison/src/main/resources/db/ /docker-entrypoint-initdb.d/
here is my docker compose file :
version: '3'
services:
tomcat:
build:
context: .
dockerfile: Dockerfile.tomcat
ports:
- 8080:8080
mysql:
build:
context: .
dockerfile: Dockerfile.db
environment:
MYSQL_ROOT_PASSWORD: toto
MYSQL_DATABASE: Mydb
but the context could not add the datasource , i have the following error :
BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'dataSource' threw exception; nested exception is org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name '"glc-batch"'; nested exception is javax.naming.NameNotFoundException: Name [app1] is not bound in this Context. Unable to find [app1].
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
... 48 common frames omitted
Caused by: org.springframework.jdbc.datasource.lookup.DataSourceLookupFailureException: Failed to look up JNDI DataSource with name '"app1"'; nested exception is javax.naming.NameNotFoundException: Name [app1] is not bound in this Context. Unable to find [app1].

the problem was the JNDI-NAME , in the properties file you should give the complete name defined in server.xml : jndi/datasourceName without quotation marks.
that was not a docker problem.
thanks

Related

Copy single file into container via docker-compose and environmental variable

Any ideas why this isn't putting the file into the container?
k6:
image: loadimpact/k6:0.32.0
environment:
- ENVIRONMENT=${ENVIRONMENT}
- AMOUNT_OF_USERS=${AMOUNT_OF_USERS}
- RUN_TIME=${RUN_TIME}
command: run /test.mjs
volumes:
- ./load-test.mjs:/test.mjs # <-- this works
- ./${USERS_FILE}:/users.csv # <-- this does not work
I'm running with the command:
ENVIRONMENT=bla AMOUNT_OF_USERS=5 RUN_TIME=1m USERS_FILE=users2.csv docker-compose up
I did a check inside the container:
console.log(exists('users.csv'))
console.log(exists('test.mjs'))
Results:
k6_1 | time="2021-05-24T11:31:51Z" level=info msg=false source=console
k6_1 | time="2021-05-24T11:31:51Z" level=info msg=true source=console
The USERS_FILE variable file exists in the same directory as the current working directory, i.e. users2.csv.
If I set the volume to the following it works:
- ./users2.csv:/users.csv
volumes:
- ./load-test.mjs:/test.mjs
- ${PWD}/${USERS_FILE}:/users.csv

Importing datasource and grafana dashboard while building container

I am trying to create docker containers with datasource and dashboard already preconfigured.
As of now I can understand that from v5.0 onwards grafana have introduced feature of provisioning.
I have created two yml file first the datasource and second the dashboard.
But I couldn't understand which part of docker-compose file will invoke these datasource.yml and dashboarad.yml file. What tag should I used and so on.Below are my docker-compose, datasource & dashboard file details.
Only detail in compose file I could bit understood is - ./grafana/provisioning/:/etc/grafana/provisioning/ which is copy some host folder structure to container (but not sure about it).
docker-compose.yml
grafana:
image: grafana/grafana
links:
- influxdb
ports:
- '3000:3000'
volumes:
- 'grafana:/var/lib/grafana'
- ./grafana/provisioning/:/etc/grafana/provisioning/
Dashboard.yml
apiVersion: 1
providers:
- name: 'Docker Dashboard'
orgId: 1
folder: ''
type: file
disableDeletion: false
updateIntervalSeconds: 10 #how often Grafana will scan for changed dashboards
options:
path: <path-where-I-have-placed-jsonfile>
Datasource.yml
datasources:
- access: 'proxy' # make grafana perform the requests
editable: true # whether it should be editable
is_default: true # whether this should be the default DS
name: 'influx' # name of the datasource
org_id: 1 # id of the organization to tie this datasource to
type: 'influxdb' # type of the data source
url: 'http://<ip-address>:8086' # url of the prom instance
database: 'influx'
version: 1 # well, versioning
the volumes directive will run only in runtime not build you need to use COPY if you want that to work in build stage
Dockerfile:
FROM grafana/grafana
COPY ./grafana/provisioning /etc/grafana/provisioning
the ./grafana/provisioning should be relative to Dockerfile
Compose:
grafana:
build: .
.
.

Can't hit dotnet core endpoint when publishing to docker

I've been working on this for awhile and can't seem to get a proper docker setup for my dotnet core application. It works fine when running with dotnet run. Here is my docker file, docker compose file, controller file, and app logs after running docker-compose up.
DockerFile:
# build application
FROM microsoft/dotnet:sdk AS build-env
WORKDIR /app
COPY ./ ./
RUN dotnet restore
RUN dotnet publish -c Release
# run application
FROM microsoft/dotnet:aspnetcore-runtime
WORKDIR /app
COPY --from=build-env app/bin/Release/netcoreapp2.2/publish/ /app
COPY appsettings.json /app
EXPOSE 80
EXPOSE 5000
ENTRYPOINT ["dotnet", "imdb_id_retrieval.dll"]
docker-compose.yml:
version: '3.7'
volumes:
imdb_id_service_volume:
external:
name: imdb_id_service_volume
networks:
app_network:
driver: bridge
services:
postgres_imdb_id_db:
image: postgres
ports:
- "5432:5432"
volumes:
- imdb_id_service_volume:/var/lib/postgresql/data
networks:
- app_network
docker_imdb_id_service:
image: docker_retrieve_data
depends_on:
- "postgres_imdb_id_db"
restart: always
environment:
- ASPNETCORE_ENVIRONMENT=development
build:
context: .
dockerfile: Dockerfile
networks:
- app_network
ports:
- "5000:80"
Controller:
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using imdb_data_retrieval.Logic;
namespace imdb_data_retrieval.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ImdbIdController : ControllerBase
{
private IRetrieveImdbIdService _retrieveImdbIdService;
public ImdbIdController(IRetrieveImdbIdService retrieveImdbIdService){
_retrieveImdbIdService = retrieveImdbIdService;
}
// GET api/values
[HttpGet]
public async Task<ActionResult<string>> Get(string title, string releaseYear)
{
var imdbId = await _retrieveImdbIdService.ScrapeImdbIdAsync(title, releaseYear);
if (imdbId == Constants.InvalidYearResponse)
return BadRequest(Constants.InvalidYearResponse);
if (imdbId == null)
return NotFound(Constants.MovieWasNotFoundResponse);
return Ok(imdbId);
}
}
}
So at this point I run "docker-compose build" and then "docker-compose up". This is the output:
[user#user-pc imdb_id_retrieval]$ docker-compose up
Starting imdb_id_retrieval_postgres_imdb_id_db_1 ... done
Recreating imdb_id_retrieval_docker_imdb_id_service_1 ... done
Attaching to imdb_id_retrieval_postgres_imdb_id_db_1, imdb_id_retrieval_docker_imdb_id_service_1
postgres_imdb_id_db_1 | 2019-05-12 12:37:58.035 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
postgres_imdb_id_db_1 | 2019-05-12 12:37:58.035 UTC [1] LOG: listening on IPv6 address "::", port 5432
postgres_imdb_id_db_1 | 2019-05-12 12:37:58.112 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
postgres_imdb_id_db_1 | 2019-05-12 12:37:58.267 UTC [23] LOG: database system was shut down at 2019-05-12 12:37:12 UTC
postgres_imdb_id_db_1 | 2019-05-12 12:37:58.555 UTC [1] LOG: database system is ready to accept connections
docker_imdb_id_service_1 | derp
docker_imdb_id_service_1 | host=postgres_imdb_id_db; Username=postgres; Port=5432; Database=ImdbIds;
docker_imdb_id_service_1 | warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
docker_imdb_id_service_1 | No XML encryptor configured. Key {964dd0aa-58de-4714-b544-3c48e2b80bb9} may be persisted to storage in unencrypted form.
docker_imdb_id_service_1 | Hosting environment: development
docker_imdb_id_service_1 | Content root path: /app
docker_imdb_id_service_1 | Now listening on: http://[::]:80
docker_imdb_id_service_1 | Application started. Press Ctrl+C to shut down.
Now I go to my browser and go to "http://localhost:5000/api/imdbid?title=iron%20man&releaseYear=2008" and I get a 404 response. The first time I try to hit the endpoint I see
docker_imdb_id_service_1 | warn: Microsoft.AspNetCore.HttpsPolicy.HttpsRedirectionMiddleware[3]
docker_imdb_id_service_1 | Failed to determine the https port for redirect.
And then no logs on consecutive hits. I don't think I need https configured.
Any ideas on what I'm doing wrong?
EDIT:
My Dockerfile now looks likes this.
# build application
FROM microsoft/dotnet:sdk AS build-env
WORKDIR /app
COPY ./ ./
RUN dotnet restore
RUN dotnet publish -c Release
# run application
FROM microsoft/dotnet:aspnetcore-runtime
WORKDIR /app
COPY --from=build-env app/bin/Release/netcoreapp2.2/publish/ /app
COPY appsettings.json /app
EXPOSE 80
EXPOSE 5000
# changed this
ENTRYPOINT ["dotnet", "imdb_id_retrieval.dll", "--urls", "http://0.0.0.0:5000"]

Error output when running a postfix container

I have the following in my docker-compose.yml file:
simplemail:
image: tozd/postfix
ports:
- "25:25"
So far, so good. But I get the following output when I run docker-compose run simplemail:
rsyslogd: cannot create '/var/spool/postfix/dev/log': No such file or
directory rsyslogd: imklog: cannot open kernel log (/proc/kmsg):
Operation not permitted. rsyslogd: activation of module imklog failed
[try http://www.rsyslog.com/e/2145 ] rsyslogd: Could no open output
pipe '/dev/xconsole': No such file or directory [try
http://www.rsyslog.com/e/2039 ] * Starting Postfix Mail Transport
Agent postfix [ OK ]
What can I do to fix the errors above?
The documentation for the tozd/postfix image states:
You should make sure you mount spool volume (/var/spool/postfix) so
that you do not lose e-mail data when you are recreating a container.
If a volume is empty, image will initialize it at the first startup.
your docker-compose.yml file should then be:
version: "3"
volumes:
postfix-data: {}
services:
simplemail:
image: tozd/postfix
ports:
- "25:25"
volumes:
- postfix-data:/var/spool/postfix

Symfony 4 produces SQLSTATE[HY000] [2002] Connection refused using Docker containers

I have 2 Docker containers using the following configuration:
version: '2'
volumes:
db_data: {}
services:
db:
container_name: database-mysql-5.7
build:
context: ./docker/db/
ports:
- "3321:3306"
volumes:
- db_data:/var/lib/mysql
web:
container_name: apache-symfony-4
build:
context: ./docker/web/
image: php
links:
- db
depends_on:
- db
ports:
- "8021:80"
volumes:
- ./app/:/var/www/symfony
I can connect to the db container from my local host (Mac OS) and I can connect to the db container (and execute sql statements successfully) from the web container. Additionally, when I exec to the web container I can execute doctrine:migrations:diff commands successfully.
However, when I try and run code like the following:
$User = $this->getDoctrine()
->getRepository(User::class)
->findAll();
I receive the following error:
An exception occurred in driver: SQLSTATE[HY000] [2002] Connection refused
octrine\DBAL\Exception\ConnectionException:
An exception occurred in driver: SQLSTATE[HY000] [2002] Connection refused
at vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php:108
at Doctrine\DBAL\Driver\AbstractMySQLDriver->convertException('An exception occurred in driver: SQLSTATE[HY000] [2002] Connection refused', object(PDOException))
(vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php:176)
at Doctrine\DBAL\DBALException::wrapException(object(Driver), object(PDOException), 'An exception occurred in driver: SQLSTATE[HY000] [2002] Connection refused')
(vendor/doctrine/dbal/lib/Doctrine/DBAL/DBALException.php:161)
at Doctrine\DBAL\DBALException::driverException(object(Driver), object(PDOException))
(vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php:47)
Here is the contents of my .env file
# This file is a "template" of which env vars need to be defined for your application
# Copy this file to .env file for development, create environment variables when deploying to production
# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration
###> symfony/framework-bundle ###
APP_ENV=dev
APP_SECRET=7c2deaf7464ad40b484d457e02a56918
#TRUSTED_PROXIES=127.0.0.1,127.0.0.2
#TRUSTED_HOSTS=localhost,example.com
###< symfony/framework-bundle ###
###> symfony/swiftmailer-bundle ###
# For Gmail as a transport, use: "gmail://username:password#localhost"
# For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode="
# Delivery is disabled by default via "null://localhost"
MAILER_URL=null://localhost
###< symfony/swiftmailer-bundle ###
###> doctrine/doctrine-bundle ###
# Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
# Configure your db driver and server_version in config/packages/doctrine.yaml
DATABASE_URL=mysql://hereswhatsontap:#####db:####/hereswhatsontap
###< doctrine/doctrine-bundle ###
Additionally, if I try and use the DBAL it returns the same error:
/**
* #Route("/test")
*/
public function testAction(Connection $connection){
$users = $connection->fetchAll('SELECT * FROM users');
return $this->render("startup/startup.html/twig", [
"NewUser" => $users
]);
}
Attempts to use the root username/password are also failing.
Ok, last additional data (I promise :)
Executing the following code works fine from within the /public folder of Symfony
<?php
$dsn = 'mysql:host=db;dbname=hereswhatsontap;';
$username = 'hereswhatsontap';
$password = '####';
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
);
$dbh = new PDO($dsn, $username, $password, $options);
$sql = "SELECT * from user";
$statement = $dbh->prepare($sql);
$statement->execute();
$users = $statement->fetchAll(2);
print_r($users);
?>
Thanks a lot for your comment, it saved me some further hours of research lol. I would just add for newbies in Docker like me, that if you want to get your container IP you can run the following command (so that you won't have to look for in the whole configuration dump you get by using only inspect):
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' YOURCONTAINERID
Thanks again!
This issue was caused by a full lack of understanding for me on how the containers communicate amongst each other.
The web container and the db container are essentially on their own 'vpn' network which means that the web container can communicate with db directly and would then use the internal port (3306) based on my configuration.
So removing the port (which I had as the external port) from my .env files' DATABASE_URL value was the answer.
DANG!

Resources