Deploy a Java App
This quickstart guide explains how to deploy a Java application to Koyeb using Git-driven or Docker-based deployment. By the end, you'll know how to use Koyeb to host your Java website or service in a few short steps. The Java application can be built using either native buildpacks or from a Dockerfile.
You will need:
- A Koyeb account (opens in a new tab)
- Java (opens in a new tab)
- Maven (opens in a new tab) to manage dependencies and build your project
- (Optional) The Koyeb CLI for deployment from the terminal
You can deploy and preview the Java application from this guide using the Deploy to Koyeb button:
Consult the repository on GitHub (opens in a new tab) to view this example application.
Create the Java app
Get started by creating a basic Java application todeploy on Koyeb.
Alternatively, you can fork the repository on GitHub (opens in a new tab) to get a complete copy of the code. If you fork the repository, then you can skip to section on git-driven deployment on Koyeb.
In your terminal, run the following commands to create a new project directory from a basic template (opens in a new tab):
mvn archetype:generate -DgroupId=app.koyeb.example \
-DartifactId=example-java \
-DarchetypeArtifactId=maven-archetype-quickstart \
-DarchetypeVersion=1.4 \
-DinteractiveMode=false
This command generates a project directory with a pom.xml
file for managing project dependencies, properties, and metadata. It also generates a single class file in src/main/java/app/koyeb/example/App.java
. The configuration we passed to the command created a project using app.koyeb.example
as the group ID and example-java
as the artifact ID.
Enter the example-java
directory:
cd example-java
Compile the generated sample application:
mvn package
Test the default application using the following command:
java -cp target/*.jar app.koyeb.example.App
The application displays "Hello World!" as an output.
Create a hello world web app
While the generated application produces output for the command line, the app doesn't yet respond to web requests.
Open the example-java/src/main/java/app/koyeb/example/App.java
file in your text editor. Replace the current contents with the following code:
package app.koyeb.example;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class App {
public static void main(String[] args) throws Exception {
int port = Integer.parseInt(System.getenv().getOrDefault("PORT", "8888"));
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
server.createContext("/", new MyHandler());
server.setExecutor(Executors.newCachedThreadPool());
System.out.println("Listening on port " + port + ".");
server.start();
}
static class MyHandler implements HttpHandler {
@Override
public void handle(HttpExchange t) throws IOException {
String response = "Hello world!";
t.sendResponseHeaders(200, response.length());
OutputStream os = t.getResponseBody();
os.write(response.getBytes());
os.close();
}
}
}
The new code imports functionality from various packages and classes to help us create a basic web server. We replace the main App
class with one that creates a server that responds to requests at /
with "Hello world!". By default, it listens on port 8888, but this can be overridden by setting the PORT
environment variable to a different value.
Test the new web application implementation by building and running the executable again:
mvn package
java -cp target/*.jar app.koyeb.example.App
Visit localhost:8888
in your web browser to see the "Hello world!" message you configured.
Test that the port is configurable by running the same command again with the PORT
environment variable set:
PORT=5555 java -cp target/*.jar app.koyeb.example.App
Now, instead of being served on port 8888, the application is accessible at localhost:5555
.
Configuring the project
To make the project easier to run, you will modify pom.xml
.
Open the pom.xml
file in the project's root directory. Inside, find the entries for the maven-jar-plugin
plugin. Add a configuration
section within the plugin specification to identify the main class of the application:
. . .
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>app.koyeb.example.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
. . .
This encodes the main class within the .jar
file so that you no longer have to specify the class to execute at runtime.
Close the file when you are finished.
Test the maven-jar-plugin
configuration by building the package again and executing the resulting .jar
file, this time without specifying a class:
mvn package
java -jar target/*.jar
The server begins listening for connections without needing to specify a class.
Create a Dockerfile for the project (Optional)
You can build and run our Java project on Koyeb using the native Java buildpack, but you can also optionally build from a Dockerfile for more control. To make it possible to build a container image for our application, create a Dockerfile and define a .dockerignore
file to tell the builder what files to skip when creating the image.
To leverage our Maven build configuration, generate a Maven wrapper that lets you include a Maven instance with our project:
mvn -N wrapper:wrapper
This generates a mvnw
bash script, a mvnw.cmd
batch script, and a .mvn/wrapper
directory to store the actual executable and configuration. We can use the mvnw
script just like we would the regular mvn
command and it will execute the commands using the local copy of Maven instead of relying on a system copy.
Define a .dockerignore
file in your main project directory. Inside, paste the following contents:
.git
.gitignore
Dockerfile
.dockerignore
target
This file tells Docker to not include Git files, the Docker files themselves, and any build artifacts placed in the target
directory. This helps ensure that the image we build is not bloated and that the build completes faster.
Create a new file called Dockerfile
within the main project directory. Inside, paste the following contents:
# Build stage
FROM eclipse-temurin:17-jdk-alpine AS builder
WORKDIR /app
COPY . .
RUN ./mvnw package
# Run stage
FROM eclipse-temurin:17-jdk-alpine AS runner
WORKDIR /app
COPY --from=builder /app/target/*.jar .
CMD ["java", "-jar", "example-java-1.0-SNAPSHOT.jar"]
This Dockerfile uses a multistage build (opens in a new tab) to separate the build steps from the final image environment. This creates a more streamlined image and allows you to tightly control what files are included in the final image.
Both stages are based on the Alpine version of the eclipse-temurin
image (opens in a new tab). The build stage copies all of the files over to the image and builds the package. The compiled artifact is then copied to the runtime image where it is executed directly with the java
executable.
If you have Docker installed locally, you can build and test the image on your computer and optionally upload it to a registry. You can deploy container images from any container registry to Koyeb.
You can also build the Dockerfile (directly from the repository when deploying)[#deploy-to-koyeb-using-git-driven-deployment], which is useful as a way of automatically deploying when changes occur.
Push the project to GitHub
In the project directory, initialize a new Git repository by running the following command:
git init
Download a basic .gitignore
file designed for Maven projects from GitHub:
curl -L https://raw.githubusercontent.com/github/gitignore/main/Maven.gitignore -o .gitignore
Specify the Java runtime version to use so that the Koyeb Java buildpack executes the project with the correct version:
echo "java.runtime.version=25" > system.properties
Add the project files to the staging area and commit them. If you don't have an existing GitHub repository to push the code to, you can create a new one and run the following commands to commit and push changes to your GitHub repository:
git add :/
git commit -m "Initial commit"
git remote add origin git@github.com:<YOUR_GITHUB_USERNAME>/<YOUR_REPOSITORY_NAME>.git
git push -u origin main
Make sure to replace <YOUR_GITHUB_USERNAME>/<YOUR_REPOSITORY_NAME>
with your GitHub username and repository name.
Deploy to Koyeb using Git-driven deployment
Once the repository is pushed to GitHub, you can deploy the Java application to Koyeb. Any changes in the deployed branch of your codebase will automatically trigger a redeploy on Koyeb, ensuring that your application is always up-to-date.
To deploy the Java app on Koyeb using the control panel (opens in a new tab), follow the steps below:
- Click Create Web Service on the Overview tab of the Koyeb control panel.
- Select GitHub as the deployment option.
- Choose the GitHub repository and branch containing your application code. Alternatively, you can enter our public Java example repository (opens in a new tab) into the Public GitHub repository at the bottom of the page:
https://github.com/koyeb/example-java
- Choose the Builder for your project. You can use either a Dockerfile or buildpack for this repository.
- If you chose the buildpack builder, click the toggle associated with the Run command. In the field, enter
java -jar target/example-java-1.0-SNAPSHOT.jar
. - Name the App and Service. For example,
example-java
. - Click the Deploy button.
This creates a Koyeb App and Service which builds and deploys your application on Koyeb. You can access your application running on Koyeb by clicking the URL ending with .koyeb.app
.
Deploy to Koyeb from a container registry
As an alternative to git-driven deployment, you can deploy a pre-built Docker container from any public or private registry. This can be useful if your application needs specific system dependencies or you need more control over how the build is performed.
To deploy a pre-built Java container image on Koyeb using the control panel (opens in a new tab), follow these steps:
- Click Create Web Service on the Overview tab of the Koyeb control panel.
- Select Docker as the deployment option.
- Choose the container image and tag from your registry and click Next to continue.
- Name the App and Service. For example,
example-java
. - Click the Deploy button.
This creates a Koyeb App and Service which builds and deploys your application on Koyeb. You can access your application running on Koyeb by clicking the URL ending with .koyeb.app
.
What's next
For more examples of Java applications deployed on Koyeb, check out these tutorials:
- Using Spring Authorization Server as an Auth Solution on Koyeb (opens in a new tab)
- Deploy the Metabase Business Intelligence Platform to Koyeb (opens in a new tab)
To learn more about the features available for your apps, check out the following documentation:
- Autoscaling (opens in a new tab) - Dynamically adjust the number of Instances within a Service to meet the demand of your applications.
- Scale-to-Zero (opens in a new tab) - Configure your Instances to automatically scale down to zero when there is no incoming traffic, reducing usage.
- Metrics (opens in a new tab) - Learn how to monitor your Services usage.