Linux, Apache, MySql Java
LAMJ image used for hosting LAMJ stack application
Can also be used during development to build with Maven or gradle.
See source on GitHub: kea-dev/lamj
The docker container is
FROM tomcat:11.0-jdk17
an official Tomcat image maintained by the Docker Commununity. See the Tomcat 11 dockerfile). This image is;FROM eclipse-temurin:17-jdk-jammy
an official Eclipse Temurin image maintained by the Eclipse Temurin project (see the 17-jdk-jammy dockerfile). And this itself is;FROM ubuntu:22.04
a.k.a Jammy.
This image includes Tomcat.
The image it inherits from includes the CMD
:
CMD ["catalina.sh", "run"]
If you use this image to host a springboot app it's typically complied as a fat .jar
which contains the Tomcat server itself and you won't have to start Tomcat. But if your project is a .war
than you might want to add the CMD
above to your own container too.
This image installs, configures and starts a mysql server.
If Mysql is the only thing you really need - It's possibly that you just want to use the community maintained image: mysql it's more battle proof and the shell script docker-entrypoint.sh it starts is far more advanced than the one used in this image.
...on the other hand - is a show case in the minimum settings and steps that are needed in order to install and configure mysql (mysqld.cnf) - I've marked the changes made in this image with LAMJ
in the comments. The original *.cnf
is backed up on the image: /etc/mysql/mysql.conf.d/installation-deaults.mysqld.cnf
.
The image uses CMD
to run:
CMD lamj.init.sh && \
tail -f /dev/null
tail -f /dev/null
keeps the container alive after af the databas service is started. It's only required if you don't use this image for anything other than mysql. But if you start catalina.sh
or run java -jar ...
then you don't need it.
You can see lamj.init.sh.
- It creates and grants permissions to a user
'root'@'%'
which is used when accessing the service from an IP address (as opposed to the logical namelocalhost
). - It sets the password for both users
'root'@'%'
and'root'@'localhost'
- It looks for
*.sql
files in the directory/docker-entrypoint-initdb.d
and if it finds any it executes them in alphabetically order against the service. This mimics the behavior of the officialmysql
image.
This image installs OpenJDK, Maven and Gradle
The image also installs:
- git
- GitHub CLI
- Pscale CLI
Run it like this:
The image is maintained in three tags
amd64
same aslatest
arm64
On Mac with M1 or M2 Processors use arm64
. In most other contexts go with amd64
or latest
. If you don't specify anything you'll get latest
.
docker run \
-it \
--rm \
-p 8080:8080 \
-p 3306:3306 \
--pid=host \
-v $(pwd):/app:rw --workdir /app \
lakruzz/lamj:latest \
/usr/bin/env bash
Note on Windows:
The -v
switch is tricky on windows you can use the command line terminal cmd
- but not PowerShell. And you must swap the -v
switch to:
-v %cd%://app:rw --workdir //app
You can replace bash
with a valid command to use any of the CLIs the image offers:
gh
mvn
gradle
mysql
pscale
See it on Docker Hub lakruzz/lamj
You simply just ditch the last line - the container will then default run the lamj.init.sh
script - and start the database service and set the root password.
Note: If you don't specify a password it will default to "root".
docker run \
-it \
--rm \
-p 8080:8080 \
-p 3306:3306 \
--pid=host \
-v $(pwd):/app:rw --workdir /app \
-e MYSQL_ROOT_PASSWORD=mysecretpassword
lakruzz/lamj:latest
For serious production sites you'll probably want to separate your app into two different deploys. But this neat image allows you to optimize the development process and even host your app in a single docker container (no need for docker compose)
In your project:
- Configure your (springboot) project to build a fat
*.jar
- as opposed to a.war
- Put all the scripts you want to initialize your database with in separate folder. Name them so the order to run them is alphabetical. In the example below I have my sql files in
src/mysql/init/
- Create a docker file
FROM lakruzz/lamj:latest COPY src /src COPY pom.xml /pom.xml RUN set -ex; \ mvn -f /pom.xml clean package; \ mv /target/*.jar /app/; \ rm -rf /target; \ rm -rf /src; \ rm -rf /pom.xml; COPY src/mysql/init/* /docker-entrypoint-initdb.d CMD set -ex; \ lamj.init.sh; \ java -jar /app/*.jar;
- Build your docker file like this:
docker build -t myapp .
- Run your app like this:
docker run \ -it \ --rm \ --name myapp \ --pid=host \ -p 8080:8080 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=mysecretpassword \ myapp
The container built this way is a single container (no docker compose needed) and can be hosted as a single instance anywhere:
- Top 10 Docker Hosting Platforms
- Best Docker Cloud Hosting
- 8 Best Docker Hosting Platforms for your Containers
- Best Docker Hosting Platforms of 2023
If your jdbc is using localhost
the database is accessed through a socket and the IP address 3306 does not need to be exposed. The authenticated user is 'root'@'localhost'
.
# application.properties
# database info
spring.datasource.url=jdbc:mysql://localhost:3306/superhero
spring.datasource.username=root
spring.datasource.password=root
If your jdbc is using 127.0.0.1
which from a network perspective is also localhost but in MySql makes quite a difference. The database is not accessed through a socket, but actually uses the WAN side IP address on tcp port 3306. For this to work the port must be be exposed. The authenticated user is 'root'@'%'
.
# application.properties
# database info
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/superhero
spring.datasource.username=root
spring.datasource.password=root
If
Have a look at this sample project lakruzz/SuperheltV5.
Read the CONTRIBUTE.md
file for details.
Summary:
It's has three different application properties:
application-dev.properties
application-prod.properties
application.properties
Profiles for dev
and prod
are defined in the pom.xml
And can be specified during build and execution:
# uses application.properties a.k.a "default"
mvn clean package
# uses application-dev.properties
mvn -Dspring.profiles.active=dev clean package
# uses application-prod.properties
mvn -Dspring.profiles.active=prod clean package
# If application is built with application.properties
java -jar target/*.jar
# If application is built with application-dev.properties
java -Dspring.profiles.active=dev -jar target/*.jar
# If application is built with application-prod.properties
java -Dspring.profiles.active=prod -jar target/*.jar
...Happy hacking!