Showing posts with label docker. Show all posts
Showing posts with label docker. Show all posts

Tuesday, March 19, 2019

Smaller Wildfly image with Galeon

First lets create Docker image in standard way:
FROM jboss/wildfly
RUN curl -Ls https://github.com/andrzejszywala/hellojee/raw/master/hellojee.war -o /opt/jboss/wildfly/standalone/deployments/hellojee.war
Build image
docker build -t hello_wildfly .
docker image ls
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
hello_wildfly            latest              cc8926d06bf0        25 minutes ago      745MB
Now lets use Galeon to create smaller wildfly
# In first stage prepare wildfly 
FROM adoptopenjdk/openjdk11:alpine-slim as WILDFLY_BUILD
ENV GALEON_VERSION 3.0.2.Final 
RUN apk --update add --no-cache --virtual .build-deps unzip curl bash
RUN curl -Ls https://github.com/wildfly/galleon/releases/download/$GALEON_VERSION/galleon-$GALEON_VERSION.zip -o /tmp/galeon.zip
RUN unzip /tmp/galeon.zip -d /tmp
RUN /tmp/galleon*/bin/galleon.sh install wildfly:current --layers=cdi,jaxrs,jpa,h2-database --dir=/tmp/wildfly 
RUN curl -Ls https://github.com/andrzejszywala/hellojee/raw/master/hellojee.war -o /tmp/wildfly/standalone/deployments/hellojee.war

# Second stage builds final image 
FROM adoptopenjdk/openjdk11:alpine-slim 
ENV LAUNCH_JBOSS_IN_BACKGROUND true
EXPOSE 8080
# Copy wildfly with application from temporary image
COPY --from=WILDFLY_BUILD /tmp/wildfly /opt/wildfy
CMD ["/opt/wildfy/bin/standalone.sh", "-b", "0.0.0.0"]
Build image
docker build -t hello_galeon .
docker image ls
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
hello_galeon             latest              a719b9633749        13 minutes ago      365MB
As you can see image is half the size.

Thursday, March 22, 2018

Prywatne repozytorium Dockera

Utworzenie pliku z użytkownikiem dla rejestru:
sudo docker run --entrypoint htpasswd registry:2 -Bbn uzytkownik haslo > /opt/docker/auth/htpasswd
Uruchomienie rejestru:
sudo docker run -d \
--restart=always \
--name registry \
-v /opt/docker/certs:/certs \
-v /opt/docker/auth:/auth \
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.unencrypted.key \
-p 5000:443 \
registry:2
Dodanie certyfikatu do rejestru:
/etc/docker/certs.d/privatehub.domain.com:5000/ca.crt
Logowanie do rejestru:
sudo docker login -u uzytkownik -h haslo -e email privatehub.domain.com:5000
Wrzucenie obrazu do rejestru:
docker build -t privatehub.domain.com:5000/apka:1 .
docker push privatehub.domain.com:5000/apka:1
Utworzenie serwisu w swarmie z przekazaniem informacji logowania do repozytorium
docker service create --replicas 1 --with-registry-auth --name apka privatehub.domain.com:5000/apka:1

Saturday, November 5, 2016

mod_cluster as a Service Discovery with Wildfly and Docker

In this blog post I'll show how to deploy microservices which uses mod_cluster instead Service Discovery. First let's create Dockerfile with mod_cluster as load balancer:
FROM fedora
RUN dnf -y update
RUN dnf -y install httpd
RUN dnf -y install mod_cluster
RUN dnf -y install mod_ssl
RUN dnf clean all

RUN sed -i "s|LoadModule proxy_balancer_module|#LoadModule proxy_balancer_module|" /etc/httpd/conf.modules.d/00-proxy.conf

ADD mod_cluster.conf /etc/httpd/conf.d/mod_cluster.conf
RUN mkdir /etc/httpd/conf/certs
RUN openssl req \
    -new \
    -newkey rsa:4096 \
    -days 365 \
    -nodes \
    -x509 \
    -subj "/C=PL/ST=Slaskie/L=Katowice/O=aszywala/OU=aszywala/CN=Andrzej Szywala" \
    -keyout www.aszywala.key \
    -out www.aszywala.crt
EXPOSE 80
EXPOSE 443
CMD ["/sbin/httpd", "-DFOREGROUND"]

Next I'll create mod_cluster.conf
LoadModule proxy_cluster_module modules/mod_proxy_cluster.so
LoadModule cluster_slotmem_module modules/mod_cluster_slotmem.so
LoadModule manager_module modules/mod_manager.so
LoadModule advertise_module modules/mod_advertise.so

<IfModule manager_module>

  Maxhost 100

  <VirtualHost *:80>
    <Directory />
        Require all granted
    </Directory>
    <Location /mod_cluster_manager>
        SetHandler mod_cluster-manager
        Require all granted
    </Location>
    <Location /server-status>
        SetHandler server-status
    </Location>

    KeepAliveTimeout 60
    ManagerBalancerName mycluster
    ServerAdvertise On
    EnableMCPMReceive On
  </VirtualHost>
</IfModule>

Build Dockerfile
docker build -t lb .
Create docker network
docker network create mynet
Run container with load balancer
docker run --name lb -it --rm --net mynet -p 80:80 -p 443:443 lb
You can open web browser and check if mod_cluster works http://localhost/mod_cluster_manager
Create Dockerfile with micro service application.
FROM jboss/wildfly
MAINTAINER Andrzej Szywala 
ADD customization $JBOSS_HOME
RUN /opt/jboss/wildfly/bin/jboss-cli.sh --file=/opt/jboss/wildfly/wildfly_conf.txt
# FIX for Error: WFLYCTL0056: Could not rename /opt/jboss/wildfly/standalone/configuration/standalone_xml_history/current...
RUN rm -rf /opt/jboss/wildfly/standalone/configuration/standalone_xml_history/current/*
ADD hellojee.war $JBOSS_HOME/standalone/deployments/hellojee.war
wildfly_conf.txt file configures mod_cluster and ajp
embed-server --server-config=standalone.xml
batch
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=lb:add(host="lb",port="80")
/extension=org.jboss.as.modcluster:add
/subsystem=undertow/server=default-server/ajp-listener=ajp:add(socket-binding=ajp, scheme="http")
/:composite(steps=[{"operation" => "add", "address" => [ ("subsystem" => "modcluster") ]},{ "operation" => "add", "address" => [ ("subsystem" => "modcluster"), ("mod-cluster-config" => "configuration") ], "connector" => "ajp", "balancer" => "hellojee", "advertise" => "false", "proxies" => ["lb"] }])
# Execute the batch
run-batch
reload
stop-embedded-server
quit
Build Dockerfile
docker build -t hellojee_cluster .
Run container
docker run --name hellojee_cluster -it --rm --net mynet hellojee_cluster
Check if application registers in loadbalancer http://localhost/mod_cluster_manager

Open browser http://localhost/hellojee/resources/hello. You should see response from application
{"database":"H2 - 1.3.173 (2013-07-28)","host":"0461b41cff7f (172.20.0.3)","hello":["Hello","Witaj","Hallo","Hej","Ahoj","Bonjour","Hola"]}
When you stop the container application will be automatically deregistered from mod_cluster. When you kill the container mod_cluster will notice that and change application status to NOTOK.

Sources for this post can be found on Github https://github.com/andrzejszywala/docker-images/tree/master/hellojee/mod_cluster

Sunday, October 9, 2016

Change database without changing code using default datasource and Docker.

In this blog post we will consider the use case that we want to use different databases for our system but we don't want to change any line of code or any file in built application. In this example we will use a simple application with a REST interface. The source code is available on github https://github.com/andrzejszywala/hellojee

In persistence.xml we don't specify datasource so application will use default datasource which is provided by the container.
<persistence version="2.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
    xsi:schemalocation="http://xmlns.jcp.org/xml/ns/persistence
    http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="hellojee" transaction-type="JTA">
    <properties>
      <property name="javax.persistence.schema-generation.database.action" value="drop-and-create">
    </property></properties>
  </persistence-unit>
</persistence>

Now let's create first Dockerfile
FROM jboss/wildfly
ADD hellojee.war $JBOSS_HOME/standalone/deployments/hellojee.war

This Dockerfile extends jboss/wildfly image and adds hellojee.war to deployments directory. Next let's build and run the image
docker build -t andrzejszywala/hellojee .
docker run -d -p 8080:8080 --name hellojee andrzejszywala/hellojee
Open browser http://localhost:8080/hellojee/resources/hello and verify that the application works. In the response you should see json object with database name, host name and some sample data from Hello table.
{"database":"H2 - 1.3.173 (2013-07-28)","host":"597840afb246 (172.17.0.2)","hello": "Hello","Witaj","Hallo","Hej","Ahoj","Bonjour","Hola"]}
Stop container
docker stop hellojee
Now we will create docker image that connects to mysql databse. Dockerfile is available on https://github.com/andrzejszywala/docker-images/tree/master/hellojee/mysql
FROM jboss/wildfly
ADD customization $JBOSS_HOME
RUN /opt/jboss/wildfly/bin/jboss-cli.sh --file=/opt/jboss/wildfly/wildfly_conf.txt
# FIX for Error: WFLYCTL0056: Could not rename /opt/jboss/wildfly/standalone/configuration/standalone_xml_history/current...
RUN rm -rf /opt/jboss/wildfly/standalone/configuration/standalone_xml_history/current/*
ADD hellojee.war $JBOSS_HOME/standalone/deployments/hellojee.war
the most important part is wildfly_conf.txt file which configures mysql module and sets mysql datasource as default so wildfly will use it in our application.
embed-server --server-config=standalone.xml
batch
# add mysql module
module add --name=com.mysql --resources=/opt/jboss/wildfly/mysql-connector-java-5.1.34.jar --dependencies=javax.api,javax.transaction.api
# driver configuration
/subsystem=datasources/jdbc-driver=mysql:add(driver-name=mysql,driver-module-name=com.mysql,driver-xa-datasource-class-name=com.mysql.jdbc.jdbc2.optional.MysqlXADataSource)
# add new datasource
data-source add --name=mysqlDS --driver-name=mysql --jndi-name=java:jboss/datasources/MySQLDS --connection-url=jdbc:mysql://mysqldb:${env.DB_PORT}/sample?useUnicode=true&characterEncoding=UTF-8 --user-name=mysql --password=mysql --use-ccm=false --max-pool-size=25 --blocking-timeout-wait-millis=5000 --enabled=true
# set default datasource
/subsystem=ee/service=default-bindings:write-attribute(name="datasource", value="java:jboss/datasources/MySQLDS")
# Execute the batch
run-batch
reload
stop-embedded-server
quit
Note that mysql host name is mysqldb. This will be the name of the mysql container and after run containers in the same network we will be able to connect to the database. Now we can build docker image
docker build -t andrzejszywala/hellojee-mysql .
Create docker network
docker network create mynet
Run mysql container
docker run --name mysqldb --net mynet -e "MYSQL_ROOT_PASSWORD=mysql" -e "MYSQL_DATABASE=sample" -e "MYSQL_USER=mysql" -e "MYSQL_PASSWORD=mysql"-d mysql:latest
And finally run the application container
docker run -d -p 8080:8080 -e "DB_PORT=3306" --name hellojee-mysql --net mynet andrzejszywala/hellojee-mysql
Open browser http://localhost:8080/hellojee/resources/hello. You should see something like this:
{"database":"MySQL - 5.7.15","host":"8acd618e942e (172.20.0.3)","hello":["Hello","Witaj","Hallo","Hej","Ahoj","Bonjour","Hola"]}
As you can see database is MySQL. JEE 7 gives us ability to build once and deploy anywhere and if we do not go beyond standard we can easily change servers and databases. All files used in this blog post are available on github https://github.com/andrzejszywala/docker-images/tree/master/hellojee