-
Notifications
You must be signed in to change notification settings - Fork 36
Added docker build and quick-start #101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 3 commits
1491a35
6b7246f
70e8e87
25d21a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
mgaffigan marked this conversation as resolved.
Show resolved
Hide resolved
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| # Include any files or directories that you don't want to be copied to your | ||
| # container here (e.g., local build artifacts, temporary files, etc.). | ||
| # | ||
| # For more help, visit the .dockerignore file reference guide at | ||
| # https://docs.docker.com/go/build-context-dockerignore/ | ||
|
|
||
| **/.DS_Store | ||
| **/.classpath | ||
| **/.dockerignore | ||
| **/.env | ||
| **/.factorypath | ||
| **/.git | ||
| **/.gitignore | ||
| **/.idea | ||
| **/.project | ||
| **/.sts4-cache | ||
| **/.settings | ||
| **/.toolstarget | ||
| **/.vs | ||
| **/.vscode | ||
| **/.next | ||
| **/.cache | ||
| **/*.dbmdl | ||
| **/*.jfm | ||
| **/charts | ||
| **/docker-compose* | ||
| **/compose.y*ml | ||
| **/Dockerfile* | ||
| **/secrets.dev.yaml | ||
| **/values.dev.yaml | ||
| **/vendor | ||
| LICENSE | ||
| README.md | ||
| **/*.class | ||
| **/*.iml | ||
| **/*.ipr | ||
| **/*.iws | ||
| **/*.log | ||
| **/.apt_generated | ||
| **/.gradle | ||
| **/.gradletasknamecache | ||
| **/.nb-gradle | ||
| **/.springBeans | ||
| **/build | ||
| **/dist | ||
| **/gradle-app.setting | ||
| **/nbbuild | ||
| **/nbdist | ||
| **/nbproject/private | ||
| **/target | ||
| *.ctxt | ||
| .mtj.tmp | ||
| .mvn/timing.properties | ||
| buildNumber.properties | ||
| dependency-reduced-pom.xml | ||
| hs_err_pid* | ||
| pom.xml.next | ||
| pom.xml.releaseBackup | ||
| pom.xml.tag | ||
| pom.xml.versionsBackup | ||
| release.properties | ||
| replay_pid* |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| # For developers and contributors | ||
|
|
||
| ## "Easy Path" with docker | ||
|
|
||
| ```bash | ||
| # Build using docker | ||
| docker build -t oie-dev . | ||
| # Start an ephemeral image | ||
| # NOTE: All data will be deleted on stop due to --rm. Use a volume for "real" use. | ||
| docker run --rm -p 8443:8443 oie-dev | ||
| ``` | ||
kpalang marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| Then use [Ballista](https://github.com/kayyagari/ballista) to connect to | ||
| https://localhost:8443/ and login using admin admin. | ||
|
|
||
| ## Build Environment | ||
|
|
||
| To build the solution, you must have a Java 1.8 JDK+FX and Apache Ant. This | ||
| can be installed by [sdkman](https://sdkman.io/) by executing `sdkman env install`. | ||
mgaffigan marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| ## Build Process | ||
|
|
||
| From the `server/` directory, run `ant -f mirth-build.xml -DdisableSigning=true`. | ||
|
|
||
| If you are using Mirth Connect Administrator Launcher, you may need to omit | ||
mgaffigan marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| `-DdisableSigning=true` to support JWS signatures and run MCAL passing `-k -d` | ||
| to make it ignore self-signed certificates. Launchers like | ||
| [Ballista](https://github.com/kayyagari/ballista) do not require signing, and | ||
| signing adds considerable time to the build process. | ||
|
|
||
| ## Run | ||
|
|
||
| After build, run the server by invoking `server/mirth-server-launcher.jar`. An | ||
| example of how to do this is listed in `docker/mirth-connect.sh`. | ||
mgaffigan marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
mgaffigan marked this conversation as resolved.
Show resolved
Hide resolved
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| # syntax=docker/dockerfile:1.7-labs | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: I think we should stay on
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. question: Could the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You cannot run an The other options I'm disagreeing with are:
I generally agree with the advice to stay on
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity since I don't currently have the means to test this, but when doing a multi-stage build with a |
||
|
|
||
| # Stages: | ||
| # 1. Builder Stage: Compiles the application and resolves dependencies. Produces | ||
| # JAR files that can be deployed. | ||
| # 1a. Install dependencies | ||
| # 1b. Build the application | ||
| # 2. Runner Stage: Creates a lightweight image that runs the application using the JRE. | ||
|
|
||
| FROM ubuntu:noble-20250415.1 AS builder | ||
| WORKDIR /app | ||
| # sdkman requires bash | ||
| SHELL ["/bin/bash", "-c"] | ||
|
|
||
| # Stage 1a: Install dependencies | ||
| # Install necessary tools | ||
| COPY .sdkmanrc . | ||
| RUN apt-get update\ | ||
| && apt-get install -y zip curl\ | ||
| && curl -s "https://get.sdkman.io?ci=true" | bash \ | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need SDKMan and not just an ubuntu jdk image?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think either is acceptable, and avoiding sdkman would certainly make the dockerfile simpler. I think I went this route because the zulu jdk image does not contain ant, so I had to pull additional packages regardless. I'll see what that would look like.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See mgaffigan@123bbe2 for changes to avoid sdkman. Problems are:
I don't love sdkman, but it does seem simpler to use it in the builder container.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with the opinion that neither of the two options are perfect. Using a jdk image can easily drift with our preferred version from But in this case installing sdkman in the container is the better way to go to ensure as identical as possible envs.
I'm not sure this is true. the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm referring to docker images. Azul and Temurin publish tgz of JavaFX, but they do not provide pre-built images. See mgaffigan@123bbe2 for the changes to install from tgz rather than sdkman.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nitpick: Downloading and executing arbitrary scripts is not good practice. The correct way should be to download the binaries from GH and set them up ourselves, but it quite big hassle and I've never completed it, so might be good enough for now.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I see the difference between using sdkman and installing sdkman - since they both download and run untrusted scripts. If we were aiming for zero-trust, then we would need to shift to installing from tgz and add hash verifications. sdkman is fundamentally opposed to that. Practically, I would recommend separately maintaining and publishing a javafx container then basing this file on that.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In my mind the difference is that we have no control over the script being downloaded from What I'm saying is this is something we should keep in mind. I don't have a viable alternative right now. |
||
| && source "$HOME/.sdkman/bin/sdkman-init.sh" && sdk env install \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| # Stage 1b: Build the application | ||
| # Copy the entire source tree (excluding .dockerignore files), and build | ||
| COPY --exclude=docker . . | ||
| WORKDIR /app/server | ||
| RUN source "$HOME/.sdkman/bin/sdkman-init.sh" \ | ||
| && ANT_OPTS="-Dfile.encoding=UTF8" ant -f mirth-build.xml -DdisableSigning=true | ||
|
|
||
| ########################################## | ||
| # | ||
| # Ubuntu JDK Image | ||
| # | ||
| ########################################## | ||
|
|
||
| FROM eclipse-temurin:21.0.7_6-jdk-noble as jdk-run | ||
jonbartels marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| RUN groupadd engine \ | ||
| && usermod -l engine ubuntu \ | ||
| && adduser engine engine \ | ||
| && mkdir -p /opt/engine/appdata \ | ||
| && chown -R engine:engine /opt/engine | ||
|
|
||
| WORKDIR /opt/engine | ||
| COPY --chmod=0755 docker/entrypoint.sh ./ | ||
| COPY --chown=engine:engine --from=builder \ | ||
| --exclude=cli-lib \ | ||
| --exclude=mirth-cli-launcher.jar \ | ||
| --exclude=mccommand \ | ||
| --exclude=manager-lib \ | ||
| --exclude=mirth-manager-launcher.jar \ | ||
| --exclude=mcmanager \ | ||
| /app/server/setup ./ | ||
|
|
||
| VOLUME /opt/engine/appdata | ||
| VOLUME /opt/engine/custom-extensions | ||
| EXPOSE 8443 | ||
|
|
||
| USER engine | ||
| ENTRYPOINT ["./entrypoint.sh"] | ||
| CMD ["./oieserver"] | ||
|
|
||
| ########################################## | ||
| # | ||
| # Alpine JRE Image | ||
| # | ||
| ########################################## | ||
|
|
||
| FROM eclipse-temurin:21.0.7_6-jre-alpine as jre-run | ||
|
|
||
| # Alpine does not include bash by default, so we install it | ||
| RUN apk add --no-cache bash | ||
| # useradd and groupadd are not available in Alpine | ||
| RUN addgroup -S engine \ | ||
| && adduser -S -g engine engine \ | ||
| && mkdir -p /opt/engine/appdata \ | ||
| && chown -R engine:engine /opt/engine | ||
|
|
||
| WORKDIR /opt/engine | ||
| COPY --chmod=0755 docker/entrypoint.sh ./ | ||
| COPY --chown=engine:engine --from=builder \ | ||
| --exclude=cli-lib \ | ||
| --exclude=mirth-cli-launcher.jar \ | ||
| --exclude=mccommand \ | ||
| --exclude=manager-lib \ | ||
| --exclude=mirth-manager-launcher.jar \ | ||
| --exclude=mcmanager \ | ||
| /app/server/setup ./ | ||
|
|
||
| VOLUME /opt/engine/appdata | ||
| VOLUME /opt/engine/custom-extensions | ||
|
|
||
| EXPOSE 8443 | ||
|
|
||
| USER engine | ||
| ENTRYPOINT ["./entrypoint.sh"] | ||
| CMD ["./oieserver"] | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: I think having an "ignore everything" and "unignore this" approach would be more readable here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are building from source, I think an exclude list would be substantially more manageable than an include list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When writing the previous comment, I was thinking of the release container.
But, if we're talking about a build container for development, I still think includelisting the 6 directories + possibly
.sdkmanrcmight be the cleaner wayThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you help me understand what you are intending? The primary goal of a
.dockerignoreis to avoid copying build artifacts, not to select things for the docker build. It should generally match .gitignore (since if you are not putting it in code-control, it probably should not be used for build).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way I see it is that we have two options to use containers in the development cycle.
ant build) from the host machine and package the build result into a container for runtime testingWith both approaches the build context should be as small as possible.
With approach 1 the context should only contain the
setup/directory and possibly some individual files. This is what I intended in the first comment.With approach 2 things get a little more complicated, as we might need most of the dirs + files in the repo par some license or instructions files. But it is quite easy to find us with a bunch of little files that tweak some tooling or another, but are not necessary to compile OIE, which is why in my mind whitelisting only the files + dirs required for compilation might be the simpler way to go.