Deploy from a Dockerfile
In this quick tutorial, you'll learn how to create and deploy a basic web server from a DockerFile.
1. Prepare the project
Let's start from our ready-to-use project. Select your favorite web technology and git clone
the project.
Then go directly to the step 4 to prepare the deployment.
- Node
- Deno
- PHP
- Python
- Go
- Java
git clone https://github.com/ScaleDynamics/docker-node my-docker
cd my-docker/
npm install
git clone https://github.com/ScaleDynamics/docker-deno my-docker
cd my-docker/
git clone https://github.com/ScaleDynamics/docker-php my-docker
cd my-docker/
git clone https://github.com/ScaleDynamics/docker-python my-docker
cd my-docker/
git clone https://github.com/ScaleDynamics/docker-go my-docker
cd my-docker/
git clone https://github.com/ScaleDynamics/docker-java my-docker
cd my-docker/
or,
Let's create manually your own my-docker
working directory, and follow the next steps
mkdir my-docker
cd my-docker/
2. Create a basic HTTP web server with Docker
- Node
- Deno
- PHP
- Python
- Go
- Java
Create a package.json
file
{
"name": "my-docker",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "node ."
}
}
Install Express
npm install express
Init a new HTTP server
Create a new index.js
file in the project directory, and copy-paste the following code into it:
const express = require("express");
const app = express();
const port = process.env.PORT || 8080;
app.get("/:name?", (req, res) => {
const name = req.params.name || "World";
const version = process.version;
res.send(`Hello ${name} from Node.js ${version}`);
});
app.listen(port, () => {
console.log(`HTTP server listening on port ${port}`);
});
Init a new Dockerfile
FROM node:lts
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --production --silent
COPY . ./
EXPOSE 8080
CMD [ "node", "index.js" ]
Init a new HTTP server
Create a new index.ts
file in the project directory, and copy-paste the following code into it:
import { serve } from "https://deno.land/std@0.130.0/http/server.ts";
const port = 8080;
const handler = (request: Request): Response => {
const url = new URL(request.url);
const name = url.pathname.slice(1) || "World";
const version = Deno.version.deno;
const body = `Hello ${name} from Deno v${version}`;
return new Response(body, { status: 200 });
};
console.log(`HTTP server listening on port ${port}`);
await serve(handler, { port });
Init a new Dockerfile
FROM denoland/deno:latest
WORKDIR /usr/src/app
COPY . .
EXPOSE 8080
CMD ["deno", "run", "--allow-net", "index.ts"]
Init a new HTTP server
Create a new index.php
file in the project directory, and copy-paste the following code into it:
<?php
$name = $_GET["name"] ?? "World";
$version = phpversion();
echo "Hello ".$name." from PHP v".$version;
?>
Init a new Dockerfile
FROM php:apache
COPY . /var/www/html
EXPOSE 80
Install Flask
python3 -m pip install flask
Init a new HTTP server
Create a new index.py
file in the project directory, and copy-paste the following code into it:
import platform
from flask import Flask
app = Flask(__name__)
@app.route('/')
@app.route('/<name>')
def index(name='World'):
version = platform.python_version()
return 'Hello {} from Python v{}'.format(name, version)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
Init a new Dockerfile
FROM python:latest
COPY . .
RUN python3 -m pip install flask
EXPOSE 8080
CMD ["python", "-u", "index.py"]
Init a new HTTP server
Create a new index.go
file in the project directory, and copy-paste the following code into it:
package main
import (
"fmt"
"net/http"
"runtime"
)
func handler(w http.ResponseWriter, r *http.Request) {
name := r.URL.Path[1:]
if name == "" {
name = "World"
}
version := runtime.Version()[2:]
fmt.Fprintf(w, "Hello %s from Go v%s", name, version)
}
func main() {
port := 8080
fmt.Printf("HTTP server listening on port %d", port)
http.HandleFunc("/", handler)
http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
}
Init a new Dockerfile
FROM golang:latest
WORKDIR /usr/src/app
COPY . .
RUN go build -o /usr/bin/app index.go
EXPOSE 8080
CMD ["/usr/bin/app"]
Init a new HTTP server
Create a new Main.java
file in the project directory, and copy-paste the following code into it:
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class Main {
static final int PORT = 8080;
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(PORT), 0);
server.createContext("/", new MyHandler());
server.setExecutor(null);
server.start();
System.out.println("Server started on port " + PORT);
}
static class MyHandler implements HttpHandler {
@Override
public void handle(HttpExchange exchange) throws IOException {
Map<String, String> params = Main.parseQueryString(exchange.getRequestURI().getQuery());
String version = System.getProperty("java.version");
String name = params.get("name") != null ? params.get("name") : "unknown";
String response = "Hello " + name + " from Java " + version;
exchange.sendResponseHeaders(200, response.length());
OutputStream os = exchange.getResponseBody();
os.write(response.getBytes());
System.out.println("Response: " + response + " sent to " + exchange.getRemoteAddress());
os.close();
}
}
public static Map<String, String> parseQueryString(String qs) {
Map<String, String> result = new HashMap<>();
if (qs == null)
return result;
int last = 0, next, l = qs.length();
while (last < l) {
next = qs.indexOf('&', last);
if (next == -1)
next = l;
if (next > last) {
int eqPos = qs.indexOf('=', last);
try {
if (eqPos < 0 || eqPos > next)
result.put(URLDecoder.decode(qs.substring(last, next), "utf-8"), "");
else
result.put(URLDecoder.decode(qs.substring(last, eqPos), "utf-8"), URLDecoder.decode(qs.substring(eqPos + 1, next), "utf-8"));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
last = next + 1;
}
return result;
}
}
Init a new Dockerfile
FROM openjdk:17
COPY . /usr/src/myapp
WORKDIR /usr/src/myapp
RUN javac Main.java
EXPOSE 8080
CMD ["java", "Main"]
3. Install the ScaleDynamics SDK
To use the SDK you need Node.js installed on your computer.
Look at https://nodejs.org/en/download/ to install it.
To access our CLI, use npx warp
. To get installation options of the SDK, look to SDK installation.
You can have the list of available commands and help with
npx warp help
Then, create or update the .dockerignore
file as below to exclude the node_modules
folder from your deployment:
node_modules/
4. Create the project and the environment
The deployment of a Docker container requires to indicate in which project and which environment you want to run it.
A project identifies a set of containers to be deployed. Users can use project to logically represents a website, a web app, a microservice, an API...
An environment defines the cloud execution environment to deploy and run a project. For example you can have 'pre-prod', 'demo', 'staging' or 'production' environments.
Login to your account
To access projects and deployment resources you need a ScaleDynamics account. You can sign up here to create your account. Subscription is FREE, no credit card required.
Once your account is created, you can login to your account with your email and password:
npx warp login
Create a project
Let's create a docker
project
npx warp project create docker
Create an environment
Let's create a demo
environment.
npx warp env create demo
5. Deploy the server
You're now ready to deploy the server container.
npx warp deploy --project docker --env demo
During the deployment, you will have to indicate the url where you want to access your server after deployment.
✔ Enter a hostname for 'my-docker' (fully qualified or not), leave blank for random: …
You can enter a name or press return to get a random one.
After that step you will have to indicate on which runner to deploy and run your container.
All runners that can be used are shown and you can select the right one.
You can select the configuration scaledynamics-shared-runner
that is a FREE mutalized runner we provide for getting started purposes.
You need to select a runner for deployment configuration 'my-docker'
? Pick a runner or a configuration: ›
❯ Config: scaledynamics-shared-runner
After deployment the url of your container is dumped on the terminal.
if you want to know the deployment url, you can access the console or use the following command to get it:
npx warp env info
6. Call the server
Now the server is deployed, let's call it from HTTP using curl for example:
curl https://DEPLOYMENT_URL
Chapeau!
Congrats', you deployed your first Managed HTTP docker.
Want to continue? Create your first Runner